forked from natuka/web.puabadge.com
代码提交
This commit is contained in:
1 parent
b52dcc0842
commit
04d89f4a9a
2 files changed
+4
-276
No files matched your search
+2
-29
@@ -15,7 +15,8 @@ export const cartoonConfig = {
|
||||
2: { name: '浮雕相框', key: 'relief_frame' },
|
||||
3: { name: '3D冰箱贴', key: 'fridge_magnet' },
|
||||
4: { name: '3D卡通手办', key: 'cartoon_figure' },
|
||||
6: { name: '浮雕挂饰', key: 'relief_pendant' }
|
||||
6: { name: '浮雕挂饰', key: 'relief_pendant' },
|
||||
8: { name: '摇摇乐', key: 'shake_toy' }
|
||||
},
|
||||
|
||||
// 主体类型配置
|
||||
@@ -58,8 +59,6 @@ export const cartoonConfig = {
|
||||
|
||||
// 产品限制配置
|
||||
productLimits: {
|
||||
// 根据产品ID配置是否需要人脸检测
|
||||
faceCheckRequired: [7, 1, 25],
|
||||
// 根据产品ID配置是否支持多视角参考图
|
||||
multiViewSupported: [19],
|
||||
// 根据产品ID配置是否支持风格类型
|
||||
@@ -94,32 +93,6 @@ export const cartoonConfig = {
|
||||
order: '@/assets/badge/order.png'
|
||||
},
|
||||
|
||||
// 提示信息配置
|
||||
messages: {
|
||||
personPhotoTip: {
|
||||
single: '1',
|
||||
multiple: '1-3',
|
||||
unit: '人'
|
||||
},
|
||||
petPhotoTip: {
|
||||
count: '1-3',
|
||||
unit: '只'
|
||||
}
|
||||
},
|
||||
|
||||
// 业务规则配置
|
||||
businessRules: {
|
||||
// 禁止的产品ID组合(typeId, subjectId)
|
||||
disabled: [
|
||||
{ typeId: 3, subjectId: 7, message: '人物3D冰箱贴暂未开放' }
|
||||
],
|
||||
// 订单类型限制(typeId, currentProdId, targetSubjectId, message)
|
||||
orderRestrictions: [
|
||||
{ typeId: 4, prodId: 19, targetSubjectId: 8, message: '该订单属于宠物卡通手办' },
|
||||
{ typeId: 4, prodId: 1, targetSubjectId: 7, message: '该订单属于人物卡通手办' }
|
||||
]
|
||||
},
|
||||
|
||||
// 样式配置
|
||||
styles: {
|
||||
colors: {
|
||||
|
||||
+2
-247
@@ -80,25 +80,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tag-change-box">
|
||||
<div class="tag-change-item">
|
||||
<div
|
||||
class="tag-change-item-title"
|
||||
:class="{ tagActive: isPersonSubject }"
|
||||
@click="prodChange(config.subjectTypes.person.id)">
|
||||
{{ toValueWithout(config.subjectTypes.person.name) }}
|
||||
</div>
|
||||
<div
|
||||
class="tag-change-item-title"
|
||||
:class="{ tagActive: isPetSubject }"
|
||||
@click="prodChange(config.subjectTypes.pet.id)">
|
||||
{{ toValueWithout(config.subjectTypes.pet.name) }}
|
||||
</div>
|
||||
</div>
|
||||
<div :style="`font-size: 12px; color: ${config.styles.colors.textTertiary}; text-align: center;`">
|
||||
{{ toValueWithout("不同主体的照片检测标准不同") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-line" v-if="shouldShowPhotoExample">
|
||||
<div class="step-line-item">
|
||||
<div class="step-line-item-title">
|
||||
@@ -126,10 +107,6 @@
|
||||
</div>
|
||||
<div class="photo-upload-body">
|
||||
<div v-if="!picture" class="photo-upload-box">
|
||||
<div class="photo-upload-header" @click="imgShow = true">
|
||||
<van-icon name="question-o" size="16px" class="photo-upload-guide-icon" />
|
||||
<span class="photo-upload-guide-text">{{ toValueWithout("图片上传指南") }}</span>
|
||||
</div>
|
||||
<div class="photo-upload-area">
|
||||
<div class="photo-upload-plus">
|
||||
+
|
||||
@@ -182,18 +159,6 @@
|
||||
upload-icon="plus" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="shouldShowPhotoTip">
|
||||
<div
|
||||
:style="`font-size: 12px; color: red; margin-top: ${config.styles.spacing.sectionMargin}; text-align: center;`"
|
||||
v-if="isPersonSubject">
|
||||
{{ toValueWithout("温馨提示:请上传只有") }}{{ personPhotoCount }}{{ toValueWithout("人的照片") }}
|
||||
</div>
|
||||
<div
|
||||
:style="`font-size: 12px; color: red; margin-top: ${config.styles.spacing.sectionMargin}; text-align: center;`"
|
||||
v-if="isPetSubject">
|
||||
{{ toValueWithout("温馨提示:请上传只有") }}{{ config.messages.petPhotoTip.count }}{{ toValueWithout("只宠物的照片") }}
|
||||
</div>
|
||||
</div>
|
||||
<div :style="`height: 120px;`"></div>
|
||||
<div class="design-action-bar">
|
||||
<div class="design-left">
|
||||
@@ -206,37 +171,6 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<van-action-sheet v-model:show="imgShow" :title="toValueWithout('图片上传指南')" :close-on-click-overlay="true" closeable>
|
||||
<div :style="`padding: 0 ${config.styles.spacing.pagePadding} 24px ${config.styles.spacing.pagePadding};`">
|
||||
<div style="text-align: center;">
|
||||
<img :src="sundryList[0]?.path" alt="照片上传指南" :style="`width: 90vw; border-radius: 16px; margin-bottom: ${config.styles.spacing.sectionMargin};`">
|
||||
</div>
|
||||
<div :style="`display: flex; justify-content: space-between; margin-bottom: ${config.styles.spacing.sectionMargin};`">
|
||||
<div style="flex: 1; text-align: center;" v-for="(item, index) in sundryList.slice(1, 4)" :key="index">
|
||||
<img :src="item.path" :alt="item.name" :style="`width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;`">
|
||||
<div :style="`font-size: 13px; color: ${config.styles.colors.textTertiary}; margin-top: 4px;`">
|
||||
{{ toValueWithout(item.name) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div :style="`display: flex; justify-content: space-around; margin-bottom: 24px;`">
|
||||
<div style="flex: 1; text-align: center;" v-for="(item, index) in sundryList.slice(4, 6)" :key="index">
|
||||
<img :src="item.path" :alt="item.name" :style="`width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;`">
|
||||
<div :style="`font-size: 13px; color: ${config.styles.colors.textTertiary}; margin-top: 4px;`">
|
||||
{{ toValueWithout(item.name) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div :style="`margin-top: 24px; text-align: center;`">
|
||||
<button
|
||||
:style="`width: 90%; height: 44px; background: ${config.styles.colors.primaryGradient}; border: none; border-radius: 22px; color: ${config.styles.colors.textPrimary}; font-size: 18px; font-weight: bold; cursor: pointer;`"
|
||||
@click="imgShow = false">
|
||||
{{ toValueWithout("我已了解") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -264,7 +198,6 @@ i18n.set(t);
|
||||
// 使用配置
|
||||
const config = cartoonConfig
|
||||
|
||||
const imgShow = ref(false)
|
||||
const referPicture = ref<UploaderFileListItem[]>([])
|
||||
const router = useRouter()
|
||||
|
||||
@@ -310,41 +243,27 @@ const getSizeList = () => {
|
||||
|
||||
// 获取首页显示的数量和类型
|
||||
const orderStat = ref({})
|
||||
const prodId = ref(config.subjectTypes.person.id)
|
||||
const prodId = ref(0)
|
||||
const prop = ref('')
|
||||
const typeId = ref(0)
|
||||
|
||||
const getOrderStat = () => {
|
||||
badgeApi.getOrderStat({}).then((res: any) => {
|
||||
orderStat.value = res
|
||||
prodId.value = getDefaultProdId(res)
|
||||
prodId.value = res.prod_id
|
||||
if (res.type_id === 4) {
|
||||
getKindList()
|
||||
}
|
||||
prop.value = res.prop
|
||||
typeId.value = res.type_id
|
||||
getSundryList()
|
||||
})
|
||||
}
|
||||
|
||||
// 根据配置获取默认产品ID
|
||||
const getDefaultProdId = (res: any): number => {
|
||||
const mapping = config.productIdMapping[res.type_id] || config.productIdMapping.default
|
||||
// 判断当前产品ID是否属于人物主体
|
||||
const isPerson = config.subjectTypes.person.prodIds.includes(res.prod_id)
|
||||
return isPerson ? mapping.person : mapping.pet
|
||||
}
|
||||
|
||||
// 计算属性:当前产品类型配置
|
||||
const productTypeConfig = computed(() => {
|
||||
return config.productTypes[typeId.value]
|
||||
})
|
||||
|
||||
// 计算属性:是否是人物主体
|
||||
const isPersonSubject = computed(() => {
|
||||
return config.subjectTypes.person.prodIds.includes(prodId.value)
|
||||
})
|
||||
|
||||
// 计算属性:是否是宠物主体
|
||||
const isPetSubject = computed(() => {
|
||||
return config.subjectTypes.pet.prodIds.includes(prodId.value)
|
||||
@@ -365,18 +284,6 @@ const shouldShowMultiView = computed(() => {
|
||||
return typeId.value === 4 && config.productLimits.multiViewSupported.includes(prodId.value)
|
||||
})
|
||||
|
||||
// 计算属性:是否显示照片提示
|
||||
const shouldShowPhotoTip = computed(() => {
|
||||
return typeId.value !== 4
|
||||
})
|
||||
|
||||
// 计算属性:人物照片数量提示
|
||||
const personPhotoCount = computed(() => {
|
||||
return prop.value === '3D真人肖像'
|
||||
? config.messages.personPhotoTip.single
|
||||
: config.messages.personPhotoTip.multiple
|
||||
})
|
||||
|
||||
const kindList = ref([])
|
||||
const getKindList = () => {
|
||||
badgeApi.getKindList({
|
||||
@@ -394,40 +301,6 @@ const getSupportSubject = (): number => {
|
||||
: config.subjectTypes.person.supportSubject
|
||||
}
|
||||
|
||||
// 产品切换
|
||||
const prodChange = (subjectId: number) => {
|
||||
// 检查是否被禁用
|
||||
const disabledRule = config.businessRules.disabled.find(
|
||||
rule => rule.typeId === typeId.value && rule.subjectId === subjectId
|
||||
)
|
||||
if (disabledRule) {
|
||||
showToast(toValueWithout(disabledRule.message))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查订单限制
|
||||
const restriction = config.businessRules.orderRestrictions.find(
|
||||
rule => rule.typeId === typeId.value && rule.prodId === prodId.value && rule.targetSubjectId === subjectId
|
||||
)
|
||||
if (restriction) {
|
||||
showToast(toValueWithout(restriction.message))
|
||||
return
|
||||
}
|
||||
|
||||
// 根据配置映射产品ID
|
||||
const mapping = config.productIdMapping[typeId.value] || config.productIdMapping.default
|
||||
if (typeId.value === 6) {
|
||||
prodId.value = subjectId === config.subjectTypes.pet.id ? mapping.pet : mapping.person
|
||||
} else if (typeId.value === 4) {
|
||||
prodId.value = subjectId === config.subjectTypes.pet.id ? mapping.pet : mapping.person
|
||||
} else {
|
||||
prodId.value = subjectId === config.subjectTypes.person.id ? mapping.person : mapping.pet
|
||||
}
|
||||
|
||||
picture.value = null
|
||||
kindId.value = 0
|
||||
}
|
||||
|
||||
const kindId = ref(0)
|
||||
const kindChange = (id: number) => {
|
||||
kindId.value = id
|
||||
@@ -479,9 +352,6 @@ function getbase64Data(data: string) {
|
||||
return false;
|
||||
}
|
||||
imgurl.value = blob;
|
||||
if (config.productLimits.faceCheckRequired.includes(prodId.value)) {
|
||||
getUploadUrl()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,61 +395,6 @@ function imgorigoinf(data: File) {
|
||||
}
|
||||
}
|
||||
|
||||
const getUploadUrl = () => {
|
||||
badgeApi.getUploadUrl({}).then((res: any) => {
|
||||
if (res) {
|
||||
sendFaceToOss(imgurl.value, res.upload_url, res.path)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 人脸识别上传
|
||||
const sendFaceToOss = async (src: Blob, url: string, path: string) => {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'image/jpeg'
|
||||
},
|
||||
body: src
|
||||
})
|
||||
if (!response.ok) {
|
||||
throw new Error('Upload failed')
|
||||
}
|
||||
if (response.status === 200) {
|
||||
badgeApi.faceCheck({
|
||||
path: path,
|
||||
prop: prop.value,
|
||||
prod_id: prodId.value
|
||||
}).then(() => {
|
||||
showSuccessToast({
|
||||
message: toValueWithout('人脸检测成功'),
|
||||
duration: 2000,
|
||||
})
|
||||
}).catch((err: any) => {
|
||||
showFailToast({
|
||||
message: err.message || toValueWithout('人脸检测失败'),
|
||||
icon: 'none',
|
||||
duration: 2000,
|
||||
})
|
||||
imgurl.value = null
|
||||
picture.value = null
|
||||
}).finally(() => {
|
||||
setTimeout(() => {
|
||||
closeToast()
|
||||
}, 2000);
|
||||
})
|
||||
}
|
||||
} catch (err: any) {
|
||||
closeToast()
|
||||
showFailToast({
|
||||
message: err.message || toValueWithout('上传失败'),
|
||||
icon: 'none',
|
||||
duration: 2000,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const onOversize = (file: any) => {
|
||||
if (file.size > config.upload.maxSize) {
|
||||
showToast(toValueWithout(`照片大小不能超过${config.upload.maxSize / 1024 / 1024}M`))
|
||||
@@ -786,36 +601,7 @@ const createLog = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 获取首页图片上传指南图片
|
||||
const sundryList = ref<any[]>([])
|
||||
const getSundryList = () => {
|
||||
const group = isPersonSubject.value
|
||||
? config.subjectTypes.person.group
|
||||
: config.subjectTypes.pet.group
|
||||
|
||||
badgeApi.getSundryList({
|
||||
page: 1,
|
||||
size: 6,
|
||||
group: group,
|
||||
}).then((res: any) => {
|
||||
const data = res || []
|
||||
sundryList.value = data.list
|
||||
}).catch((err: any) => {
|
||||
showToast({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
watch(
|
||||
() => prodId.value,
|
||||
() => {
|
||||
getSundryList()
|
||||
}
|
||||
)
|
||||
getSundryList()
|
||||
openApp()
|
||||
getOrderStat()
|
||||
getSizeList()
|
||||
@@ -1106,37 +892,6 @@ onMounted(() => {
|
||||
margin-bottom: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.tag-change-box {
|
||||
margin: 0 auto;
|
||||
}
|
||||
.tag-change-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 12px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.tag-change-item-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
background: #E5E5E5;
|
||||
width: 120px;
|
||||
height: 32px;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
}
|
||||
.tag-change-item-title:first-child {
|
||||
border-top-left-radius: 16px;
|
||||
border-bottom-left-radius: 16px;
|
||||
}
|
||||
.tag-change-item-title:last-child {
|
||||
border-top-right-radius: 16px;
|
||||
border-bottom-right-radius: 16px;
|
||||
}
|
||||
.tag-change-item-title.tagActive {
|
||||
background: #50CF54;
|
||||
color: #fff;
|
||||
}
|
||||
.kind-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in new issue
Block a user