Browse Source

代码提交

main
Linzm 3 weeks ago
parent
commit
04d89f4a9a
  1. 31
      src/config/cartoon.ts
  2. 249
      src/views/cartoon/index.vue

31
src/config/cartoon.ts

@ -15,7 +15,8 @@ export const cartoonConfig = {
2: { name: '浮雕相框', key: 'relief_frame' }, 2: { name: '浮雕相框', key: 'relief_frame' },
3: { name: '3D冰箱贴', key: 'fridge_magnet' }, 3: { name: '3D冰箱贴', key: 'fridge_magnet' },
4: { name: '3D卡通手办', key: 'cartoon_figure' }, 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: { productLimits: {
// 根据产品ID配置是否需要人脸检测
faceCheckRequired: [7, 1, 25],
// 根据产品ID配置是否支持多视角参考图 // 根据产品ID配置是否支持多视角参考图
multiViewSupported: [19], multiViewSupported: [19],
// 根据产品ID配置是否支持风格类型 // 根据产品ID配置是否支持风格类型
@ -94,32 +93,6 @@ export const cartoonConfig = {
order: '@/assets/badge/order.png' 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: { styles: {
colors: { colors: {

249
src/views/cartoon/index.vue

@ -80,25 +80,6 @@
</div> </div>
</div> </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" v-if="shouldShowPhotoExample">
<div class="step-line-item"> <div class="step-line-item">
<div class="step-line-item-title"> <div class="step-line-item-title">
@ -126,10 +107,6 @@
</div> </div>
<div class="photo-upload-body"> <div class="photo-upload-body">
<div v-if="!picture" class="photo-upload-box"> <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-area">
<div class="photo-upload-plus"> <div class="photo-upload-plus">
+ +
@ -182,18 +159,6 @@
upload-icon="plus" /> upload-icon="plus" />
</div> </div>
</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 :style="`height: 120px;`"></div>
<div class="design-action-bar"> <div class="design-action-bar">
<div class="design-left"> <div class="design-left">
@ -206,37 +171,6 @@
</button> </button>
</div> </div>
</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> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -264,7 +198,6 @@ i18n.set(t);
// 使 // 使
const config = cartoonConfig const config = cartoonConfig
const imgShow = ref(false)
const referPicture = ref<UploaderFileListItem[]>([]) const referPicture = ref<UploaderFileListItem[]>([])
const router = useRouter() const router = useRouter()
@ -310,41 +243,27 @@ const getSizeList = () => {
// //
const orderStat = ref({}) const orderStat = ref({})
const prodId = ref(config.subjectTypes.person.id) const prodId = ref(0)
const prop = ref('') const prop = ref('')
const typeId = ref(0) const typeId = ref(0)
const getOrderStat = () => { const getOrderStat = () => {
badgeApi.getOrderStat({}).then((res: any) => { badgeApi.getOrderStat({}).then((res: any) => {
orderStat.value = res orderStat.value = res
prodId.value = getDefaultProdId(res) prodId.value = res.prod_id
if (res.type_id === 4) { if (res.type_id === 4) {
getKindList() getKindList()
} }
prop.value = res.prop prop.value = res.prop
typeId.value = res.type_id 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(() => { const productTypeConfig = computed(() => {
return config.productTypes[typeId.value] return config.productTypes[typeId.value]
}) })
//
const isPersonSubject = computed(() => {
return config.subjectTypes.person.prodIds.includes(prodId.value)
})
// //
const isPetSubject = computed(() => { const isPetSubject = computed(() => {
return config.subjectTypes.pet.prodIds.includes(prodId.value) 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) 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 kindList = ref([])
const getKindList = () => { const getKindList = () => {
badgeApi.getKindList({ badgeApi.getKindList({
@ -394,40 +301,6 @@ const getSupportSubject = (): number => {
: config.subjectTypes.person.supportSubject : 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 kindId = ref(0)
const kindChange = (id: number) => { const kindChange = (id: number) => {
kindId.value = id kindId.value = id
@ -479,9 +352,6 @@ function getbase64Data(data: string) {
return false; return false;
} }
imgurl.value = blob; 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) => { const onOversize = (file: any) => {
if (file.size > config.upload.maxSize) { if (file.size > config.upload.maxSize) {
showToast(toValueWithout(`照片大小不能超过${config.upload.maxSize / 1024 / 1024}M`)) 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(() => { onMounted(() => {
watch(
() => prodId.value,
() => {
getSundryList()
}
)
getSundryList()
openApp() openApp()
getOrderStat() getOrderStat()
getSizeList() getSizeList()
@ -1106,37 +892,6 @@ onMounted(() => {
margin-bottom: 12px; margin-bottom: 12px;
font-size: 14px; 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 { .kind-box {
display: flex; display: flex;
align-items: center; align-items: center;

Loading…
Cancel
Save