Browse Source

宠物徽章

lzm_web
Linzm 7 months ago
parent
commit
0943188106
  1. 3
      .env.development
  2. 1
      components.d.ts
  3. 2
      src/api/badge.ts
  4. 271
      src/views/badge/index.vue
  5. 309
      src/views/badge/preview.vue
  6. 2
      src/views/badge/record.vue

3
.env.development

@ -1,5 +1,6 @@
VITE_APP_PREVIEW=true VITE_APP_PREVIEW=true
# VITE_APP_API_BASE_URL=http://172.16.0.51:8166/web/ # VITE_APP_API_BASE_URL=http://172.16.0.47:8166/web/
# VITE_APP_API_BASE_URL=https://wechat-test.api.puabadge.com/web/
VITE_APP_API_BASE_URL=https://wechat.api.puabadge.com/web/ VITE_APP_API_BASE_URL=https://wechat.api.puabadge.com/web/
# VITE_APP_API_WX_URL=https://wechat.api.puabadge.com/web/ # VITE_APP_API_WX_URL=https://wechat.api.puabadge.com/web/
# http://web.suwa3d.dev:28499/ # http://web.suwa3d.dev:28499/

1
components.d.ts vendored

@ -21,7 +21,6 @@ declare module '@vue/runtime-core' {
Tabbar: typeof import('./src/components/tabbar/index.vue')['default'] Tabbar: typeof import('./src/components/tabbar/index.vue')['default']
Tensorflow: typeof import('./src/components/arFrame/tensorflow.vue')['default'] Tensorflow: typeof import('./src/components/arFrame/tensorflow.vue')['default']
VanActionSheet: typeof import('vant/es')['ActionSheet'] VanActionSheet: typeof import('vant/es')['ActionSheet']
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
VanDivider: typeof import('vant/es')['Divider'] VanDivider: typeof import('vant/es')['Divider']
VanField: typeof import('vant/es')['Field'] VanField: typeof import('vant/es')['Field']
VanIcon: typeof import('vant/es')['Icon'] VanIcon: typeof import('vant/es')['Icon']

2
src/api/badge.ts

@ -65,7 +65,7 @@ export const getOrderDetail = (params: any) => {
} }
// 推送生成效果图 // 推送生成效果图
export const putMOdeling = (data: any) => { export const putModeling = (data: any) => {
return request('images/putModeling', { return request('images/putModeling', {
method: 'POST', method: 'POST',
data, data,

271
src/views/badge/index.vue

@ -41,7 +41,6 @@ const openApp = () => {
const imgurl = ref('') const imgurl = ref('')
const imgBgUrl = ref('') const imgBgUrl = ref('')
const isBgShow = ref(true)
const remaining = ref(0) const remaining = ref(0)
function goToRecord() { function goToRecord() {
router.push('/badge/record') router.push('/badge/record')
@ -58,9 +57,12 @@ const getSizeList = () => {
} }
const orderStat = ref({}) const orderStat = ref({})
const prodId = ref(7)
const getOrderStat = () => { const getOrderStat = () => {
badgeApi.getOrderStat({}).then((res: any) => { badgeApi.getOrderStat({}).then((res: any) => {
orderStat.value = res orderStat.value = res
prodId.value = res.prod_id
getSundryList()
}) })
} }
@ -75,18 +77,10 @@ function goToPreview() {
showToast('请先上传照片') showToast('请先上传照片')
return return
} }
if (isBgShow.value == false && !imgBgUrl.value) {
showToast('请先上传背景照片')
return
}
if (orderStat.value.remain_count <= 0) { if (orderStat.value.remain_count <= 0) {
showToast('剩余次数不足') showToast('剩余次数不足')
return return
} }
if (checkId.value == 0) {
showToast('请选择风格样式')
return
}
isLoading.value = true isLoading.value = true
if (trialCode.value) { if (trialCode.value) {
trialPhone() trialPhone()
@ -117,8 +111,9 @@ const trialPhone = async () => {
message: err.message, message: err.message,
duration: 2000, duration: 2000,
}) })
isLoading.value = false
}).finally(() => { }).finally(() => {
isLoading.value = false
}) })
} }
const picture = ref(null) const picture = ref(null)
@ -154,7 +149,6 @@ const getRandomNumber = () => {
// Pid // Pid
const pid = ref('') const pid = ref('')
const kindId = ref(0)
const getPid = async () => { const getPid = async () => {
showLoadingToast({ showLoadingToast({
message: '上传中...', message: '上传中...',
@ -163,15 +157,13 @@ const getPid = async () => {
duration: 0, duration: 0,
}) })
const params = { const params = {
extend_value: isBgShow.value ? -1 : 0, prod_id: prodId.value
kind_id: checkId.value,
} }
try { try {
const res = await badgeApi.getPid(params) const res = await badgeApi.getPid(params)
console.log('getPid', res) console.log('getPid', res)
isLoading.value = false isLoading.value = false
pid.value = res.pid pid.value = res.pid
if (isBgShow.value) {
try { try {
const uploadTasks = [ const uploadTasks = [
sendToOss(imgurl.value, res.url), sendToOss(imgurl.value, res.url),
@ -185,24 +177,8 @@ const getPid = async () => {
message: '上传失败', message: '上传失败',
duration: 2000, duration: 2000,
}) })
} isLoading.value = false
} else { return
try {
const uploadTasks = [
sendToOss(imgurl.value, res.url),
sendToOss(imgurl.value, res.oss_url),
sendToOss(imgBgUrl.value, res.extend_url),
sendToOss(imgBgUrl.value, res.extend_bg_url)
]
await Promise.all(uploadTasks)
} catch (err) {
closeToast()
console.error('上传失败:', err)
showFailToast({
message: '上传失败',
duration: 2000,
})
}
} }
} catch (err) { } catch (err) {
isLoading.value = false isLoading.value = false
@ -240,11 +216,10 @@ const sendToOss = async (src: string, url: string) => {
isAnotherAPICalled.value = true isAnotherAPICalled.value = true
const params = { const params = {
pid: pid.value, pid: pid.value,
kind_id: checkId.value,
extend_value: isBgShow.value ? -1 : 0,
group: 1, group: 1,
prod_id: prodId.value
} }
badgeApi.putMOdeling(params).then((res: any) => { badgeApi.putModeling(params).then((res: any) => {
console.log('putModeling', res) console.log('putModeling', res)
createLog() createLog()
}).catch((err) => { }).catch((err) => {
@ -268,7 +243,7 @@ const createLog = () => {
const params = { const params = {
pid: pid.value, pid: pid.value,
group: 1, group: 1,
kind_id: checkId.value, prod_id: prodId.value
} }
badgeApi.createLog(params).then((res: any) => { badgeApi.createLog(params).then((res: any) => {
console.log('createLog', res) console.log('createLog', res)
@ -283,6 +258,7 @@ const createLog = () => {
query: { query: {
pid: pid.value, pid: pid.value,
group: 1, group: 1,
prod_id: prodId.value
}, },
}) })
}, 1000); }, 1000);
@ -297,32 +273,12 @@ const createLog = () => {
}) })
} }
const kindList = ref([])
const checkId = ref(0)
const getKindList = () => {
badgeApi.getKindList({
page: 1,
size: 20,
scale: 20,
}).then((res: any) => {
const data = res || []
kindList.value = data.list
}).catch((err) => {
showToast({
message: err.message,
duration: 2000,
})
}).finally(() => {
})
}
const sundryList = ref([]) const sundryList = ref([])
const getSundryList = () => { const getSundryList = () => {
badgeApi.getSundryList({ badgeApi.getSundryList({
page: 1, page: 1,
size: 6, size: 6,
group: 'gp', group: prodId.value == 7 ? 'gp' : 'pet',
}).then((res: any) => { }).then((res: any) => {
const data = res || [] const data = res || []
sundryList.value = data.list sundryList.value = data.list
@ -335,25 +291,7 @@ const getSundryList = () => {
}) })
} }
const caseList = ref([])
const getList = () => {
badgeApi.getSundryList({
page: 1,
size: 5,
group: 'case',
ids: '6,7,8,9,19'
}).then((res: any) => {
const data = res || []
caseList.value = data.list
}).catch((err) => {
showToast({
message: err.message,
duration: 2000,
})
}).finally(() => {
})
}
const trialCode = ref(false) const trialCode = ref(false)
const trialCodeValue = ref('') const trialCodeValue = ref('')
const getTrialCode = () => { const getTrialCode = () => {
@ -380,6 +318,10 @@ const onBlur = async () => {
return; return;
} }
} }
const styleChange = (id: number) => {
prodId.value = id
getSundryList()
}
const key = CryptoJS.enc.Utf8.parse("123abcdefpua2025"); const key = CryptoJS.enc.Utf8.parse("123abcdefpua2025");
const iv = CryptoJS.enc.Utf8.parse('DYgjCEIMVrj2W9xN'); const iv = CryptoJS.enc.Utf8.parse('DYgjCEIMVrj2W9xN');
function Encrypt(word: string): string { function Encrypt(word: string): string {
@ -387,7 +329,6 @@ function Encrypt(word: string): string {
let encrypted = CryptoJS.AES.encrypt(srcs, key, { let encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return encrypted.ciphertext.toString(); return encrypted.ciphertext.toString();
} }
function handleBeforeUnload(_event: BeforeUnloadEvent) { function handleBeforeUnload(_event: BeforeUnloadEvent) {
localStorage.remove('code') localStorage.remove('code')
@ -395,9 +336,7 @@ function handleBeforeUnload(_event: BeforeUnloadEvent) {
localStorage.remove('userId') localStorage.remove('userId')
} }
onMounted(() => { onMounted(() => {
getKindList()
getSundryList() getSundryList()
getList()
openApp() openApp()
getTrialCode() getTrialCode()
window.addEventListener('beforeunload', handleBeforeUnload); window.addEventListener('beforeunload', handleBeforeUnload);
@ -407,6 +346,24 @@ onMounted(() => {
<template> <template>
<div class="photo-upload-page"> <div class="photo-upload-page">
<div class="badge-size" v-if="trialCode == false"> <div class="badge-size" v-if="trialCode == false">
<div class="order-type">
<div class="order-type-item">
<div class="order-type-item-title" v-if="orderStat.order_no">
订单编号
</div>
<div class="order-type-item-title">
{{ orderStat.order_no }}
</div>
</div>
<div class="order-type-item" v-if="orderStat.prod_id">
<div class="order-type-item-title">
产品类型
</div>
<div class="order-type-item-title">
{{ orderStat.prod_id == 7 ? '人物立体徽章' : '宠物立体徽章'}}
</div>
</div>
</div>
<div class="size-title"> <div class="size-title">
剩余兑换数量 剩余兑换数量
</div> </div>
@ -452,8 +409,18 @@ onMounted(() => {
@confirm="onBlur" @confirm="onBlur"
/> />
<p style="font-size: 12px; color: #000; margin-left: 16px;">需要先输入手机号才可体验徽章设计</p> <p style="font-size: 12px; color: #000; margin-left: 16px;">需要先输入手机号才可体验徽章设计</p>
<div class="style-box">
<div class="style-box-item">
<div class="style-item-title" :class="{ styleActive: prodId == 7 }" @click="styleChange(7)">
人物立体徽章
</div>
<div class="style-item-title" :class="{ styleActive: prodId == 8 }" @click="styleChange(8)">
宠物立体徽章
</div> </div>
<div style="height: 8px;background: #F2F2F2;" /> </div>
</div>
</div>
<div style="height: 8px;background: #F2F2F2;"></div>
<div class="step-container" v-if="trialCode == false"> <div class="step-container" v-if="trialCode == false">
<div class="step-item active"> <div class="step-item active">
<div class="step-num"> <div class="step-num">
@ -508,75 +475,9 @@ onMounted(() => {
<h5-cropper :option="option" @getbase64Data="getbase64Data" @getFile="getFile" @getblob='getBlob' ></h5-cropper> <h5-cropper :option="option" @getbase64Data="getbase64Data" @getFile="getFile" @getblob='getBlob' ></h5-cropper>
</div> </div>
</div> </div>
<div style="font-size: 12px; color: red; margin-top: 16px; text-align: center;">温馨提示请上传只有1-2人的照片</div> <div style="font-size: 12px; color: red; margin-top: 16px; text-align: center;" v-if="prodId == 7">温馨提示请上传只有1-2人的照片</div>
<div class="style-section"> <div style="font-size: 12px; color: red; margin-top: 16px; text-align: center;" v-if="prodId == 8">温馨提示请上传只有1-3只宠物的照片</div>
<div class="style-title"> <div style="height: 90px;"></div>
风格样式
</div>
<div class="style-list">
<!-- <div class="style-item" @click="checkId = 0">
<img class="style-img" src="@/assets/badge/suiji.png" alt="随机风格盲盒">
<div class="style-label">
随机风格盲盒
</div>
<span class="style-selected" v-if="checkId == 0" />
</div> -->
<div class="style-item" v-for="item in kindList" :key="item.id" @click="checkId = item.id">
<img class="style-img" :src="item.path" :alt="item.name">
<div class="style-label">
{{ item.name }}
</div>
<span class="style-selected" v-if="item.id == checkId" />
</div>
</div>
</div>
<div class="bg-style-section">
<div class="bg-style-header">
<span class="bg-style-title">背景样式</span>
<span class="bg-style-desc disabled" @click="show = true">
<van-icon name="question-o" size="16px" />
<span class="iconfont" style="margin-left:5px;font-size:14px;vertical-align:middle;">背景样式说明</span>
</span>
</div>
<div class="bg-style-tabs">
<button
class="bg-style-tab" :class="isBgShow == true ? 'active' : ''"
type="button" @click="isBgShow = true"
>
照片原图背景
</button>
<button
class="bg-style-tab" :class="isBgShow == false ? 'active' : ''"
type="button" @click="isBgShow = false"
>
补充背景照片
</button>
</div>
<div v-if="isBgShow == true" class="bg-style-tip">
选择该选项设计的徽章会根据上传的肖像照片背景进行生成效果
</div>
<div v-if="isBgShow == false" class="bg-style-tip">
选择该选项需要额外上传一张照片作为背景
</div>
</div>
<div class="bg-photo-upload-section" v-if="isBgShow == false">
<div class="bg-photo-upload-header">
<span>补充背景照片</span>
</div>
<div class="bg-photo-upload-area">
<div v-if="!imgBgUrl" class="bg-photo-upload-label">
<div class="bg-photo-upload-box">
<div class="bg-photo-upload-plus">+</div>
<div class="bg-photo-upload-text">上传照片</div>
</div>
</div>
<img v-if="pictureBg" class="bg-photo-upload-img" :src="pictureBg" alt="">
<div class="bg-photo-upload-label-1">
<h5-cropper :option="options" @getbase64Data="getBgbase64Data" @getFile="getFile" @getblob='getBlobBg'></h5-cropper>
</div>
</div>
</div>
<div style="height: 90px;" />
<div class="design-action-bar"> <div class="design-action-bar">
<div class="design-left"> <div class="design-left">
<img class="design-leaf-icon" width="18" height="18" src="@/assets/badge/leaf.png" alt=""> <img class="design-leaf-icon" width="18" height="18" src="@/assets/badge/leaf.png" alt="">
@ -589,47 +490,6 @@ onMounted(() => {
</button> </button>
</div> </div>
</div> </div>
<van-action-sheet v-model:show="show" title="背景样式说明" :close-on-click-overlay="true" closeable>
<div style="padding: 24px 16px;">
<div style="font-weight: bold; font-size: 15px; margin-bottom: 4px;">
照片自有背景
</div>
<div style="font-size: 12px; color: #888; margin-bottom: 12px;">
选择该选项设计的徽章会根据上传的人像照片背景进行生成效果
</div>
<div style="display: flex; align-items: center; justify-content: center; margin-bottom: 24px;">
<img :src="caseList[2].path" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover; margin-right: 12px;">
<span style="font-size: 24px; color: #bbb; margin-right: 12px;">
<van-icon name="arrow" />
</span>
<img :src="caseList[3].path" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover;">
</div>
<div style="font-weight: bold; font-size: 15px; margin-bottom: 4px;">
补充背景照片
</div>
<div style="font-size: 12px; color: #888; margin-bottom: 12px;">
选择该选项需要额外上传一张照片作为背景
</div>
<div style="display: flex; align-items: center; justify-content: center; margin-bottom: 12px;">
<img :src="caseList[0].path" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover; margin-right: 12px;">
<span style="font-size: 24px; color: #bbb; margin-right: 12px;">
<van-icon name="plus" />
</span>
<img :src="caseList[1].path" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover;">
</div>
<div style="font-size: 24px; color: #bbb;text-align: center;">
<van-icon name="arrow-down" />
</div>
<div style="display: flex; align-items: center; justify-content: center; margin-top: 12px;">
<img :src="caseList[4].path" style="width: 120px; height: 120px; border-radius: 16px; object-fit: cover;">
</div>
<div style="margin-top: 32px; text-align: center;">
<button style="width: 90%; height: 44px; background: linear-gradient(90deg, #d6f5b7 0%, #50cf54 100%); border: none; border-radius: 22px; color: #222; font-size: 18px; font-weight: bold; cursor: pointer;" @click="show = false">
我已了解
</button>
</div>
</div>
</van-action-sheet>
<van-action-sheet v-model:show="imgShow" title="图片上传指南" :close-on-click-overlay="true" closeable> <van-action-sheet v-model:show="imgShow" title="图片上传指南" :close-on-click-overlay="true" closeable>
<div style="padding: 0 16px 24px 16px;"> <div style="padding: 0 16px 24px 16px;">
@ -1153,4 +1013,37 @@ onMounted(() => {
padding-bottom: 120px; padding-bottom: 120px;
} }
} }
.order-type-item {
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
border-radius: 12px;
margin-bottom: 12px;
font-size: 14px;
}
.style-box {
padding: 0 16px;
}
.style-box-item {
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 12px;
font-size: 14px;
margin-bottom: 12px;
}
.style-item-title {
width: 48%;
text-align: center;
padding: 10px 0;
border-radius: 12px;
color: #333;
font-size: 14px;
background: #f5f5f5;
}
.style-item-title.styleActive {
background: #50cf54;
color: #fff;
}
</style> </style>

309
src/views/badge/preview.vue

@ -25,20 +25,35 @@
<div class="progress-bar-fg" :style="{ width: progress + '%' }"></div> <div class="progress-bar-fg" :style="{ width: progress + '%' }"></div>
</div> </div>
<div class="progress-text">{{progressText}} {{progress}}%</div> <div class="progress-text">{{progressText}} {{progress}}%</div>
<div class="progress-desc">总计大约需要60秒请耐心等待...</div> <div class="progress-desc">总计大约需要90秒请耐心等待...</div>
</div> </div>
<div v-else class="progress-section"> <div v-else class="progress-section">
<van-swipe v-model="currentIndex" class="progress-section-img" :autoplay="3000" :show-indicators="false"> <!-- <van-swipe v-model="currentIndex" class="progress-section-img" :autoplay="3000" :show-indicators="false">
<van-swipe-item v-for="item in imageList" :key="item.id"> <van-swipe-item v-for="item in imageList" :key="item.id">
<img class="progress-section-img" :src="item.origin_url" alt=""> <img class="progress-section-img" :src="item.origin_url" alt="">
<div class="progress-image-item-shadow"></div> <div class="progress-image-item-shadow"></div>
</van-swipe-item> </van-swipe-item>
</van-swipe> </van-swipe> -->
<div class="progress-section-img">
<img class="progress-section-img-item" :src="imageUrl" alt="">
<div class="progress-image-item-shadow"></div>
</div>
<div class="image-list-box">
<div class="image-list-item" v-for="item in imageList" :key="item.key">
<img v-if="item.status == 1" class="image-list-item-img" :class="{ imgActive: item.key == imgKey }" :src="item.origin_url" alt="" @click="changeImage(item)">
<div v-else-if="item.status == 0" class="image-list-item-loading">
设计中
</div>
<div v-else-if="item.status == 2" class="image-list-item-loading">
设计失败
</div>
</div>
</div>
</div> </div>
<div class="info-section"> <div class="info-section">
<div class="info-item"> <div class="info-item">
<div class="info-title">{{ style_name }}</div> <div class="info-title">{{ prodId == 7 ? '人物立体徽章' : '宠物立体徽章' }}</div>
<div class="info-content">风格</div> <div class="info-content">产品类型</div>
</div> </div>
<div class="info-item"> <div class="info-item">
<div class="info-title">3D全彩打印</div> <div class="info-title">3D全彩打印</div>
@ -49,10 +64,10 @@
<div class="info-content">材料</div> <div class="info-content">材料</div>
</div> </div>
</div> </div>
<div class="info-desc"> <!-- <div class="info-desc">
下单后预计需要7天完成生产发货<br> 下单后预计需要7天完成生产发货<br>
实物3D打印色彩与图片有合理色差如对产品有疑问可以联系客服咨询 实物3D打印色彩与图片有合理色差如对产品有疑问可以联系客服咨询
</div> </div> -->
<div style="padding: 0 16px;"> <div style="padding: 0 16px;">
<van-divider /> <van-divider />
</div> </div>
@ -65,51 +80,19 @@
<van-stepper v-model="item.count" :min="0" :max="item.remaining" @change="changeValue" /> <van-stepper v-model="item.count" :min="0" :max="item.remaining" @change="changeValue" />
</div> </div>
</div> </div>
<!-- <div class="order-item">
<span class="order-size">5cm</span>
<span class="order-free">(剩余兑换2)</span>
<div class="order-ctrl">
<van-stepper v-model="value" />
</div>
</div> -->
</div> </div>
<div style="height: 110px;"></div> <div style="height: 110px;"></div>
<div class="confirm-box"> <div class="confirm-box">
<div class="action-section"> <div class="action-section">
<button v-if="trialCode == false" @click="reload" :disabled="flag < 2" class="action-btn"><img class="action-img" src="@/assets/badge/reload.png" alt=""> 再次生成</button> <button v-if="trialCode == false" @click="sureReload" :disabled="flag < 1" class="action-btn"><img class="action-img" src="@/assets/badge/reload.png" alt=""> 再次生成</button>
<button v-if="trialCode == true" @click="compare" :disabled="flag < 2" class="action-btn"><img class="action-img" src="@/assets/badge/duibi.png" alt=""> 前后对比</button> <button @click="compare" :disabled="flag < 1" class="action-btn"><img class="action-img" src="@/assets/badge/duibi.png" alt=""> 前后对比</button>
<button v-if="trialCode == true" @click="save" :disabled="flag < 2" class="action-btn"><img class="action-img" src="@/assets/badge/down.png" alt=""> 保存图片</button> <button @click="save" :disabled="flag < 1" class="action-btn"><img class="action-img" src="@/assets/badge/down.png" alt=""> 保存图片</button>
</div> </div>
<div class="btn-box" v-if="trialCode == false"> <div class="btn-box" v-if="trialCode == false">
<button @click="confirm" :disabled="flag < 2" class="confirm-btn">确认选择</button> <button @click="confirm" :disabled="flag < 1" class="confirm-btn">确认选择</button>
</div>
</div>
</div>
<van-action-sheet v-model:show="showReload" title="风格样式选择" :close-on-click-overlay="true" closeable>
<div class="style-selection">
<div class="style-grid">
<!-- <div class="style-item" :class="{'active': checkId == 0}" @click="checkId = 0">
<img src="@/assets/badge/suiji.png" alt="随机风格盲盒" class="style-img">
<div class="style-label">随机风格盲盒</div>
<span class="style-selected" v-if="checkId == 0" style="display: inline-block;">
<van-icon name="checked" color="#50cf54" size="21px" />
</span>
</div> -->
<div class="style-item" :class="{'active': item.id == checkId}" v-for="item in kindList" :key="item.id" @click="checkId = item.id">
<img :src="item.path" :alt="item.name" class="style-img">
<div class="style-label">{{item.name}}</div>
<span class="style-selected" v-if="item.id == checkId">
<van-icon name="checked" color="#50cf54" size="21px" />
</span>
</div> </div>
</div> </div>
<div class="confirm-wrapper">
<button class="confirm-button" @click="sureReload">
确认再次生成
</button>
</div> </div>
</div>
</van-action-sheet>
<van-action-sheet v-model:show="showCompare" title="前后对比" :close-on-click-overlay="true" closeable> <van-action-sheet v-model:show="showCompare" title="前后对比" :close-on-click-overlay="true" closeable>
<div style="padding: 16px;"> <div style="padding: 16px;">
@ -132,38 +115,9 @@
</div> </div>
</van-action-sheet> </van-action-sheet>
<van-action-sheet v-model:show="showBgCompare" title="前后对比" :close-on-click-overlay="true" closeable>
<div style="padding: 16px;">
<div style="display: flex; align-items: center; justify-content: center; gap: 20px;">
<div style="text-align: center;">
<img :src="compareList.origin_path" alt="原图" style="width: 120px; height: 120px; border-radius: 8px;">
</div>
<div style="font-size: 24px; color: #333;">
<van-icon name="plus" size="20px" />
</div>
<div style="text-align: center;">
<img :src="compareList.extend_path" alt="背景图" style="width: 120px; height: 120px; border-radius: 8px;">
</div>
</div>
<div style="font-size: 24px; color: #333;display: flex; align-items: center; justify-content: center; margin: 16px 0;">
<van-icon name="arrow-down" size="20px" />
</div>
<div style="display: flex; align-items: center; justify-content: center; gap: 20px;">
<div style="text-align: center;">
<img :src="imageUrl" alt="效果图" style="width: 120px; height: 120px; border-radius: 8px;">
</div>
</div>
<div style="text-align: center; margin-top: 16px; color: #999; font-size: 12px;">
温馨提示<br/>
AI设计的图案效果图是根据用户提供的照片机器学习生成的<br/>
多试几次就能找到你满意的效果~
</div>
</div>
</van-action-sheet>
<div v-if="showPreview"> <div v-if="showPreview">
<div class="preview-mask" @click="showPreview = false"> <div class="preview-mask" @click="showPreview = false">
<img :src="imageUrl" alt="徽章预览" /> <img :src="imageWater" alt="徽章预览" />
<p>长按图片 保存到相册</p> <p>长按图片 保存到相册</p>
</div> </div>
</div> </div>
@ -181,52 +135,28 @@ const showCompare = ref(false)
const showBgCompare = ref(false) const showBgCompare = ref(false)
const currentIndex = ref(0) const currentIndex = ref(0)
const imageList = ref([]) const imageList = ref([])
const imageWater = ref('')
function compare() { function compare() {
if (extend_value.value == -1) {
showCompare.value = true showCompare.value = true
} else {
showBgCompare.value = true
} }
}
const kindList = ref([])
const checkId = ref(0)
function reload() {
badgeApi.getKindList({
page: 1,
size: 20,
scale: 20,
}).then((res: any) => {
const data = res || []
kindList.value = data.list
}).catch((err) => {
showToast({
message: err.message,
duration: 2000,
})
}).finally((err) => {
})
showReload.value = true
}
// const getKindID = () => {
// return kindList.value.map(obj => obj.id)[Math.floor(Math.random() * kindList.value.length)];
// }
function sureReload() { function sureReload() {
console.log('sureReload') if (payAmount.value <= 0) {
if (checkId.value == 0) { showToast('当前次数已用完,请重新购买')
showToast('请选择风格样式')
return return
} }
imageUrl.value = ''; isPreview.value = false
group.value = newGroup.value group.value = newGroup.value
const params = { const params = {
pid: pid.value, pid: pid.value,
kind_id: checkId.value,
extend_value: extend_value.value,
group: group.value, group: group.value,
prod_id: prodId.value
} }
badgeApi.putMOdeling(params).then((res: any) => { badgeApi.putModeling(params).then((res: any) => {
console.log('putModeling', res) console.log('putModeling', res)
imageUrl.value = '';
imageList.value = []
imgKey.value = '';
createLog() createLog()
}).catch((err) => { }).catch((err) => {
console.log('putModeling', err) console.log('putModeling', err)
@ -241,11 +171,18 @@ function sureReload() {
} }
const imgKey = ref(101)
const changeImage = (item: any) => {
imgKey.value = item.key
imageUrl.value = item.origin_url
imageWater.value = item.url
}
const createLog = () => { const createLog = () => {
badgeApi.createLog({ badgeApi.createLog({
pid: pid.value, pid: pid.value,
kind_id: checkId.value,
group: group.value, group: group.value,
prod_id: prodId.value
}).then((res: any) => { }).then((res: any) => {
console.log('createLog', res) console.log('createLog', res)
showReload.value = false showReload.value = false
@ -269,35 +206,17 @@ const createLog = () => {
const showPreview = ref(false) const showPreview = ref(false)
function save() { function save() {
//
// const downloadImage = (url: string) => {
// const link = document.createElement('a')
// link.href = url
// link.download = '.png'
// document.body.appendChild(link)
// link.click()
// document.body.removeChild(link)
// }
// if (imageUrl.value) {
// try {
// downloadImage(imageUrl.value);
// } catch {
// showPreview.value = true; //
// }
// }
showPreview.value = true; showPreview.value = true;
} }
const compareList = ref({}) const compareList = ref({})
const extend_value = ref(0)
const style_name = ref('') const style_name = ref('')
function getCompareImage() { function getCompareImage() {
badgeApi.getCompareImage({ badgeApi.getCompareImage({
pid: pid.value, pid: pid.value,
group: group.value, group: group.value,
prod_id: prodId.value
}).then((res: any) => { }).then((res: any) => {
console.log('getCompareImage', res) console.log('getCompareImage', res)
extend_value.value = res.extend_value
compareList.value = res compareList.value = res
style_name.value = res.list[0].kind_name || res.kind_name style_name.value = res.list[0].kind_name || res.kind_name
}).catch((err) => { }).catch((err) => {
@ -340,14 +259,15 @@ const confirm = () => {
showConfirmDialog({ showConfirmDialog({
title: '确认下单', title: '确认下单',
message: message:
'请再次确认是否选择这个模型下单。', '请再次确认是否选择这个模型下单,一个链接只能下单一次。',
}) })
.then(() => { .then(() => {
const parms = { const parms = {
pid: pid.value, pid: pid.value,
key: key.value, key: imgKey.value,
pay_amount: payAmount.value, pay_amount: payAmount.value,
products: sizeList.value products: sizeList.value,
prod_id: prodId.value
} }
badgeApi.creatOrder(parms).then((res: any) => { badgeApi.creatOrder(parms).then((res: any) => {
console.log('creatOrder', res) console.log('creatOrder', res)
@ -371,6 +291,7 @@ const confirm = () => {
}) })
}) })
.catch(() => { .catch(() => {
loading.value = false
// on cancel // on cancel
}); });
@ -406,14 +327,71 @@ const progressList = () => {
} }
const newGroup = ref(0) const newGroup = ref(0)
const isPreview = ref(false)
const getImageList = () => { const getImageList = () => {
badgeApi.getImageList({ badgeApi.getImageList({
pid: pid.value, pid: pid.value,
group: group.value group: group.value,
prod_id: prodId.value
}).then((res: any) => { }).then((res: any) => {
console.log('getImageList', res) console.log('getImageList', res)
const data = res || [] const data = res || []
flag.value = data.flag flag.value = data.flag
prodId.value = data.prod_id
if (data.flag === 1) {
newGroup.value = data.next_group
nextTick(() => {
//
const newList = data.list.map(item => ({
...item,
isNew: true
}))
// 1()
const firstGeneratedImage = newList.find(item => item.status === 1)
// ,
if (firstGeneratedImage && !isPreview.value) {
imageUrl.value = firstGeneratedImage.origin_url
imageWater.value = firstGeneratedImage.url
imgKey.value = firstGeneratedImage.key
isPreview.value = true
}
// ,
const mergedList = imageList.value.map(item => {
const newItem = newList.find(n => n.key === item.key)
return newItem || item
})
//
newList.forEach(newItem => {
if (!mergedList.find(item => item.key === newItem.key)) {
mergedList.push(newItem)
}
})
//
imageList.value = mergedList
// ,
console.log('imgKey.value', imgKey.value)
if (imgKey.value) {
const currentImage = mergedList.filter((item: any) => item.key === imgKey.value)[0]
console.log('currentImage', currentImage)
if (currentImage && currentImage.status === 1) {
imageUrl.value = currentImage.origin_url
imageWater.value = currentImage.url
isPreview.value = true
} else {
imageUrl.value = currentImage.origin_url
imageWater.value = currentImage.url
isPreview.value = true
}
}
})
}
if (data.flag === 2) { if (data.flag === 2) {
newGroup.value = data.next_group newGroup.value = data.next_group
// //
@ -424,14 +402,22 @@ const getImageList = () => {
progress.value = 100 progress.value = 100
// //
imageUrl.value = data.list[0].origin_url
imageList.value = data.list imageList.value = data.list
key.value = data.list[0].key if (imgKey.value) {
imageUrl.value = data.list.filter((item: any) => item.key == imgKey.value)[0].origin_url
imageWater.value = data.list.filter((item: any) => item.key == imgKey.value)[0].url
} else {
imageUrl.value = data.list[0].origin_url
imageWater.value = data.list[0].url
imgKey.value = data.list[0].key
}
localStorage.remove('userId') localStorage.remove('userId')
} }
}).catch((err) => { }).catch((err) => {
clearInterval(progressTimer.value) //
progress.value = 0 // clearInterval(timer.value)
// clearInterval(progressTimer.value)
// progress.value = 0
showToast({ showToast({
message: err.message, message: err.message,
duration: 2000, duration: 2000,
@ -453,15 +439,27 @@ function handleBeforeUnload(_event: BeforeUnloadEvent) {
localStorage.remove('code') localStorage.remove('code')
localStorage.remove('trialCode') localStorage.remove('trialCode')
localStorage.remove('userId') localStorage.remove('userId')
//
clearInterval(timer.value)
clearInterval(progressTimer.value)
} }
const pid = ref(0) const pid = ref(0)
const route = useRoute() const route = useRoute()
const prodId = ref(0)
onMounted(() => { onMounted(() => {
pid.value = route.query.pid pid.value = route.query.pid
group.value = route.query.group group.value = route.query.group
if (route.query.key) {
imgKey.value = route.query.key
}
if (route.query.prod_id) {
prodId.value = route.query.prod_id
}
// pid.value = 281505; // pid.value = 281505;
// group.value = 1; // group.value = 1;
// prodId.value = 7;
getImageList() getImageList()
progressList() progressList()
getCompareImage() getCompareImage()
@ -597,7 +595,7 @@ onUnmounted(() => {
margin: 0 auto; margin: 0 auto;
text-align: center; text-align: center;
width: 80vw; width: 80vw;
height: 80vw; min-height: 80vw;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -607,6 +605,12 @@ onUnmounted(() => {
width: 80vw; width: 80vw;
height: 80vw; height: 80vw;
border-radius: 50%; border-radius: 50%;
position: relative;
}
.progress-section-img-item {
width: 80vw;
height: 80vw;
border-radius: 50%;
} }
.progress-bar-bg { .progress-bar-bg {
width: 70%; width: 70%;
@ -863,10 +867,41 @@ onUnmounted(() => {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 80vw;
height: 100%; height: 80vw;
object-fit: cover; object-fit: cover;
box-shadow: inset 2px 2px 4px rgba(255, 255, 255, 0.5),inset -2px -2px 4px rgba(0, 0, 0, 0.2); box-shadow: inset 2px 2px 4px rgba(255, 255, 255, 0.5),inset -2px -2px 4px rgba(0, 0, 0, 0.2);
border-radius: 50%; border-radius: 50%;
} }
.image-list-box {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
padding: 16px 16px 0 16px;
}
.image-list-item {
width: 20vw;
height: 20vw;
}
.image-list-item-img {
width: 20vw;
height: 20vw;
border-radius: 12px;
border: 3px solid #fff;
}
.image-list-item-img.imgActive {
border: 3px solid #50cf54;
}
.image-list-item-loading {
width: 20vw;
height: 20vw;
border-radius: 12px;
background: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #999;
}
</style> </style>

2
src/views/badge/record.vue

@ -67,6 +67,8 @@ function goPreview(item) {
query: { query: {
pid: item.sw_pid, pid: item.sw_pid,
group: item.group_count, group: item.group_count,
key: item.num,
prod_id: item.prod_id
}, },
}) })
} }

Loading…
Cancel
Save