forked from natuka/web.puabadge.com
Initial commit
This commit is contained in:
commit
84061c9a18
243 files changed
+63148
No files matched your search
@@ -0,0 +1,331 @@
|
||||
<template>
|
||||
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" left-text="返回" left-arrow
|
||||
@click-left="returnClick" safe-area-inset-top/>
|
||||
<div>
|
||||
<div class="page">
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<div class="s-title">SUWA3D</div>
|
||||
<div class="l-title">关于我们</div>
|
||||
</div>
|
||||
<div class="description">速相科技成立于2016年,总部在福建厦门<br />目前是全球首家商业化3D人像摄影专业机构<br />产品材料安全环保,细节还原度高<br />旗下的品牌“速哇”为国内首家数字人3D真人手办连锁品牌<br />速哇3D手办亲人、朋友、恋人、宠物的各种美好时刻记录下来</div>
|
||||
<div class="info-box">
|
||||
<img src="@/assets/about/mail.png" class="info-icon"/>
|
||||
<div class="info-detail">
|
||||
<div class="info-label">邮箱</div>
|
||||
<div class="info-value">business@suwa3d.com</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box" @click="call(1)">
|
||||
<img src="@/assets/about/hands.png" class="info-icon"/>
|
||||
<div class="info-detail">
|
||||
<div class="info-label">合作热线</div>
|
||||
<div class="info-value">400 6667 215</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box" @click="call(2)">
|
||||
<img src="@/assets/about/tel.png" class="info-icon"/>
|
||||
<div class="info-detail">
|
||||
<div class="info-label">招商电话</div>
|
||||
<div class="info-value">18046215201</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box" @click="call(1)">
|
||||
<img src="@/assets/about/hands.png" class="info-icon"/>
|
||||
<div class="info-detail">
|
||||
<div class="info-label">合作热线</div>
|
||||
<div class="info-value">400 6667 215</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box" @click="call(2)">
|
||||
<img src="@/assets/about/tel.png" class="info-icon"/>
|
||||
<div class="info-detail">
|
||||
<div class="info-label">招商电话</div>
|
||||
<div class="info-value">18046215201</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<div class="s-title">SUWA3D</div>
|
||||
<div class="l-title">全国门店</div>
|
||||
</div>
|
||||
<img src="@/assets/about/map.png" class="map_img"/>
|
||||
<div class="group_6">
|
||||
<div class="shop-count">
|
||||
<div class="under_border"></div>
|
||||
<div class="count">49+</div>
|
||||
</div>
|
||||
<div class="text_25">家门店</div>
|
||||
<div class="point">
|
||||
<div class="group_7"></div>
|
||||
<div class="group_8"></div>
|
||||
</div>
|
||||
<div class="text-wrapper_4">
|
||||
<div class="text_26">速哇加盟门店城市</div>
|
||||
<div class="text_27">速哇待开业门店</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {useStore} from '@/stores'
|
||||
const store = useStore();
|
||||
import { useTokenStore } from '@/stores/token'
|
||||
const tokenStore = useTokenStore();
|
||||
const userInfo = ref("")
|
||||
|
||||
const {isWechat} = tokenStore;
|
||||
|
||||
onMounted(()=> {
|
||||
userInfo.value = tokenStore.userInfo;
|
||||
})
|
||||
const returnClick = () => history.back()
|
||||
const call = (num: number) => {
|
||||
const a = document.createElement("a");
|
||||
let phoneNum = ""
|
||||
switch(num) {
|
||||
case 1: phoneNum = "4006667215";break;
|
||||
case 2: phoneNum = "18046215201";break;
|
||||
}
|
||||
a.href = "tel:" + phoneNum;
|
||||
a.click();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
background-color: rgba(255, 255, 255, 1.000000);
|
||||
position: relative;
|
||||
width: 375px;
|
||||
height: 100vh;
|
||||
overflow: scroll;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
.section {
|
||||
width: 375px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 50px;
|
||||
.section-title {
|
||||
width: 157px;
|
||||
height: 40px;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
margin: 25px auto 0 auto;
|
||||
.s-title {
|
||||
overflow-wrap: break-word;
|
||||
font-size: 36px;
|
||||
font-family: Source Han Sans CN-Heavy;
|
||||
font-weight: 900;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
line-height: 36px;
|
||||
webkit-background-clip: text;
|
||||
webkit-text-fill-color: transparent;
|
||||
color: mintcream;
|
||||
}
|
||||
|
||||
.l-title {
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(61, 61, 61, 1.000000);
|
||||
font-size: 24px;
|
||||
font-family: Source Han Sans CN-Bold;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
line-height: 24px;
|
||||
margin: 16px 30px 0 -126px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
width: 345px;
|
||||
height: 108px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(102, 102, 102, 1.000000);
|
||||
font-size: 12px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
line-height: 18px;
|
||||
margin: 30px auto 15px auto;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
width: 205px;
|
||||
height: 54px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 30px auto 0 auto;
|
||||
.info-icon {
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
}
|
||||
.info-detail {
|
||||
width: 131px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
.info-label {
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Medium;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
line-height: 16px;
|
||||
}
|
||||
.info-value {
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(153, 153, 153, 1.000000);
|
||||
font-size: 12px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
line-height: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-group_7 {
|
||||
width: 157px;
|
||||
height: 40px;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
margin: 50px 0 31px 109px;
|
||||
}
|
||||
|
||||
.map_img {
|
||||
width: 345px;
|
||||
height: 283px;
|
||||
margin: 50px auto 0 auto;
|
||||
}
|
||||
|
||||
.group_6 {
|
||||
width: 305px;
|
||||
height: 44px;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
margin: 30px auto;
|
||||
}
|
||||
|
||||
.shop-count {
|
||||
position: relative;
|
||||
width: 73px;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.under_border {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-image: linear-gradient(90deg, rgba(85, 176, 56, 0.000000) 0, rgba(108, 217, 73, 1.000000) 100.000000%);
|
||||
width: 73px;
|
||||
height: 16px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.count {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 73px;
|
||||
height: 36px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 40px;
|
||||
font-family: Source Han Sans CN-Heavy;
|
||||
font-weight: 900;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.text_25 {
|
||||
width: 48px;
|
||||
height: 16px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Heavy;
|
||||
font-weight: 900;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
line-height: 16px;
|
||||
margin: 18px 0 0 5px;
|
||||
}
|
||||
|
||||
.point {
|
||||
width: 8px;
|
||||
height: 38px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin: 3px 0 0 49px;
|
||||
}
|
||||
|
||||
.group_7 {
|
||||
background-color: rgba(85, 176, 56, 1.000000);
|
||||
border-radius: 100%;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.group_8 {
|
||||
background-color: rgba(255, 94, 94, 1.000000);
|
||||
border-radius: 100%;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin-top: 22px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.text-wrapper_4 {
|
||||
width: 112px;
|
||||
height: 44px;
|
||||
margin-left: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.text_26 {
|
||||
width: 112px;
|
||||
height: 14px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(61, 61, 61, 1.000000);
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
.text_27 {
|
||||
width: 83px;
|
||||
height: 14px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(61, 61, 61, 1.000000);
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 14px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,349 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 收件信息页 -->
|
||||
<div class="container">
|
||||
<!-- <mp-dialog
|
||||
show="{{ dialogShow }}"
|
||||
bindbuttontap="tapDialogButton"
|
||||
buttons="{{ buttons }}">
|
||||
<div>
|
||||
<div class="calcelTitle">
|
||||
确定要删除地址?
|
||||
</div>
|
||||
</div>
|
||||
</mp-dialog> -->
|
||||
<van-dialog message="确定要删除地址?" v-model:show="dialogShow"
|
||||
@confirm="tapDialogButton" showCancelButton confirm-button-color="#AAAAAA"
|
||||
cancel-button-color="#009944" round />
|
||||
<div class="main">
|
||||
<block v-if="address_list[0]">
|
||||
<div class="top">
|
||||
<div class="controller" @click="controlEdit" >{{ currentIndex == false ? '管理' : '完成'}}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<block v-for="item, index in address_list" :key="index">
|
||||
<div class="item" @click="onSelect" data-item="{{item}}">
|
||||
<div class="item_wrap">
|
||||
<div class="info">
|
||||
<div class="detail">
|
||||
<div class="user">{{item.receive_contact}}</div>
|
||||
<div class="phoneNumber">{{item.receive_mobile}}</div>
|
||||
<div class="status" v-if="item.is_default == 1">默认</div>
|
||||
<div class="shop_status" v-if="item.shop_id > 0">门店</div>
|
||||
</div>
|
||||
<div class="address">{{item.province_name}} {{item.city_name}} {{item.county_name}} {{item.receive_address}}</div>
|
||||
</div>
|
||||
<div class="edit_box {{!editShow ? 'floatRight' : ''}}">
|
||||
<van-checkbox
|
||||
v-if="!select && !editShow"
|
||||
icon-size="25px"
|
||||
value="{{ addressId == item.id }}"
|
||||
checked-color="#009944"
|
||||
></van-checkbox>
|
||||
<van-icon v-if="editShow" name="edit" size="25" @click.stop="editClick(item.id)"/>
|
||||
<van-icon v-if="editShow" name="cross" size="25" @click.stop="deleteClick(item.shop_id, item.id)"/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</block>
|
||||
</div>
|
||||
</block>
|
||||
<div class="empty" v-else>
|
||||
<div class="text">您还没有收件地址,快添加一个吧~</div>
|
||||
</div>
|
||||
</div>
|
||||
<router-link class="add_btn" to="/address/edit">
|
||||
<div class="add_btn">添加收件地址</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const router = useRouter()
|
||||
const currentIndex = ref(false) // 编辑地址
|
||||
const isCover = ref(false) // 防抖
|
||||
const editShow= ref(false) // 编辑栏展开
|
||||
const baseInfo = ref("") // 本地存储baseInfo
|
||||
const address_list = ref("") // 地址列表
|
||||
const addressId = ref(0) // 地址id
|
||||
const select = ref(false) // 选择
|
||||
const dialogShow = ref(false) // 确认框开关
|
||||
const current_id = ref(0) // 删除的门店id
|
||||
const shop_id = ref(0) // 当前的门店id
|
||||
|
||||
onMounted(()=> {
|
||||
// this.setData({
|
||||
// addressId: options.id,
|
||||
// shop_id: options.shopid,
|
||||
// pid: options.pid,
|
||||
// select: options.select
|
||||
// })
|
||||
getAddress();
|
||||
})
|
||||
|
||||
// 编辑地址
|
||||
const controlEdit = () => {
|
||||
currentIndex.value = !currentIndex.value;
|
||||
editShow.value = !editShow.value;
|
||||
}
|
||||
// 删除确认
|
||||
const tapDialogButton = () => {
|
||||
deleteConfirm();
|
||||
dialogShow.value = false
|
||||
}
|
||||
// 修改地址信息
|
||||
const editClick = (id) => {
|
||||
router.push({
|
||||
path: '/packageAddress/pages/address/edit/edit?id=' + id,
|
||||
})
|
||||
}
|
||||
// 删除点击
|
||||
const deleteClick = (sid, id) => {
|
||||
addressId.value = id;
|
||||
current_id.value = sid;
|
||||
dialogShow.value = true;
|
||||
}
|
||||
// 确定删除
|
||||
const deleteConfirm = () => {
|
||||
// let id = this.data.addressId;
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
// let params = {
|
||||
// id: id,
|
||||
// open_id: u.openid,
|
||||
// union_id: u.unionid,
|
||||
// }
|
||||
// if(this.data.current_id > 0) {
|
||||
// setTimeout(()=> {
|
||||
// wx.showToast({
|
||||
// title: "门店地址不可删除",
|
||||
// icon: "error"
|
||||
// })
|
||||
// }, 500)
|
||||
// return false
|
||||
// }
|
||||
// app.api.deleteAddress(params).then(res=>{
|
||||
// console.log(res)
|
||||
// if(res.code == 1000) {
|
||||
// this.setData({
|
||||
// isCover: true
|
||||
// })
|
||||
// setTimeout(()=> {
|
||||
// this.setData({
|
||||
// isCover: false
|
||||
// })
|
||||
// }, 2000)
|
||||
// wx.showToast({
|
||||
// icon: 'none',
|
||||
// title: res.message
|
||||
// });
|
||||
// setTimeout(()=> {
|
||||
// this.getAddress();
|
||||
// }, 200)
|
||||
// }
|
||||
// })
|
||||
}
|
||||
// 获取所有收件信息
|
||||
const getAddress = () => {
|
||||
// let _this = this;
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
// let obj = {
|
||||
// shop_id: this.data.shop_id,
|
||||
// pid: this.data.pid,
|
||||
// open_id: u.openid,
|
||||
// union_id: u.unionid,
|
||||
// }
|
||||
// app.api.addressList(obj).then(res=> {
|
||||
// console.log(res)
|
||||
// if(res.code == 1000) {
|
||||
// let address_list = res.data;
|
||||
// _this.setData({
|
||||
// address_list
|
||||
// })
|
||||
// }else {
|
||||
// wx.showToast({
|
||||
// icon: 'none',
|
||||
// title: res.message
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
}
|
||||
const onSelect = (e) => {
|
||||
if(editShow.value || select.value) {
|
||||
return false
|
||||
}
|
||||
// const data = e.currentTarget.dataset.item;
|
||||
// const prevPage = getCurrentPages()[getCurrentPages().length - 2];
|
||||
// prevPage.setData({
|
||||
// id: data.id,
|
||||
// receive_contact: data.receive_contact,
|
||||
// receive_mobile: data.receive_mobile,
|
||||
// receive_address: data.receive_address,
|
||||
// city_name: data.city_name,
|
||||
// county_name: data.county_name,
|
||||
// province_name: data.province_name,
|
||||
// shop_id: data.shop_id,
|
||||
// });
|
||||
// wx.navigateBack()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
// background: #f7f7f7;
|
||||
height: 100vh;
|
||||
background: #f8f8f8;
|
||||
.main {
|
||||
width: 100%;
|
||||
.top {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
width: 90%;
|
||||
height: 30px;
|
||||
margin: 0 auto;
|
||||
.controller {
|
||||
font-size: 15px;
|
||||
color: #009944;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.item {
|
||||
width: 100%;
|
||||
height: 62.5px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #d8d8d8;
|
||||
.item_wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 328px;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
font-size: 12px;
|
||||
max-width: 250px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.detail {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-bottom: 7.5px;
|
||||
.user {
|
||||
font-size: 15px;
|
||||
color: #333333;
|
||||
margin-right: 7.5px;
|
||||
max-width: 125px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.phoneNumber {
|
||||
color: #6c6c6c;
|
||||
margin-right: 7.5px;
|
||||
}
|
||||
.status {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 35px;
|
||||
height: 15px;
|
||||
border-radius: 7.5px;
|
||||
background: #ce80ff;
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
}
|
||||
.shop_status {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: 18px;
|
||||
border-radius: 8px;
|
||||
background: #e6a23c;
|
||||
color: #ffffff;
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
padding: 0 7.5px;
|
||||
}
|
||||
}
|
||||
.address {
|
||||
color: #333333;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
}
|
||||
}
|
||||
.edit_box {
|
||||
width: 60px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.edit {
|
||||
width: 16px;
|
||||
height: 20px;
|
||||
}
|
||||
.delete {
|
||||
width: 16.5px;
|
||||
height: 19px;
|
||||
}
|
||||
}
|
||||
.floatRight {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
// height: 100vh;
|
||||
padding: 75px 0;
|
||||
// background: #f8f8f8;
|
||||
.icon {
|
||||
width: 58.5px;
|
||||
height: 55.5px;
|
||||
}
|
||||
.text {
|
||||
font-size: 13px;
|
||||
color: #999999;
|
||||
margin-top: 7.5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.add_btn {
|
||||
position: fixed;
|
||||
bottom: 5%;
|
||||
left: 50%;
|
||||
margin: -18.5px 0 0 -146.5px;
|
||||
background: #009944;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 293px;
|
||||
height: 37px;
|
||||
color: #ffffff;
|
||||
font-size: 15px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,267 @@
|
||||
<template name="cropper">
|
||||
<view>
|
||||
<image :src="imgSrc.imgSrc" class="my-avatar" mode="aspectFill" @click="fSelect" :style="imgStyle"></image>
|
||||
<!-- 上传图片 -->
|
||||
<canvas canvas-id="avatar-canvas" id="avatar-canvas" class="my-canvas" :style="{top: styleTop, height: cvsStyleHeight}"
|
||||
disable-scroll="false"></canvas>
|
||||
<!-- 截取边框 -->
|
||||
<canvas canvas-id="oper-canvas" id="oper-canvas" class="oper-canvas" :style="{top: styleTop, height: cvsStyleHeight}"
|
||||
disable-scroll="false" @touchstart="fStart" @touchmove="fMove" @touchend="fEnd"></canvas>
|
||||
<view class="oper-wrapper" :style="{display: styleDisplay}">
|
||||
<view class="btn-wrapper" v-if="showOper">
|
||||
<view @click="fClose" hover-class="hover">取消</view>
|
||||
<view @click="fUpload" hover-class="hover">选取</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const tabHeight = 70;
|
||||
export default {
|
||||
name: "cropper",
|
||||
data() {
|
||||
return {
|
||||
cvsStyleHeight: '0px',
|
||||
styleDisplay: 'none',
|
||||
styleTop: '-10000px',
|
||||
prvTop: '-10000px',
|
||||
imgStyle: {},
|
||||
selStyle: {},
|
||||
showOper: true,
|
||||
imgSrc: {
|
||||
imgSrc: ''
|
||||
},
|
||||
qlty: 0.9,
|
||||
postWidthFirst: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
avatarSrc() {
|
||||
this.imgSrc.imgSrc = this.avatarSrc;
|
||||
}
|
||||
},
|
||||
props: {
|
||||
avatarSrc: '',
|
||||
avatarStyle: '',
|
||||
selWidth: '',
|
||||
selHeight: '',
|
||||
expWidth: '',
|
||||
expHeight: '',
|
||||
minScale: '',
|
||||
maxScale: '',
|
||||
canScale: '',
|
||||
noTab: '',
|
||||
quality: '',
|
||||
index: ''
|
||||
},
|
||||
created() {
|
||||
const canvas = document.getElementById('avatar-canvas');
|
||||
const operCanvas = document.getElementById('oper-canvas');
|
||||
this.ctxCanvas = canvas.getContext('2d');
|
||||
this.ctxCanvasOper = operCanvas.getContext('2d');
|
||||
|
||||
this.qlty = parseInt(this.quality) || 0.9;
|
||||
this.imgSrc.imgSrc = this.avatarSrc;
|
||||
this.letScale = this.canScale === 'false' ? 0 : 1;
|
||||
this.indx = this.index || undefined;
|
||||
this.mnScale = this.minScale || 0.3;
|
||||
this.mxScale = this.maxScale || 4;
|
||||
this.noBar = this.noTab === 'true' ? 1 : 0;
|
||||
if (this.noBar) {
|
||||
this.moreHeight = 0;
|
||||
this.fWindowResize();
|
||||
} else {
|
||||
this.moreHeight = 50;
|
||||
this.fWindowResize();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fWindowResize() {
|
||||
const sysInfo = {
|
||||
platform: navigator.platform,
|
||||
pixelRatio: window.devicePixelRatio,
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight,
|
||||
windowTop: window.scrollY,
|
||||
windowBottom: 0,
|
||||
statusBarHeight: 0,
|
||||
screenHeight: screen.height
|
||||
};
|
||||
|
||||
this.platform = sysInfo.platform;
|
||||
this.pixelRatio = sysInfo.pixelRatio;
|
||||
this.windowWidth = sysInfo.windowWidth;
|
||||
this.drawTop = sysInfo.windowTop;
|
||||
this.windowHeight = sysInfo.windowHeight + sysInfo.windowBottom;
|
||||
this.cvsStyleHeight = this.windowHeight - tabHeight + 'px';
|
||||
|
||||
this.pxRatio = this.windowWidth / 750;
|
||||
|
||||
let style = this.avatarStyle;
|
||||
console.log(style)
|
||||
this.imgStyle = style;
|
||||
this.expWidth && (this.exportWidth = this.expWidth.indexOf('rpx') >= 0 ? parseInt(this.expWidth) * this.pxRatio :
|
||||
parseInt(this.expWidth));
|
||||
this.expHeight && (this.exportHeight = this.expHeight.indexOf('rpx') >= 0 ? parseInt(this.expHeight) * this.pxRatio :
|
||||
parseInt(this.expHeight));
|
||||
|
||||
if (this.styleDisplay === 'flex') {
|
||||
this.fDrawInit(true);
|
||||
}
|
||||
this.fHideImg();
|
||||
},
|
||||
fSelect() {
|
||||
if (this.fSelecting) return;
|
||||
this.fSelecting = true;
|
||||
setTimeout(() => {
|
||||
this.fSelecting = false;
|
||||
}, 500);
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.accept = 'image/*';
|
||||
input.onchange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if(!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const path = e.target.result;
|
||||
this.imgPath = path;
|
||||
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
this.imgWidth = img.width;
|
||||
this.imgHeight = img.height;
|
||||
this.path = path;
|
||||
|
||||
if (!this.hasSel) {
|
||||
let style = this.selStyle || {};
|
||||
if (this.selWidth && this.selHeight) {
|
||||
let selWidth = this.selWidth.indexOf('rpx') >= 0 ? parseInt(this.selWidth) * this.pxRatio :
|
||||
parseInt(this.selWidth),
|
||||
selHeight = this.selHeight.indexOf('rpx') >= 0 ? parseInt(this.selHeight) * this.pxRatio :
|
||||
parseInt(this.selHeight);
|
||||
style.width = parseInt(selWidth);
|
||||
style.height = parseInt(selHeight);
|
||||
style.top = parseInt((this.windowHeight - style.height - tabHeight) / 2);
|
||||
style.left = parseInt((this.windowWidth - style.width) / 2);
|
||||
} else {
|
||||
alert('裁剪框的宽或高没有设置');
|
||||
return;
|
||||
}
|
||||
this.selStyle = style;
|
||||
}
|
||||
|
||||
this.fDrawInit(true);
|
||||
};
|
||||
img.src = path;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
input.click();
|
||||
},
|
||||
fUpload() {
|
||||
if (this.fUploading) return;
|
||||
this.fUploading = true;
|
||||
setTimeout(() => {
|
||||
this.fUploading = false;
|
||||
}, 1000);
|
||||
|
||||
let style = this.selStyle,
|
||||
x = parseInt(style.left),
|
||||
y = parseInt(style.top),
|
||||
width = parseInt(style.width),
|
||||
height = parseInt(style.height),
|
||||
expWidth = this.exportWidth || width,
|
||||
expHeight = this.exportHeight || height;
|
||||
|
||||
x *= this.pixelRatio;
|
||||
y *= this.pixelRatio;
|
||||
expWidth = width;
|
||||
expHeight = height;
|
||||
|
||||
this.styleDisplay = 'none';
|
||||
this.styleTop = '-10000px';
|
||||
this.hasSel = false;
|
||||
this.fHideImg();
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(this.ctxCanvas.canvas, x, y, width, height, 0, 0, expWidth, expHeight);
|
||||
|
||||
canvas.toBlob((blob) => {
|
||||
const url = URL.createObjectURL(blob);
|
||||
this.$emit("upload", {
|
||||
avatar: this.imgSrc,
|
||||
path: url,
|
||||
index: this.indx
|
||||
});
|
||||
}, 'image/png', this.qlty);
|
||||
},
|
||||
// ... 其他方法保持不变
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.my-canvas {
|
||||
display: flex;
|
||||
position: fixed !important;
|
||||
background: #000000;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.my-avatar {
|
||||
width: 100vw;
|
||||
height: 100vw;
|
||||
}
|
||||
|
||||
.oper-canvas {
|
||||
display: flex;
|
||||
position: fixed !important;
|
||||
left: 0;
|
||||
z-index: 101;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.oper-wrapper {
|
||||
height: 71px;
|
||||
position: fixed !important;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 200;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.btn-wrapper {
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
justify-content: space-around;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.btn-wrapper view {
|
||||
width: 160rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
z-index: 300;
|
||||
}
|
||||
|
||||
.hover {
|
||||
color: #f1f1f1;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,707 @@
|
||||
<template>
|
||||
<div class="photo-upload-page">
|
||||
<div class="badge-size">
|
||||
<div class="size-title">剩余兑换数量</div>
|
||||
<div class="size-options">
|
||||
<div class="size-item">
|
||||
<div class="size-text">4cm</div>
|
||||
<div class="size-count">(剩余兑换:1)</div>
|
||||
</div>
|
||||
<div class="size-item">
|
||||
<div class="size-text">5cm</div>
|
||||
<div class="size-count">(剩余兑换:2)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="badge-info">
|
||||
<div class="badge-item" @click="goToRecord">
|
||||
<div class="badge-title">设计图集</div>
|
||||
<div class="badge-count">8张</div>
|
||||
</div>
|
||||
<div class="badge-item" @click="goToMyOrder">
|
||||
<div class="badge-title">我的订单</div>
|
||||
<div class="badge-count">3笔</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 8px;background: #F2F2F2;"></div>
|
||||
<div class="step-container">
|
||||
<div class="step-item active">
|
||||
<div class="step-num">1</div>
|
||||
<div class="step-content">
|
||||
<div class="step-title">上传正面照片</div>
|
||||
<div class="step-desc">1张五官清晰的正面照片</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-item">
|
||||
<div class="step-num">2</div>
|
||||
<div class="step-content">
|
||||
<div class="step-title">确认下单</div>
|
||||
<div class="step-desc">选择一个你喜欢的设计</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div 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">图片上传指南</span>
|
||||
</div>
|
||||
<div class="photo-upload-area" @click="onUploadClick">
|
||||
<!-- <cropper selWidth="660rpx" selHeight="660rpx" @upload="myUpload" :avatarSrc="imgurl" avatarStyle="width:100vw;height:100vw;">
|
||||
<img v-if="imgurl" :src="imgurl" class="photo-upload-image" alt="上传的照片" />
|
||||
<div v-else class="photo-upload-placeholder">
|
||||
<span class="photo-upload-plus">+</span>
|
||||
<span class="photo-upload-text">点击上传照片</span>
|
||||
</div>
|
||||
</cropper> -->
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
style="display: none"
|
||||
@change="onFileChange"
|
||||
/>
|
||||
<div class="photo-upload-plus">+</div>
|
||||
<div class="photo-upload-text">点击上传照片</div>
|
||||
<div class="photo-upload-tip">*上传照片时建议勾选[原图]</div>
|
||||
</div>
|
||||
<div class="photo-upload-footer">
|
||||
请确定您对上传的照片拥有合法使用权利或已取得他人合法授权,且同意本平台分析图片信息以提供生成服务
|
||||
</div>
|
||||
</div>
|
||||
<div class="style-section">
|
||||
<div class="style-title">风格样式</div>
|
||||
<div class="style-list">
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="随机风格盲盒" />
|
||||
<div class="style-label">随机风格盲盒</div>
|
||||
<span class="style-selected"></span>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版国风动漫" />
|
||||
<div class="style-label">Q版国风动漫</div>
|
||||
<span class="style-selected"></span>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版卡通" />
|
||||
<div class="style-label">Q版卡通</div>
|
||||
<span class="style-selected"></span>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="芭比风" />
|
||||
<div class="style-label">芭比风</div>
|
||||
<span class="style-selected"></span>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="随机风格盲盒" />
|
||||
<div class="style-label">随机风格盲盒</div>
|
||||
<span class="style-selected"></span>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版国风动漫" />
|
||||
<div class="style-label">Q版国风动漫</div>
|
||||
<span class="style-selected"></span>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版卡通" />
|
||||
<div class="style-label">Q版卡通</div>
|
||||
<span class="style-selected"></span>
|
||||
</div>
|
||||
<div class="style-item">
|
||||
<img class="style-img" src="@/assets/badge/suiji.png" alt="芭比风" />
|
||||
<div class="style-label">芭比风</div>
|
||||
<span class="style-selected"></span>
|
||||
</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 active"
|
||||
type="button"
|
||||
>
|
||||
照片原图背景
|
||||
</button>
|
||||
<button
|
||||
class="bg-style-tab"
|
||||
type="button"
|
||||
disabled
|
||||
>
|
||||
补充背景照片
|
||||
</button>
|
||||
</div>
|
||||
<div class="bg-style-tip">
|
||||
选择该选项设计的徽章会根据上传的肖像照片背景进行生成效果
|
||||
</div>
|
||||
<div class="bg-style-tip">
|
||||
选择该选项需要额外上传一张照片作为背景
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-photo-upload-section">
|
||||
<div class="bg-photo-upload-header">
|
||||
<span>补充背景照片</span>
|
||||
</div>
|
||||
<div class="bg-photo-upload-area">
|
||||
<label class="bg-photo-upload-label">
|
||||
<input type="file" accept="image/*" style="display:none" />
|
||||
<div class="bg-photo-upload-box">
|
||||
<div class="bg-photo-upload-plus">+</div>
|
||||
<div class="bg-photo-upload-text">上传照片</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 90px;"></div>
|
||||
<div class="design-action-bar">
|
||||
<div class="design-left">
|
||||
<img class="design-leaf-icon" width="18" height="18" src="@/assets/badge/leaf.png" alt="">
|
||||
<span class="design-remaining">剩余12次</span>
|
||||
</div>
|
||||
<button class="design-btn" @click="goToPreview">
|
||||
<span>开始设计</span>
|
||||
<img class="design-arrow" src="@/assets/badge/arrow.png" alt="">
|
||||
</button>
|
||||
</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="@/assets/badge/suiji.png" 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="@/assets/badge/suiji.png" 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="@/assets/badge/suiji.png" 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="@/assets/badge/suiji.png" 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="@/assets/badge/suiji.png" 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>
|
||||
<div style="padding: 0 16px 24px 16px;">
|
||||
<div style="text-align: center;">
|
||||
<img src="@/assets/badge/suiji.png" alt="照片上传指南" style="width: 220px; border-radius: 16px; margin-bottom: 16px;" />
|
||||
</div>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 8px 12px; justify-content: center; margin-bottom: 16px;">
|
||||
<span style="background: #e6f7e6; color: #22c55e; border-radius: 8px; padding: 2px 10px; font-size: 13px;">光线均匀</span>
|
||||
<span style="background: #e6f7e6; color: #22c55e; border-radius: 8px; padding: 2px 10px; font-size: 13px;">照片清晰</span>
|
||||
<span style="background: #e6f7e6; color: #22c55e; border-radius: 8px; padding: 2px 10px; font-size: 13px;">主体明确</span>
|
||||
<span style="background: #e6f7e6; color: #22c55e; border-radius: 8px; padding: 2px 10px; font-size: 13px;">面部特征明显</span>
|
||||
<span style="background: #e6f7e6; color: #22c55e; border-radius: 8px; padding: 2px 10px; font-size: 13px;">预留充足留白</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 16px;">
|
||||
<div style="flex: 1; text-align: center;">
|
||||
<img src="@/assets/badge/suiji.png" alt="多主体" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" />
|
||||
<div style="font-size: 13px; color: #888; margin-top: 4px;">多主体</div>
|
||||
</div>
|
||||
<div style="flex: 1; text-align: center;">
|
||||
<img src="@/assets/badge/suiji.png" alt="光线昏暗" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" />
|
||||
<div style="font-size: 13px; color: #888; margin-top: 4px;">光线昏暗</div>
|
||||
</div>
|
||||
<div style="flex: 1; text-align: center;">
|
||||
<img src="@/assets/badge/suiji.png" alt="后侧面及背影" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" />
|
||||
<div style="font-size: 13px; color: #888; margin-top: 4px;">后侧面及背影</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 24px;">
|
||||
<div style="flex: 1; text-align: center;">
|
||||
<img src="@/assets/badge/suiji.png" alt="照片模糊" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" />
|
||||
<div style="font-size: 13px; color: #888; margin-top: 4px;">照片模糊</div>
|
||||
</div>
|
||||
<div style="flex: 1; text-align: center;">
|
||||
<img src="@/assets/badge/suiji.png" alt="照片留白过少" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" />
|
||||
<div style="font-size: 13px; color: #888; margin-top: 4px;">照片留白过少</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 24px; 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="imgShow = false">
|
||||
我已了解
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import cropper from "./cropper.vue";
|
||||
const show = ref(false);
|
||||
const imgShow = ref(false);
|
||||
const router = useRouter();
|
||||
const imgurl = ref(''); //头像地址
|
||||
const fileInput = ref<HTMLInputElement | null>(null);
|
||||
function onUploadClick() {
|
||||
if (fileInput.value) {
|
||||
fileInput.value.click();
|
||||
}
|
||||
}
|
||||
function myUpload(rsp) {
|
||||
const self = this;
|
||||
self.imgurl = rsp.path; //更新头像方式一
|
||||
}
|
||||
function goToRecord() {
|
||||
router.push('/badge/record');
|
||||
}
|
||||
function goToMyOrder() {
|
||||
router.push('/badge/myOrder');
|
||||
}
|
||||
function goToPreview() {
|
||||
router.push('/badge/preview');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.photo-upload-page {
|
||||
height: auto;
|
||||
overflow-y: scroll!important;
|
||||
}
|
||||
.badge-size {
|
||||
padding: 16px;
|
||||
.size-title {
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
}
|
||||
.size-options {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 8px;
|
||||
.size-item:last-child {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.size-item {
|
||||
flex: 1;
|
||||
.size-text {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
padding: 4px 10px;
|
||||
background: #F0F2F5;
|
||||
border-radius: 4px;
|
||||
margin-right: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
.size-count {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.badge-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 16px 16px 16px;
|
||||
.badge-item:first-child {
|
||||
background-image: url('@/assets/badge/sheji.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.badge-item:last-child {
|
||||
background-image: url('@/assets/badge/order.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.badge-item {
|
||||
padding: 18px 12px;
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
height: 88px;
|
||||
.badge-title {
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.badge-count {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.step-container {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 16px 0 16px 16px;
|
||||
}
|
||||
.step-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.step-item.active {
|
||||
flex: 2;
|
||||
margin-left: 50px;
|
||||
}
|
||||
.step-num {
|
||||
font-size: 48px;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
margin-right: 8px;
|
||||
text-shadow: 0 2px 8px #e6f7e6;
|
||||
color: #CCCCCC;
|
||||
}
|
||||
.step-item.active .step-num {
|
||||
color: #fff;
|
||||
text-shadow:
|
||||
1px 1px 0 #000,
|
||||
-1px -1px 0 #000,
|
||||
-1px 1px 0 #000,
|
||||
1px -1px 0 #000,
|
||||
0 1px 0 #000,
|
||||
1px 0 0 #000,
|
||||
0 -1px 0 #000,
|
||||
-1px 0 0 #000;
|
||||
}
|
||||
.step-item.active .step-num::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 0;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background-color: #50cf54;
|
||||
opacity: 0.5;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.step-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.step-title {
|
||||
font-size: 16px;
|
||||
color: #808080;;
|
||||
}
|
||||
.step-desc {
|
||||
font-size: 12px;
|
||||
color: #808080;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.photo-upload-box {
|
||||
margin: 16px auto 0 auto;
|
||||
width: 80vw;
|
||||
height: 80vw;
|
||||
border-radius: 12px;
|
||||
background: #F0F2F5;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.photo-upload-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px 0 12px;
|
||||
font-size: 14px;
|
||||
color: #888;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.photo-upload-guide-icon {
|
||||
font-size: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
.photo-upload-guide-text {
|
||||
font-size: 13px;
|
||||
}
|
||||
.photo-upload-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
}
|
||||
.photo-upload-plus {
|
||||
font-size: 48px;
|
||||
color: #c2c2c2;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.photo-upload-text {
|
||||
font-size: 16px;
|
||||
color: #888;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.photo-upload-tip {
|
||||
font-size: 12px;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
.photo-upload-footer {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #b0b0b0;
|
||||
padding: 0 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.style-section {
|
||||
margin: 16px 0 0 0;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.style-title {
|
||||
font-size: 16px;
|
||||
color: #222;
|
||||
font-weight: bold;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.style-list {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
overflow-x: scroll;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
}
|
||||
.style-list::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
}
|
||||
.style-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
width: 25vw;
|
||||
}
|
||||
.style-img {
|
||||
width: 23vw;
|
||||
height: 23vw;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
background: #f5f5f5;
|
||||
border: 2px solid transparent;
|
||||
transition: border 0.2s;
|
||||
}
|
||||
.style-item .style-selected {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
bottom: 30px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: #50cf54;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fff;
|
||||
display: inline-block;
|
||||
box-shadow: 0 2px 8px rgba(80, 207, 84, 0.2);
|
||||
}
|
||||
.style-item .style-selected::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 6px;
|
||||
border-left: 2px solid #fff;
|
||||
border-bottom: 2px solid #fff;
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 5px;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.style-item .style-label {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.style-item:hover .style-img,
|
||||
.style-item .style-selected ~ .style-img {
|
||||
border: 2px solid #50cf54;
|
||||
}
|
||||
|
||||
.bg-style-section {
|
||||
margin: 24px 0 0 0;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.bg-style-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.bg-style-title {
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.bg-style-desc {
|
||||
font-size: 13px;
|
||||
color: #808080;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bg-style-desc.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
.bg-style-tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.bg-style-tab {
|
||||
padding: 6px 18px;
|
||||
border: none;
|
||||
border-radius: 18px;
|
||||
background: #f0f2f5;
|
||||
color: #333;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
}
|
||||
.bg-style-tab.active {
|
||||
background: #e6f7e6;
|
||||
color: #22c55e;
|
||||
font-weight: bold;
|
||||
}
|
||||
.bg-style-tab:disabled {
|
||||
background: #f0f2f5;
|
||||
color: #b0b0b0;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bg-style-tip {
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.bg-photo-upload-section {
|
||||
margin: 24px 0 0 0;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.bg-photo-upload-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.bg-photo-upload-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.bg-photo-upload-label {
|
||||
display: inline-block;
|
||||
}
|
||||
.bg-photo-upload-box {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border: 2px dashed #b0b0b0;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
background: #fafafa;
|
||||
transition: border 0.2s;
|
||||
}
|
||||
.bg-photo-upload-plus {
|
||||
font-size: 32px;
|
||||
color: #b0b0b0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.bg-photo-upload-text {
|
||||
font-size: 16px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.design-action-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
.design-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.design-leaf-icon {
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.design-remaining {
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.design-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
width: 50vw;
|
||||
height: 56px;
|
||||
border-radius: 28px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
background: linear-gradient(90deg, #D1ED8E 0%, #55E668 100%);
|
||||
color: #222;
|
||||
box-shadow: 0 2px 8px rgba(80, 207, 84, 0.10);
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.design-btn .design-arrow {
|
||||
margin-left: 20px;
|
||||
vertical-align: middle;
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
transition: transform 0.2s;
|
||||
width: 18px;
|
||||
height: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="my-order">
|
||||
<div class="header" @click="goBack">
|
||||
<span class="back-icon"><van-icon name="arrow-left" size="16px" /> 返回</span>
|
||||
</div>
|
||||
<div class="order-list">
|
||||
<div class="order-item" @click="OrderDetail">
|
||||
<img class="order-img" src="@/assets/badge/suiji.png" alt="order1" />
|
||||
<span class="order-status status-processing">生产中</span>
|
||||
</div>
|
||||
<div class="order-item">
|
||||
<img class="order-img" src="@/assets/badge/suiji.png" alt="order2" />
|
||||
<span class="order-status status-finished">已完成</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter();
|
||||
function goBack() {
|
||||
router.push('/badge');
|
||||
}
|
||||
function OrderDetail() {
|
||||
router.push('/badge/orderDetail')
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
padding: 16px 16px 0 16px;
|
||||
}
|
||||
.back-icon {
|
||||
margin-right: 8px;
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.order-list {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: space-between;
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
position: relative;
|
||||
width: 43vw;
|
||||
height: 43vw;
|
||||
/* border-radius: 50%; */
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.order-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
padding: 2px 14px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
background: #bdbdbd;
|
||||
opacity: 0.9;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.status-processing {
|
||||
background: #bdbdbd;
|
||||
}
|
||||
|
||||
.status-finished {
|
||||
background: #8bc34a;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div class="my-order">
|
||||
<div class="header" @click="goBack">
|
||||
<span class="back-icon"><van-icon name="arrow-left" size="16px" /> 返回</span>
|
||||
</div>
|
||||
<div class="order-status">
|
||||
<div class="avatar-wrapper">
|
||||
<img class="avatar-img" src="@/assets/badge/suiji.png" alt="生产中" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="status-info">
|
||||
<div class="status-title">生产中</div>
|
||||
<div class="status-desc">
|
||||
下单后预计需要7天完成生产发货。如对产品有疑问,可以联系客服咨询。
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 0 16px;">
|
||||
<van-divider />
|
||||
</div>
|
||||
<div class="product-info">
|
||||
<div class="product-title">产品信息</div>
|
||||
<div class="product-details">
|
||||
<div class="product-row">
|
||||
<span class="product-label">产品名称</span>
|
||||
<span class="product-value">立体徽章</span>
|
||||
</div>
|
||||
<div class="product-row">
|
||||
<span class="product-label">尺寸</span>
|
||||
<span class="product-value">5cm</span>
|
||||
</div>
|
||||
<div class="product-row">
|
||||
<span class="product-label">购买数量</span>
|
||||
<span class="product-value">1</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 0 16px;">
|
||||
<van-divider />
|
||||
</div>
|
||||
<div class="address-info" style="padding: 0 16px;">
|
||||
<div class="address-title">收货信息</div>
|
||||
<div class="address-row">
|
||||
<img class="address-img" src="@/assets/badge/location.png" alt="" >
|
||||
<span class="address-name">张先生</span>
|
||||
<span class="address-phone">136****0731</span>
|
||||
</div>
|
||||
<div class="address-detail">
|
||||
详细地址详细地址详细地址详细地址详细地址详细地址
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 0 16px;">
|
||||
<van-divider />
|
||||
</div>
|
||||
<div class="product-info">
|
||||
<div class="product-title">订单信息</div>
|
||||
<div class="product-details">
|
||||
<div class="product-row">
|
||||
<span class="product-label">购买订单id</span>
|
||||
<span class="product-value">O98462</span>
|
||||
</div>
|
||||
<div class="product-row">
|
||||
<span class="product-label">购买时间</span>
|
||||
<span class="product-value">2025-03-24 16:12:46</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 30px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter();
|
||||
function goBack() {
|
||||
router.push('/badge/myOrder');
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
padding: 16px 16px 0 16px;
|
||||
}
|
||||
.back-icon {
|
||||
margin-right: 8px;
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.order-status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 32px;
|
||||
}
|
||||
.avatar-wrapper {
|
||||
width: 85vw;
|
||||
height: 85vw;
|
||||
border-radius: 50%;
|
||||
box-shadow: 2px 2px 4px #00000042,inset -2px -2px 4px #00000048,inset 2px 2px 4px #ffffffb4;
|
||||
margin-bottom: 24px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.status-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.status-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.status-desc {
|
||||
font-size: 10px;
|
||||
color: #888;
|
||||
}
|
||||
.product-info {
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: #111;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.product-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.product-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.product-label {
|
||||
color: #bdbdbd;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.product-value {
|
||||
color: #222;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.address-info {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.address-title {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: #111;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.address-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #222;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.address-img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.address-name {
|
||||
margin-right: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.address-phone {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.address-detail {
|
||||
font-size: 12px;
|
||||
color: #bdbdbd;
|
||||
margin-left: 24px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,381 @@
|
||||
<template>
|
||||
<div class="preview-container">
|
||||
<view class="backstyle_1"></view>
|
||||
<view class="backstyle_2"></view>
|
||||
<div class="header" @click="goBack">
|
||||
<span class="back-icon"><van-icon name="arrow-left" size="16px" /> 返回</span>
|
||||
</div>
|
||||
<div class="step-container">
|
||||
<div class="step-item">
|
||||
<div class="step-content">
|
||||
<div class="step-title">正面照片</div>
|
||||
<div class="step-desc">清晰的正面照片</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-item active">
|
||||
<div class="step-num">2</div>
|
||||
<div class="step-content">
|
||||
<div class="step-title">确认下单</div>
|
||||
<div class="step-desc">选择一个你喜欢的设计</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-section">
|
||||
<div class="progress-bar-bg">
|
||||
<div class="progress-bar-fg" :style="{ width: '12%' }"></div>
|
||||
</div>
|
||||
<div class="progress-text">照片数据分析中 12%</div>
|
||||
<div class="progress-desc">总计大约需要60秒,请耐心等待...</div>
|
||||
</div>
|
||||
<div class="info-section">
|
||||
<div class="info-item">
|
||||
<div class="info-title">芯比风格</div>
|
||||
<div class="info-content">风格</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-title">3D全彩打印</div>
|
||||
<div class="info-content">工艺</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-title">环保树脂</div>
|
||||
<div class="info-content">材料</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-desc">
|
||||
下单后如对排版要求有变更生产发货。<br>
|
||||
实物3D打印色彩与图片有自然色差,如对产品有疑问,可以联系客服咨询。
|
||||
</div>
|
||||
<div style="padding: 0 16px;">
|
||||
<van-divider />
|
||||
</div>
|
||||
<div class="order-section">
|
||||
<div class="order-title">订购数量</div>
|
||||
<div class="order-item">
|
||||
<span class="order-size">4cm</span>
|
||||
<span class="order-free">(剩余兑换:1)</span>
|
||||
<div class="order-ctrl">
|
||||
<button class="order-btn" disabled>-</button>
|
||||
<span class="order-count">1</span>
|
||||
<button class="order-btn">+</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-item">
|
||||
<span class="order-size">5cm</span>
|
||||
<span class="order-free">(剩余兑换:2)</span>
|
||||
<div class="order-ctrl">
|
||||
<button class="order-btn" disabled>-</button>
|
||||
<span class="order-count">1</span>
|
||||
<button class="order-btn">+</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="confirm-box">
|
||||
<div class="action-section">
|
||||
<button class="action-btn"><img class="action-img" src="@/assets/badge/reload.png" alt=""> 再次生成</button>
|
||||
<button class="action-btn"><img class="action-img" src="@/assets/badge/duibi.png" alt=""> 前后对比</button>
|
||||
<button class="action-btn"><img class="action-img" src="@/assets/badge/down.png" alt=""> 保存图片</button>
|
||||
</div>
|
||||
<div class="btn-box">
|
||||
<button class="confirm-btn">确认选择</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter();
|
||||
function goBack() {
|
||||
router.push('/badge');
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.preview-container {
|
||||
min-height: 100vh;
|
||||
font-family: 'PingFang SC', Arial, sans-serif;
|
||||
color: #222;
|
||||
}
|
||||
.backstyle_1 {
|
||||
position: fixed;
|
||||
left: -110px;
|
||||
top: -40px;
|
||||
width: 328px;
|
||||
height: 216px;
|
||||
opacity: 0.2;
|
||||
transform: rotate(-13.72deg);
|
||||
border-radius: 50%;
|
||||
/* background: radial-gradient(48.48% 50% at 50% 50%, #EBD4A0 0%, #ebd5a000 81.94%); */
|
||||
background-image: radial-gradient( rgba(250, 182, 55, 0.726), #ebd5a09c, #d4cab100);
|
||||
z-index: -10;
|
||||
}
|
||||
.backstyle_2 {
|
||||
position: fixed;
|
||||
left: 97px;
|
||||
top: -95px;
|
||||
width: 370px;
|
||||
height: 374px;
|
||||
opacity: 0.1;
|
||||
border-radius: 50%;
|
||||
/* background: radial-gradient(59.73% 50% at 50% 50%, #90F272 0%, #90f27200 84.03%); */
|
||||
background-image: radial-gradient( rgb(69, 255, 63), #90f2729a, #90f27200);
|
||||
z-index: -10;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
padding: 16px 16px 0 16px;
|
||||
}
|
||||
.back-icon {
|
||||
margin-right: 8px;
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.step-container {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 16px 16px 16px 0;
|
||||
}
|
||||
.step-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.step-item.active {
|
||||
flex: 2.5;
|
||||
}
|
||||
.step-num {
|
||||
font-size: 48px;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
margin-right: 8px;
|
||||
text-shadow: 0 2px 8px #e6f7e6;
|
||||
color: #CCCCCC;
|
||||
}
|
||||
.step-item.active .step-num {
|
||||
color: #fff;
|
||||
text-shadow:
|
||||
1px 1px 0 #000,
|
||||
-1px -1px 0 #000,
|
||||
-1px 1px 0 #000,
|
||||
1px -1px 0 #000,
|
||||
0 1px 0 #000,
|
||||
1px 0 0 #000,
|
||||
0 -1px 0 #000,
|
||||
-1px 0 0 #000;
|
||||
}
|
||||
.step-item.active .step-num::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 0;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background-color: #50cf54;
|
||||
opacity: 0.5;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.step-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.step-item.active .step-title {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
.step-item.active .step-desc {
|
||||
color: #808080;
|
||||
font-size: 13px;
|
||||
}
|
||||
.step-title {
|
||||
font-size: 15px;
|
||||
color: #808080;;
|
||||
}
|
||||
.step-desc {
|
||||
font-size: 12px;
|
||||
color: #808080;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.progress-section {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
width: 80vw;
|
||||
height: 80vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.progress-bar-bg {
|
||||
width: 70%;
|
||||
height: 10px;
|
||||
background: #eee;
|
||||
border-radius: 5px;
|
||||
margin: 0 auto 8px auto;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress-bar-fg {
|
||||
height: 100%;
|
||||
background: #6fdc8c;
|
||||
border-radius: 5px;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
.progress-text {
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.progress-desc {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.info-section {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding: 16px;
|
||||
}
|
||||
.info-item {
|
||||
flex: 1;
|
||||
}
|
||||
.info-title {
|
||||
font-size: 13px;
|
||||
color: #222;
|
||||
font-weight: 600;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.info-content {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.info-desc {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-bottom: 18px;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.order-section {
|
||||
border-radius: 10px;
|
||||
padding: 0 16px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.order-title {
|
||||
font-size: 14px;
|
||||
color: #222;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.order-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.order-size {
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.order-free {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.order-ctrl {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
.order-btn {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border: none;
|
||||
background: #e8e8e8;
|
||||
color: #bbb;
|
||||
font-size: 18px;
|
||||
border-radius: 4px;
|
||||
margin: 0 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.order-btn:disabled {
|
||||
background: #f2f2f2;
|
||||
color: #ddd;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.order-count {
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
width: 22px;
|
||||
text-align: center;
|
||||
}
|
||||
.confirm-box {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
z-index: 10;
|
||||
padding: 0 16px 16px 16px;
|
||||
border-top: 1px solid #e6e6e6;
|
||||
}
|
||||
.action-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
margin: 0 4px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
color: #222;
|
||||
font-size: 13px;
|
||||
padding: 8px 0;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
}
|
||||
.action-img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.action-btn:hover {
|
||||
background: #e6f7ea;
|
||||
}
|
||||
.btn-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.confirm-btn {
|
||||
width: 80vw;
|
||||
background: linear-gradient(90deg, #D1ED8E 0%, #55E668 100%);
|
||||
color: #000;
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 24px;
|
||||
padding: 12px 0;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(111,220,140,0.08);
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.confirm-btn:active {
|
||||
background: linear-gradient(90deg, #5ccf7a 0%, #8fdca0 100%);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="header" @click="goBack">
|
||||
<span class="back-icon"><van-icon name="arrow-left" size="16px" /> 返回</span>
|
||||
</div>
|
||||
<div class="record-container">
|
||||
<div class="record-note">
|
||||
注:可点击效果图进行下单打印
|
||||
</div>
|
||||
<div class="record-images">
|
||||
<div
|
||||
v-for="(item, idx) in images"
|
||||
:key="idx"
|
||||
@click="onImageClick(item)"
|
||||
class="record-image-item"
|
||||
>
|
||||
<img :src="item" class="record-image" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter();
|
||||
function goBack() {
|
||||
router.push('/badge');
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
padding: 16px 16px 0 16px;
|
||||
}
|
||||
.back-icon {
|
||||
margin-right: 8px;
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.record-container {
|
||||
max-width: 500px;
|
||||
margin: 24px auto;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.record-note {
|
||||
color: #888;
|
||||
font-size: 14px;
|
||||
margin-bottom: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.record-images {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.record-image-item {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.record-image-item:hover {
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.14);
|
||||
}
|
||||
|
||||
.record-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="page">
|
||||
<div class="section_2">
|
||||
<div class="group_26">
|
||||
<div class="image-text_35" v-if="symbol == 2">
|
||||
<image src="/static/images/order/shunfeng.png" class="icon_1"></image>
|
||||
<text lines="1" class="text-group_1">顺丰快递</text>
|
||||
</div>
|
||||
<div class="image-text_35" v-else>
|
||||
<image src="/static/images/order/jingdong.png" class="icon_1"></image>
|
||||
<text lines="1" class="text-group_1">京东快递</text>
|
||||
</div>
|
||||
<text lines="1" class="text_1">orderInfo.delivery_no</text>
|
||||
<div @click="copyOrderId" data-text="{{orderInfo.delivery_no}}" class="button_1_copy">复制</div>
|
||||
<!-- <div class="icon_5">
|
||||
<image src="/static/images/order/tel.png" class="icon_6"></image>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="list_7" v-if="routerInfo.length > 0">
|
||||
|
||||
<!-- acceptAddress: "深圳市"
|
||||
acceptTime: "2023-04-03 19:39:40"
|
||||
opCode: "50"
|
||||
remark: "顺丰速运 已收取快件" -->
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="image-text_11-0" v-for="value, key in routerInfo" :key="value.delivery_id">
|
||||
|
||||
<div v-if="key==0">
|
||||
<image class="gou_1" src="/static/images/order/gou_1.png"></image>
|
||||
|
||||
<div class="image_4-0" style="width:0rpx;border:1px solid #55B038;height:95%"></div>
|
||||
|
||||
<div class="text-group_51-1">
|
||||
<text lines="1" class="text_23-1">{{value.remark}}</text>
|
||||
<text lines="1" decode="true" class="text_24-1">{{value.acceptTime}}</text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<image class="yuan_gou" src="/static/images/order/gray_yuan.png"></image>
|
||||
<div class="image_4-0" style="width:0rpx;border:1px solid #DCDEE0;height:95%"></div>
|
||||
|
||||
<div class="text-group_51-1">
|
||||
<text lines="1" class="text_23-1">{{value.remark}}</text>
|
||||
<text lines="1" decode="true" class="text_24-1">{{value.acceptTime}}</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="image-text_11-1" v-for="{{routerInfo}}" v-key="delivery_id" v-for-index="key" v-for-item="value">
|
||||
|
||||
<image v-if="{{key == 0}}" src="/static/images/order/gou.png" class="thumbnail_3-1" style="width: 96rpx;height: 0rpx;opacity: 1;border: 4rpx solid #55B038;"></image>
|
||||
<image src="/static/images/order/line.png" class="thumbnail_3-1"></image>
|
||||
|
||||
<div class="text-group_51-1">
|
||||
<text lines="1" class="text_23-1">{{value.remark}}</text>
|
||||
<text lines="1" decode="true" class="text_24-1">{{value.acceptTime}}</text>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,376 @@
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<Brand />
|
||||
<van-divider>——内容精选——</van-divider>
|
||||
<Article />
|
||||
<div class="empty" />
|
||||
<Tabbar></Tabbar>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { showLoadingToast, showToast, closeToast } from "vant";
|
||||
import { localStorage } from '@/utils/local-storage'
|
||||
import {imgSrc} from "@/utils/utils"
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
const showAvaModal = ref(false)
|
||||
const isPhone = ref(false)
|
||||
const userInfo = ref("")
|
||||
const mode = ref("")
|
||||
const orderList = ref([])
|
||||
const page = ref(1)
|
||||
|
||||
const active = ref('home')
|
||||
|
||||
onMounted(()=>{
|
||||
isLogin();
|
||||
showLoadingToast({
|
||||
message: '加载中...'.$t,
|
||||
forbidClick: true,
|
||||
});
|
||||
setTimeout(()=> {
|
||||
closeToast();
|
||||
loading.value = false;
|
||||
}, 1000)
|
||||
})
|
||||
// 登录判断
|
||||
const isLogin = () => {
|
||||
// let data = localStorage.get('userInfo');
|
||||
// userInfo.value = data || "";
|
||||
// isPhone.value = data.mobile && true;
|
||||
// if (data.mobile || isPhone.value) {
|
||||
// orderList.value = [];
|
||||
// page.value = 1;
|
||||
// getOrderList(data)
|
||||
// }
|
||||
}
|
||||
|
||||
//跳转外部连接
|
||||
const handleToWebSite = () => {
|
||||
// 如果未登录先跳转到登陆页
|
||||
if (!userInfo.value && !isPhone.value) { // 用户登录
|
||||
router.push({
|
||||
// 跳转到webview页面
|
||||
// url: "/pages/login/login",
|
||||
});
|
||||
return
|
||||
}
|
||||
// const url = 'https://wechat.api.suwa3d.com/applyTakephoto/page'; // 跳转的外链
|
||||
// const navtitle = '立即预约'; // 这个标题是你自己可以设置的
|
||||
router.push({
|
||||
// 跳转到webview页面
|
||||
// path: `/pages/webview/webview?url=${url}&nav=${navtitle}`,
|
||||
});
|
||||
}
|
||||
|
||||
// 复制订单ID
|
||||
const copyOrderId = (e) => {
|
||||
// wx.setClipboardData({
|
||||
// data: e.currentTarget.dataset.text.toString(),
|
||||
// success: function (res) {
|
||||
// wx.getClipboardData({ //这个api是把拿到的数据放到电脑系统中的
|
||||
// success: function (res) {
|
||||
// console.log(res.data) // data
|
||||
// wx.showToast({
|
||||
// title: '复制成功',
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
// 状态判断
|
||||
const statusJudge = (data) => {
|
||||
data.map((item) => {
|
||||
switch (item.status) {
|
||||
case 1000:
|
||||
item.statusName = "上传完成";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 2000:
|
||||
item.statusName = "待门店提交建模";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 3000:
|
||||
item.statusName = "待建模";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 4000 :
|
||||
item.statusName = "建模中";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 4100 :
|
||||
item.statusName = "建模完成";
|
||||
item.statusColor = 1;
|
||||
break;
|
||||
case 5000 :
|
||||
item.statusName = "待修模";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 6000 :
|
||||
item.statusName = "修模中";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 7000 :
|
||||
if (item.digital_type == 1) {
|
||||
item.statusName = "3D相册已创建";
|
||||
} else {
|
||||
item.statusName = "修模完成";
|
||||
}
|
||||
|
||||
item.statusColor = 1;
|
||||
break;
|
||||
case 7011 :
|
||||
item.statusName = "3D相册已创建";
|
||||
item.statusColor = 1;
|
||||
break;
|
||||
case 7020 :
|
||||
item.statusName = "待打印";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 8000 :
|
||||
item.statusName = "打印中";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 8100 :
|
||||
item.statusName = "后道工序处理";
|
||||
item.statusColor = 0;
|
||||
break;
|
||||
case 8110 :
|
||||
// item.statusName = "称净重";
|
||||
// item.statusColor = 0;
|
||||
break;
|
||||
case 9000 :
|
||||
item.statusName = "快递中";
|
||||
item.statusColor = 1;
|
||||
break;
|
||||
case 10000 :
|
||||
item.statusName = "订单已完成";
|
||||
item.statusColor = 1;
|
||||
break;
|
||||
default:
|
||||
return false
|
||||
}
|
||||
if (item.status >= 7020 && item.status < 8000) {
|
||||
item.statusName = "待打印";
|
||||
item.statusColor = 0;
|
||||
}
|
||||
if (item.status > 6000 && item.status < 7000) {
|
||||
item.statusName = "待审核";
|
||||
item.statusColor = 0;
|
||||
}
|
||||
if (item.status > 8000 && item.status < 9000) {
|
||||
item.statusName = "后道工序处理中";
|
||||
item.statusColor = 0;
|
||||
}
|
||||
if (item.status >= 9000 && item.status < 10000) {
|
||||
item.statusName = "快递中";
|
||||
item.statusColor = 1;
|
||||
}
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
// 购买手办
|
||||
// goBuy(e) {
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
// var pid = e.currentTarget.dataset.pid;
|
||||
// var cn = e.currentTarget.dataset.cn;
|
||||
// var oid = e.currentTarget.dataset.oid;
|
||||
// var cid = e.currentTarget.dataset.cid;
|
||||
// console.log(`/pages/cart/cart?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}`)
|
||||
// wx.navigateTo({
|
||||
// url: `/pages/cart/cart?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}`,
|
||||
// });
|
||||
// }
|
||||
|
||||
// 跳转到照片的详情
|
||||
const goPhoto = (e) => {
|
||||
// const {id} = e.currentTarget.dataset;
|
||||
router.push({
|
||||
// path: `/pages/message/detail/detail?id=${id}&hidden=true`,
|
||||
});
|
||||
}
|
||||
|
||||
// 跳转至songDetail页面
|
||||
const toOrderDetail = (e) => {
|
||||
// var orderInfo = e.currentTarget.dataset.row;
|
||||
// // 路由跳转传参: query参数
|
||||
// router.push({
|
||||
// // 不能直接将song对象作为参数传递,长度过长,会被自动截取掉
|
||||
// // url: '/pages/songDetail/songDetail?songPackage=' + JSON.stringify(songPackage)
|
||||
// path: '/pages/orderdetail/orderdetail',
|
||||
// success: function (res) {
|
||||
// res.eventChannel.emit("orderInfo", orderInfo)
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
// 订单列表遍历
|
||||
const getOrderList = (userInfo) => {
|
||||
// showLoadingToast({
|
||||
// message: '加载中...',
|
||||
// forbidClick: true,
|
||||
// });
|
||||
if (userInfo) {
|
||||
var obj = {}
|
||||
// wx.getSystemInfo({
|
||||
// success(el) {
|
||||
// obj = {
|
||||
// version: el.version, // 微信版本
|
||||
// brand: el.brand, // 设备品牌
|
||||
// model: el.model, // 设备型号
|
||||
// platform: el.platform, // 客户端平台
|
||||
// system: el.system, // 操作系统及版本
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
let data = {
|
||||
open_id: userInfo.openid,
|
||||
union_id: userInfo.unionid,
|
||||
page: page.value
|
||||
}
|
||||
data = Object.assign(data, obj)
|
||||
// app.api.getOrderList(data).then(res => {
|
||||
// if (res.code == 1000) {
|
||||
// let data = res.data;
|
||||
// let {orderList} = that.data;
|
||||
// data = orderList.length >= 6 ? [...orderList, ...data] : data
|
||||
// data = that.statusJudge(data);
|
||||
// that.setData({
|
||||
// orderList: data,
|
||||
// page: that.data.page + 1
|
||||
// })
|
||||
// wx.hideLoading();
|
||||
// wx.stopPullDownRefresh();
|
||||
// }
|
||||
// }).catch(err => {
|
||||
// console.log(err);
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
// const onReachBottom = () {
|
||||
// // 懒加载订单列表
|
||||
// if (this.data.orderList.length >= 6) {
|
||||
// let userInfo = this.data.userInfo || wx.getStorageSync('userInfo');
|
||||
// this.getOrderList(userInfo)
|
||||
// }
|
||||
// }
|
||||
|
||||
// 文章跳转
|
||||
const articleJump = (e) => {
|
||||
// const {id, title} = e.currentTarget.dataset
|
||||
// let param = encodeURIComponent(id);
|
||||
// router.push({
|
||||
// // 跳转到webview页面
|
||||
// path: `/pages/webview/webview?url=${param}&nav=${title}`,
|
||||
// });
|
||||
}
|
||||
|
||||
// 跳转至songDetail页面
|
||||
const toAlbum = (e) => {
|
||||
//获取用户的信息
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
// var pid = e.currentTarget.dataset.pid;
|
||||
// var cn = e.currentTarget.dataset.cn;
|
||||
// var oid = e.currentTarget.dataset.oid;
|
||||
// var cid = e.currentTarget.dataset.cid;
|
||||
// var status = e.currentTarget.dataset.status;
|
||||
// var remainingExperienceStatus = e.currentTarget.dataset.remain_status;
|
||||
// var expireTime = e.currentTarget.dataset.expire_time;
|
||||
// var digitalOrderId = e.currentTarget.dataset.digital_order_id;
|
||||
// var digitalType = e.currentTarget.dataset.digital_type;
|
||||
// var createTime = e.currentTarget.dataset.create_time;
|
||||
// var titleCode = e.currentTarget.dataset.title_code;
|
||||
// console.log(e.currentTarget.dataset)
|
||||
// //判断createTime时间是否在2023-04-15 00:00:00 之后
|
||||
// wx.request({
|
||||
// url: config.url + '/miniProgram/judgeP3dLogOrderTime',
|
||||
// data: {photoTime: createTime, pid},
|
||||
// header: {'content-type': 'application/json'},
|
||||
// success: (res) => {
|
||||
// if (res.data.data.use_status != 1) {
|
||||
// wx.showToast({
|
||||
// title: '该订单不支持3D相册,需重新拍照',
|
||||
// icon: 'none',
|
||||
// duration: 2000
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// const url = `/package3D/pages/3d/3d?openid=${u.openid}`
|
||||
// + `&unionid=${u.unionid}&id=${pid}&oid=${oid}`
|
||||
// + `&cn=${cn}&cid=${cid}&expireTime=${expireTime}`
|
||||
// + `&digitalType=${digitalType}`
|
||||
// + `&status=${status}`
|
||||
// + `&titleCode=${titleCode}`
|
||||
// + `&remainingExperienceStatus=${remainingExperienceStatus}`
|
||||
|
||||
// console.log("url", url);
|
||||
|
||||
// if (digitalOrderId == 0) {
|
||||
// wx.navigateTo({
|
||||
// url: url,
|
||||
// });
|
||||
// return
|
||||
// }
|
||||
|
||||
// if (status < 4100) {
|
||||
// wx.showToast({
|
||||
// title: '3D相册制作中',
|
||||
// icon: 'none',
|
||||
// duration: 2000
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
|
||||
// //获取时间戳
|
||||
// // const timestamp = Date.parse(new Date());
|
||||
// // const url = `http://172.16.20.5:3000/?t=${Date.now()}#/model?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}&expireTime=${expireTime}&remainingExperienceStatus=${remainingExperienceStatus}`
|
||||
// // const url = `https://wechat.suwa3d.com/3d/index.html?t=${Date.now()}#/model?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}`
|
||||
// // const navtitle = '3D相册'; // 这个标题是你自己可以设置的
|
||||
// wx.navigateTo({
|
||||
// // 跳转到webview页面
|
||||
// // url: `/pages/webview/webview?nav=${navtitle}&url=${encodeURIComponent(url)}`,
|
||||
// url: url,
|
||||
// });
|
||||
// },
|
||||
// fail: (err) => {
|
||||
// console.log(err);
|
||||
// }
|
||||
// })
|
||||
|
||||
}
|
||||
|
||||
const gotoAddPrint = (e) => {
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
// var pid = e.currentTarget.dataset.pid;
|
||||
// var oid = e.currentTarget.dataset.oid;
|
||||
// var cn = e.currentTarget.dataset.cn;
|
||||
// var cn = e.currentTarget.dataset.oid;
|
||||
// var cid = e.currentTarget.dataset.cid;
|
||||
// wx.navigateTo({
|
||||
// // 跳转到webview页面
|
||||
// url: `/pages/cart/cart?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}`,
|
||||
// });
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
padding: 0px 15px 35px 15px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,29 @@
|
||||
function googleToNormalize(data: any) {
|
||||
return {
|
||||
unionid: data.id,
|
||||
social_type: 'google',
|
||||
nickname: (data.last_name + data.first_name) || '',
|
||||
email: data.email || '',
|
||||
headimgurl: data.thumbnail || '',
|
||||
}
|
||||
}
|
||||
|
||||
function twitterToNormalize(data: any) {
|
||||
return {
|
||||
unionid: data.id_str || data.id,
|
||||
social_type: 'twitter',
|
||||
nickname: data.name || '',
|
||||
email: data.email || '',
|
||||
headimgurl: data.thumbnail || '',
|
||||
}
|
||||
}
|
||||
|
||||
export function normalize(socialType: string, data: any) {
|
||||
switch (socialType) {
|
||||
case 'google':
|
||||
return googleToNormalize(data)
|
||||
case 'twitter':
|
||||
return twitterToNormalize(data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
<script setup lang="ts">
|
||||
import hello from 'hellojs'
|
||||
import type { Ref } from 'vue'
|
||||
import { normalize } from './helpers/transfer'
|
||||
// import { useUserStore } from '@/stores/user'
|
||||
import router from '@/router'
|
||||
import {useStore} from '@/stores'
|
||||
import { useTokenStore } from '@/stores/token'
|
||||
|
||||
import * as authApi from '@/api/auth'
|
||||
|
||||
interface Item {
|
||||
icon: string
|
||||
name: string
|
||||
text: string
|
||||
}
|
||||
|
||||
const logins: Ref<Item[]> = ref([
|
||||
// {
|
||||
// icon: 'microsoft',
|
||||
// name: 'windows',
|
||||
// text: 'windows',
|
||||
// },
|
||||
{
|
||||
icon: 'googleplus',
|
||||
name: 'google',
|
||||
text: 'G+',
|
||||
},
|
||||
// {
|
||||
// icon: 'facebook',
|
||||
// name: 'facebook',
|
||||
// text: 'Facebook',
|
||||
// },
|
||||
// {
|
||||
// icon: 'apple',
|
||||
// name: 'apple',
|
||||
// text: 'apple',
|
||||
// },
|
||||
{
|
||||
icon: 'twitter',
|
||||
name: 'twitter',
|
||||
text: 'twitter',
|
||||
},
|
||||
// {
|
||||
// icon: 'wechat',
|
||||
// name: 'wechat',
|
||||
// text: 'wechat',
|
||||
// },
|
||||
])
|
||||
|
||||
function onBtn(item: Item) {
|
||||
switch (item.name) {
|
||||
case 'wechat':
|
||||
window.location.href = `https://wechat.api.suwa3d.com/api/auth/page?callback${encodeURIComponent(window.location.href)}`
|
||||
return
|
||||
}
|
||||
|
||||
hello(item.name).login().then((d: any) => {
|
||||
console.log('d', d)
|
||||
// hello(item.name).api('me').then((d: any) => {
|
||||
// console.log('d', d)
|
||||
// const data: any = normalize(item.name, d)
|
||||
// // const user = useUserStore()
|
||||
// // user.login(d)
|
||||
// // useRouter().replace('/')
|
||||
// }, (e: any) => {
|
||||
// console.log('/me error', e)
|
||||
// })
|
||||
}, () => {
|
||||
// console.log('login failed')
|
||||
})
|
||||
}
|
||||
|
||||
const stores = useStore();
|
||||
|
||||
hello.on('auth.login', (r: any) => {
|
||||
hello(r.network).api('/me', 'get').then((d) => {
|
||||
const data: any = normalize(r.network, d)
|
||||
authApi.getUser(data).then((res: any) => {
|
||||
useTokenStore().login(res)
|
||||
let url = stores.redirectUrl();
|
||||
if (url) {
|
||||
stores.setRedirect('')
|
||||
router.replace(url)
|
||||
return
|
||||
}
|
||||
|
||||
router.replace('/')
|
||||
}, (e: any) => {
|
||||
console.log('auth.login /me error', e)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// TODO: 这边需要进行配置
|
||||
hello.init({
|
||||
facebook: '1875721406193406',
|
||||
windows: '000000004403AD10',
|
||||
google: '495792315385-mj44iuov1bupumvl6evmmcvag39mi38t.apps.googleusercontent.com',
|
||||
twitter: 'ICw3GtdIivmHPI5qTLD0gZDbN',
|
||||
}, {
|
||||
redirect_uri: './oauth.html',
|
||||
scope: 'email',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<van-divider>Social Login</van-divider>
|
||||
<div v-for="(item, i) in logins" :key="i" class="l-btn">
|
||||
<van-button plain icon-prefix="iconfont" :icon="item.icon" type="primary" size="large" @click="onBtn(item)">
|
||||
{{ item.text }}
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.l-btn{
|
||||
margin: .4rem;
|
||||
width: 100%;
|
||||
}
|
||||
.container{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,78 @@
|
||||
<script setup lang="ts">
|
||||
import { queryProse } from '@/api'
|
||||
|
||||
const messages = ref<string>('')
|
||||
|
||||
const pull = () => {
|
||||
queryProse().then((res) => {
|
||||
messages.value = res.prose
|
||||
})
|
||||
}
|
||||
|
||||
// reset data
|
||||
const reset = () => messages.value = ''
|
||||
|
||||
// back
|
||||
const onClickLeft = () => history.back()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-nav-bar title="💿 mock 指南" left-arrow fixed @click-left="onClickLeft" />
|
||||
|
||||
<div class="container">
|
||||
<div class="data-label">
|
||||
来自异步请求的数据
|
||||
</div>
|
||||
<div class="data-content">
|
||||
<div v-if="messages">
|
||||
{{ messages }}
|
||||
</div>
|
||||
<van-empty v-else description="暂无数据" />
|
||||
</div>
|
||||
|
||||
<van-button round block type="primary" @click="pull">
|
||||
请求
|
||||
</van-button>
|
||||
<van-button round block type="default" @click="reset">
|
||||
清空
|
||||
</van-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 74px 30px;
|
||||
|
||||
.data-label {
|
||||
color: #969799;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.data-content {
|
||||
height: 300px;
|
||||
padding: 20px;
|
||||
line-height: 30px;
|
||||
background: #fff;
|
||||
margin-top: 20px;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
.data-content {
|
||||
background: #222;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.van-button--block {
|
||||
margin-top: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="page_wrap">
|
||||
<div class="content">
|
||||
<van-cell-group inset border>
|
||||
<van-cell title="批次号" :value="id" />
|
||||
<van-cell title="机器编号" :value="machine_id" />
|
||||
<van-cell title="模型数量" :value="model_count" />
|
||||
<van-cell title="批次详情" :value="order_count" is-link :to="{ name: 'orderDetail', query: { id: id } }" />
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group style="margin-top: 10px;" inset border>
|
||||
<van-cell class="diy_cell" title="模型称重照片" label="需将模型和重量均拍入照片">
|
||||
<van-uploader style="margin-top: 10px;" v-model="fileList" :after-read="beforeUpload" />
|
||||
</van-cell>
|
||||
<van-cell class="diy_cell" title="模型总重(克)">
|
||||
<van-field placeholder="请输入" v-model="total_weight">
|
||||
<template #button>g</template>
|
||||
</van-field>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<div class="confirm-btn" @click="submitData">确认</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import dayjs from 'dayjs'
|
||||
const route = useRoute();
|
||||
const router = useRouter()
|
||||
import { showSuccessToast, showToast } from "vant";
|
||||
const id = route.query.id as string | number;
|
||||
const machine_id = route.query.machine_id as string | number;
|
||||
const model_count = route.query.model_count as string | number;
|
||||
const order_count = route.query.order_count as string | number;
|
||||
import * as api from '@/api/multiPrint'
|
||||
const fileList = ref([
|
||||
]);
|
||||
|
||||
const total_weight = ref('')
|
||||
const imgList = ref()
|
||||
|
||||
// 图片添加时间水印
|
||||
function addWatermarkToImage(file, timestamp) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function(e) {
|
||||
img.onload = function() {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const width = img.width;
|
||||
const height = img.height;
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
// 将原始图片绘制到 Canvas 上
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
|
||||
// 添加水印文本
|
||||
ctx.font = '80px Arial';
|
||||
ctx.fillStyle = '#ff0000';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'top'; // 垂直方向顶部对齐
|
||||
|
||||
// 添加水印文本
|
||||
ctx.fillText(timestamp, width / 2, 100); // 在指定位置绘制文字
|
||||
|
||||
// 获取带水印的新图片数据
|
||||
canvas.toBlob((blob) => {
|
||||
// 创建新的文件
|
||||
const newFile = new File([blob], file.name, {
|
||||
type: file.type,
|
||||
});
|
||||
resolve(newFile);
|
||||
}, file.type); // 使用原始文件类型
|
||||
};
|
||||
img.src = e.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
|
||||
const beforeUpload = async () => {
|
||||
try {
|
||||
let file = fileList.value[0].file;
|
||||
console.log("beforeUpload",fileList)
|
||||
var timestamp = "时间:" + dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
let data = {
|
||||
keyName: file.name,
|
||||
}
|
||||
let fileData = await addWatermarkToImage(file, timestamp)
|
||||
console.log("addWatermarkToImage", fileData)
|
||||
api.getPutSignURL(data).then(res => {
|
||||
imgList.value = res.signedURL
|
||||
api.uploadToOss(res.signedURL, fileData)
|
||||
}).catch(err=>{
|
||||
showToast('提交失败' + err.message)
|
||||
})
|
||||
}catch(err) {
|
||||
}
|
||||
}
|
||||
|
||||
const submitData = () => {
|
||||
console.log("submitData",imgList.value)
|
||||
if(imgList.value == '' && total_weight.value == '') {
|
||||
return
|
||||
}
|
||||
|
||||
let params = {
|
||||
id: id,
|
||||
model_weight_photo: imgList.value,
|
||||
total_weight: total_weight.value
|
||||
}
|
||||
api.add({...params}).then((res: any) => {
|
||||
showSuccessToast('提交成功, 请稍后在检查')
|
||||
router.back()
|
||||
}).catch((err: Error) => {
|
||||
showToast('提交失败' + err.message)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #F3F3F3;
|
||||
padding-top: 10px;
|
||||
.page_wrap {
|
||||
position: relative;
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
margin: 0px auto;
|
||||
.content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 10px;
|
||||
.diy_cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.confirm-btn {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
background-color: #4281E3;
|
||||
color: #FFFFFF;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.van-cell-group--inset) {
|
||||
margin: 0;
|
||||
}
|
||||
:deep(.van-cell::after){
|
||||
transform: scaleY(1.5);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,273 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="page">
|
||||
<div class="page_wrap">
|
||||
<van-search
|
||||
v-model="keyWord"
|
||||
background="#F3F3F3"
|
||||
shape="round"
|
||||
clearable
|
||||
@search="onSearch"
|
||||
@clear="getPage"
|
||||
input-align="center"
|
||||
placeholder="机器编号"
|
||||
/>
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-list
|
||||
v-model:loading="loading" v-model:error="error" :error-text="'请求失败,点击重新加载'" :finished-text="'没有更多了'"
|
||||
:finished="finished" @load="onLoad"
|
||||
>
|
||||
<div class="content">
|
||||
<div class="content_wrap">
|
||||
<div class="content_item" v-for="item, index in list" :key="index">
|
||||
<div class="left">
|
||||
<div class="content_item_title">机器编号{{item.machine_id}}
|
||||
<van-tag style="margin-left: 10px;" :type="getProgressStatusType(item.process_status)">
|
||||
{{ renderProgressStatus(item) }}
|
||||
</van-tag>
|
||||
</div>
|
||||
<div class="content_item_info">
|
||||
<div class="time">提交打印时间: <span>{{ item.print_time }}</span></div>
|
||||
<div class="count">模型数量: <span>{{ item.model_count }}</span></div>
|
||||
<div class="reason" v-if="showReason(item)">原因: <span>
|
||||
{{item.message}}
|
||||
</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="icon_item" @click="goDetail(item)">
|
||||
<img class="icon" :src="weight" alt="">
|
||||
<div class="icon_text">称毛重</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import * as api from '@/api/multiPrint'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
const router = useRouter();
|
||||
import weight from '@/assets/common/weight.png';
|
||||
const keyWord = ref('')
|
||||
const loading = ref(false)
|
||||
const error = ref(false)
|
||||
const finished = ref(false)
|
||||
const refreshing = ref(false)
|
||||
let currentPage = ref(1)
|
||||
let currentSize = ref(20)
|
||||
|
||||
const list = ref([])
|
||||
const onLoad = () => {
|
||||
if (refreshing.value) {
|
||||
currentPage.value = 1;
|
||||
list.value = [];
|
||||
refreshing.value = false;
|
||||
}
|
||||
|
||||
getPage()
|
||||
};
|
||||
|
||||
const onRefresh = () => {
|
||||
// 清空列表数据
|
||||
finished.value = false;
|
||||
|
||||
loading.value = true;
|
||||
onLoad();
|
||||
};
|
||||
|
||||
const onSearch = () => {
|
||||
currentPage.value = 1;
|
||||
list.value = [];
|
||||
getPage()
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const goDetail = (val: any) => {
|
||||
console.log("goDetail",val)
|
||||
|
||||
router.push({
|
||||
path: '/multiPrintDetail',
|
||||
query: {
|
||||
id: val.id,
|
||||
machine_id: val.machine_id,
|
||||
model_count: val.model_count,
|
||||
order_count: val.order_count,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getPage() {
|
||||
api.page({
|
||||
page: currentPage.value,
|
||||
keyWord: keyWord.value,
|
||||
size: currentSize.value
|
||||
}).then(res => {
|
||||
console.log("getPage",res)
|
||||
let data = res.list || [];
|
||||
list.value = list.value.concat(data)
|
||||
if(data.length < currentSize.value) {
|
||||
finished.value = true;
|
||||
}
|
||||
currentPage.value++
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
error.value = true
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function renderProgressStatus(item: any) {
|
||||
switch (item.process_status) {
|
||||
case 0:
|
||||
return '待处理'
|
||||
case 1:
|
||||
return `处理中(${item.process_count}/${item.model_count})`
|
||||
case 2:
|
||||
return '处理完成'
|
||||
default:
|
||||
return '处理失败'
|
||||
}
|
||||
}
|
||||
|
||||
function getProgressStatusType(progressStatus) {
|
||||
switch (progressStatus) {
|
||||
case 0:
|
||||
return 'default'
|
||||
case 1:
|
||||
return 'warning'
|
||||
case 2:
|
||||
return 'success'
|
||||
case 3:
|
||||
return 'danger'
|
||||
default:
|
||||
return 'danger'
|
||||
}
|
||||
}
|
||||
|
||||
function showReason(item) {
|
||||
return item.process_status == 3;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #F3F3F3;
|
||||
padding-top: 10px;
|
||||
.page_wrap {
|
||||
position: relative;
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
margin: 0px auto;
|
||||
.content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 93vh;
|
||||
margin: 10px 0;
|
||||
.content_wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
.content_item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
// min-height: 100px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 10px;
|
||||
.left {
|
||||
position: relative;
|
||||
width: 75%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
.content_item_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
.content_item_info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 10px;
|
||||
.time {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
.count {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
span {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
.reason {
|
||||
font-size: 14px;
|
||||
color: #ec4444;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 25%;
|
||||
|
||||
.icon_item {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.icon_text {
|
||||
font-size: 12px;
|
||||
color: #1296db;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.van-search) {
|
||||
padding: 0;
|
||||
background: #ffffff!important;
|
||||
border-radius: 30px;
|
||||
}
|
||||
:deep(.van-search__content) {
|
||||
background: #ffffff!important;
|
||||
}
|
||||
.van-pull-refresh {
|
||||
height: calc(95vh) !important; /* 计算高度(减去的高度自己调) */
|
||||
overflow: auto !important; /* 滚动自适应 */
|
||||
}
|
||||
|
||||
.van-list {
|
||||
height: auto !important; /* 列表高度自适应 */
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="page">
|
||||
<div class="page_wrap">
|
||||
<van-search
|
||||
v-model="keyWord"
|
||||
background="#F3F3F3"
|
||||
shape="round"
|
||||
clearable
|
||||
@search="onSearch"
|
||||
@clear="getOrderList"
|
||||
input-align="center"
|
||||
placeholder="请输入订单号搜索"
|
||||
/>
|
||||
<van-list
|
||||
v-model:loading="loading" v-model:error="error" :error-text="'请求失败,点击重新加载'" :finished-text="'没有更多了'"
|
||||
:finished="finished" @load="onLoad"
|
||||
>
|
||||
<div class="content">
|
||||
<div class="content_wrap">
|
||||
<div class="order_item" v-for="item, index in orderList" :key="index">
|
||||
<div class="order_img">
|
||||
<img :src="imgSrc(item.texture_cover_img)" >
|
||||
</div>
|
||||
<div class="order_info">
|
||||
<div class="order_id">{{ item.pid }}</div>
|
||||
<div class="order_size" >
|
||||
<span v-for="el , elIndex in filterSize(item.model_size)" :key="elIndex">
|
||||
{{ el }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import * as api from '@/api/multiPrint'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { onMounted } from 'vue';
|
||||
const route = useRoute();
|
||||
import {imgSrc} from "@/utils/utils"
|
||||
const id = route.query.id as string | number;
|
||||
const keyWord = ref('')
|
||||
const loading = ref(false)
|
||||
const error = ref(false)
|
||||
const finished = ref(false)
|
||||
const refreshing = ref(false)
|
||||
let currentPage = ref(1)
|
||||
let totalCount = ref(0)
|
||||
const orderList = ref([])
|
||||
// const test = ref('18cm_x2___15cm_x3___20cm_x1')
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
const onLoad = () => {
|
||||
if (refreshing.value) {
|
||||
currentPage.value = 1;
|
||||
orderList.value = [];
|
||||
refreshing.value = false;
|
||||
}
|
||||
|
||||
getOrderList(currentPage.value)
|
||||
loading.value = false;
|
||||
|
||||
if (orderList.value.length >= totalCount.value) {
|
||||
finished.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const filterSize = (input: any) => {
|
||||
const items = input.split("___");
|
||||
|
||||
const result = items.map(item => {
|
||||
const match = item.match(/(\d+)cm_x(\d+)/);
|
||||
if (match) {
|
||||
return `${match[1]}cm*${match[2]}`;
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const getOrderList = (page: any) => {
|
||||
api.detailPage({print_batch_id: id, keyWord: keyWord.value, page: page || 1}).then(res => {
|
||||
console.log(res)
|
||||
orderList.value = [...orderList.value, ...res.list]
|
||||
totalCount.value = res.total
|
||||
loading.value = false
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const onSearch = () => {
|
||||
currentPage.value = 1
|
||||
getOrderList(currentPage.value)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #F3F3F3;
|
||||
padding-top: 10px;
|
||||
.page_wrap {
|
||||
position: relative;
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
margin: 0px auto;
|
||||
.content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 93vh;
|
||||
overflow: scroll;
|
||||
margin: 10px 0;
|
||||
.content_wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
.order_item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
width: 48%;
|
||||
min-height: 154px;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
.order_img {
|
||||
position: relative;
|
||||
width: 163px;
|
||||
height: 122px;
|
||||
overflow: hidden;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
.order_info {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
padding-top: 10px;
|
||||
.order_id {
|
||||
width: 100%;
|
||||
}
|
||||
.order_size {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.van-search) {
|
||||
padding: 0;
|
||||
background: #ffffff!important;
|
||||
border-radius: 30px;
|
||||
}
|
||||
:deep(.van-search__content) {
|
||||
background: #ffffff!important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,768 @@
|
||||
<script lang="tsx" setup>
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
const { toClipboard } = useClipboard()
|
||||
const router = useRouter()
|
||||
import { orderStatus } from '@/utils/utils'
|
||||
import { closeToast, showFailToast, showSuccessToast, showToast } from 'vant';
|
||||
import * as myOrderApi from '@/api/my_order'
|
||||
import { useStore } from '@/stores'
|
||||
const store = useStore();
|
||||
import { useTokenStore } from '@/stores/token'
|
||||
const tokenStore = useTokenStore();
|
||||
|
||||
const {isWechat} = tokenStore;
|
||||
|
||||
const orderInfo = ref({})
|
||||
const orderList = ref("")
|
||||
const orderId = ref("")
|
||||
const title = ref("")
|
||||
const pid = ref("")
|
||||
const userInfo = ref({})
|
||||
const nums = ref(0)
|
||||
const orderDetailInfo = ref({})
|
||||
const dialogShow = ref(false)
|
||||
const dialogShow2 = ref(false)
|
||||
const actionShow = ref(false)
|
||||
const actions = ref([
|
||||
{
|
||||
name: '删除订单'.$t,
|
||||
},
|
||||
])
|
||||
|
||||
onMounted(()=> {
|
||||
userInfo.value = tokenStore.userInfo;
|
||||
orderInfo.value = store.orderInfo;
|
||||
console.log("orderInfo.value", orderInfo.value)
|
||||
getOrderInfo(orderInfo.value.pid);
|
||||
})
|
||||
const returnClick = () => history.back();
|
||||
// 更多点击
|
||||
const moreClick = () => {
|
||||
actionShow.value = !actionShow.value
|
||||
}
|
||||
|
||||
// 删除点击
|
||||
const onSelect = (e) => {
|
||||
if(e.detail.name) {
|
||||
dialogShow.value = true
|
||||
}
|
||||
}
|
||||
const higher = computed(()=> {
|
||||
return isWechat() ? 'higher' : '';
|
||||
});
|
||||
|
||||
// 删除确认
|
||||
const tapDialogButton = (e) => {
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
let params = {
|
||||
pid: orderInfo.value.pid,
|
||||
// unionid: u.unionid
|
||||
}
|
||||
// 状态判断
|
||||
let status = orderInfo.value.status
|
||||
let digital_order_id = orderInfo.value.digital_order_id;
|
||||
let order_id = orderInfo.value.order_id;
|
||||
let experience_status = orderInfo.value.remaining_experience.status;
|
||||
let buyType = 0;
|
||||
let undone_status = 0;
|
||||
if(digital_order_id != order_id && digital_order_id && order_id) {
|
||||
buyType = 1; // 相册和手办都购买
|
||||
if(status != 9000) {
|
||||
undone_status = 1;
|
||||
}
|
||||
}else if(digital_order_id == order_id) {
|
||||
buyType = 2; // 只购买相册
|
||||
if(status < 7011) {
|
||||
undone_status = 1;
|
||||
}
|
||||
}else if(digital_order_id == 0 && order_id !=0) {
|
||||
buyType = 3; // 只购买手办
|
||||
if(status != 9000) {
|
||||
undone_status = 1;
|
||||
}
|
||||
}else if(experience_status == 1 && status < 4100) {
|
||||
buyType = 4; // 免费体验3d相册中
|
||||
if(status < 4100) {
|
||||
undone_status = 1;
|
||||
}
|
||||
}
|
||||
if(undone_status!=0) {
|
||||
dialogShow.value = false;
|
||||
// dialogShow3.value = true;
|
||||
return
|
||||
}
|
||||
// app.api.deleteOrder(params).then((res)=> {
|
||||
// if(res.code == 1000) {
|
||||
// showToast("删除成功".$t)
|
||||
// setTimeout(()=> {
|
||||
// router.push({
|
||||
// path: "/myOrder",
|
||||
// })
|
||||
// }, 2000)
|
||||
// dialogShow.value = false;
|
||||
// }else if(res.code == -1) {
|
||||
// showFailToast(res.message)
|
||||
// }
|
||||
// }).catch((err)=> {
|
||||
// title.value = err;
|
||||
// dialogShow.value = false;
|
||||
// dialogShow2.value = true;
|
||||
// })
|
||||
closeToast();
|
||||
|
||||
}
|
||||
|
||||
const tapDialogButton2 = () => {
|
||||
dialogShow2.value = false
|
||||
contact();
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
actionShow.value = false
|
||||
}
|
||||
|
||||
//获取订单的详情信息
|
||||
const getOrderInfo = (pid) => {
|
||||
if (pid) {
|
||||
myOrderApi.detail(pid).then((res:any)=> {
|
||||
let data = res;
|
||||
data.forEach(element=> {
|
||||
let arr = element.model_size.split(" ")
|
||||
let obj = [];
|
||||
arr.forEach(item => {
|
||||
let index = item.lastIndexOf("*");
|
||||
let num = item.substring(index+1, item.length)
|
||||
let size = item.substring(0, index)
|
||||
obj.push({size,num})
|
||||
});
|
||||
element.filterSize = obj
|
||||
})
|
||||
orderList.value = data;
|
||||
})
|
||||
// data = Object.assign(data, obj)
|
||||
}
|
||||
}
|
||||
|
||||
// 复制
|
||||
const copyOrderId = () => {
|
||||
copy(orderInfo.value.pid.toString())
|
||||
}
|
||||
|
||||
// 使用插件
|
||||
const copy = async (msg) => {
|
||||
try {
|
||||
// 复制
|
||||
console.log("msg", msg)
|
||||
await toClipboard(msg)
|
||||
showSuccessToast("复制成功".$t)
|
||||
// 复制成功
|
||||
} catch (e) {
|
||||
// 复制失败
|
||||
showFailToast("复制失败".$t)
|
||||
}
|
||||
}
|
||||
const callShow = ref(false);
|
||||
const callClick = () => {
|
||||
callShow.value = true;
|
||||
}
|
||||
|
||||
const contact = () => {
|
||||
const a = document.createElement("a");
|
||||
a.href = "tel:" + orderInfo.value.shop_tel
|
||||
a.click();
|
||||
callShow.value = false;
|
||||
}
|
||||
|
||||
// 跳转至3D相册
|
||||
// toAlbum(e) {
|
||||
// //获取用户的信息
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
// var pid = this.data.orderInfo.pid;
|
||||
// var oid = this.data.orderInfo.order_id;
|
||||
// var cn = this.data.orderInfo.customer_name;
|
||||
// var cid = this.data.orderInfo.customer_id;
|
||||
// var createTime = this.data.orderInfo.create_time;
|
||||
// var status = this.data.orderInfo.status;
|
||||
// var remainingExperienceStatus = this.data.orderInfo.remaining_experience.status;
|
||||
// var expireTime = this.data.orderInfo.remaining_experience.day;
|
||||
// var digitalOrderId = this.data.orderInfo.digital_order_id;
|
||||
// var digitalType = this.data.orderInfo.digital_type;
|
||||
// var titleCode = this.data.orderInfo.remaining_experience.title_code;
|
||||
// //判断createTime时间是否在2023-04-15 00:00:00 之后
|
||||
// wx.request({
|
||||
// url: config.url + '/miniProgram/judgeP3dLogOrderTime',
|
||||
// data: { photoTime: createTime, pid },
|
||||
// header: { 'content-type': 'application/json' },
|
||||
// success: (res) => {
|
||||
// if(res.data.data.use_status!=1){
|
||||
// wx.showToast({
|
||||
// title: '该订单不支持3D相册,需重新拍照',
|
||||
// icon: 'none',
|
||||
// duration: 2000
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
// const url = `/package3D/pages/3d/3d?openid=${u.openid}`
|
||||
// + `&unionid=${u.unionid}&id=${pid}&oid=${oid}`
|
||||
// + `&cn=${cn}&cid=${cid}&expireTime=${expireTime}`
|
||||
// + `&digitalType=${digitalType}`
|
||||
// + `&status=${status}`
|
||||
// + `&titleCode=${titleCode}`
|
||||
// + `&remainingExperienceStatus=${remainingExperienceStatus}`;
|
||||
// //判断是否有购买3D相册
|
||||
// if (digitalOrderId == 0) {
|
||||
// wx.navigateTo({
|
||||
// url: url
|
||||
// });
|
||||
// return
|
||||
// }
|
||||
|
||||
// if(remainingExperienceStatus == 1) {
|
||||
// if(status < 4100){
|
||||
// wx.showToast({
|
||||
// title: '3D相册制作中',
|
||||
// icon: 'none',
|
||||
// duration: 2000
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
// wx.navigateTo({
|
||||
// url: url,
|
||||
// });
|
||||
// }
|
||||
// wx.navigateTo({
|
||||
// // 跳转到webview页面
|
||||
// // url: `/pages/webview/webview?nav=${navtitle}&url=${encodeURIComponent(url)}`,
|
||||
// url: url,
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
|
||||
// },
|
||||
|
||||
//前往物流界面
|
||||
const turnToDelivery = () => {
|
||||
if(orderInfo.value.delivery_no) {
|
||||
// wx.navigateTo({
|
||||
// url: '/pages/delivery/delivery',
|
||||
// success: function (res) {
|
||||
// res.eventChannel.emit("orderInfo", that.data.orderInfo)
|
||||
// }
|
||||
// })
|
||||
}else {
|
||||
showToast("暂无快递信息".$t)
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-dialog :title="'确认删除订单?'.$t" :message="'删除的订单将无法恢复'.$t" v-model:show="dialogShow" :confirmButtonText="'确认删除'.$t"
|
||||
:cancelButtonText="'我再想想'.$t" @confirm="tapDialogButton" showCancelButton confirm-button-color="#AAAAAA"
|
||||
cancel-button-color="#009944" round />
|
||||
<van-dialog :title="'门店电话'.$t" :message="'确定拨打门店电话吗?'.$t" v-model:show="callShow" :confirmButtonText="'确定'.$t" :cancelButtonText="'取消'.$t"
|
||||
@confirm="contact" showCancelButton confirm-button-color="#AAAAAA" cancel-button-color="#009944" round />
|
||||
<van-dialog :title="title" v-model:show="dialogShow2" :confirmButtonText="'联系门店'.$t" :cancelButtonText="'我再想想'.$t"
|
||||
@confirm="tapDialogButton2" showCancelButton confirm-button-color="#AAAAAA" cancel-button-color="#009944" round />
|
||||
<!-- <van-dialog :title="'订单处于未完结状态'.$t,无法删除" v-model:show="dialogShow3" :confirmButtonText="'我已知晓'.$t" @confirm="tapDialogButton3"
|
||||
confirm-button-color="#009944" round /> -->
|
||||
<van-action-sheet round v-model:show="actionShow" :actions="actions" @close="onClose" @select="onSelect" @cancel="onClose"
|
||||
:cancel-text="'取消'.$t" />
|
||||
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" :left-text="'返回'.$t" left-arrow
|
||||
@click-left="returnClick" safe-area-inset-top/>
|
||||
<div class="page">
|
||||
<div :class="['container', higher]">
|
||||
<div class="order_info">
|
||||
<div class="text-wrapper_43">
|
||||
<div class="order-info">
|
||||
<div class="text_31">{{ '订单信息'.$t }}</div>
|
||||
<img src="@/assets/order/more.png" mode="widthFix" class="more" @click="moreClick"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-wrapper_45">
|
||||
<div class="order-id">
|
||||
<div class="text_39">{{'订单ID'.$t}}</div>
|
||||
<div class="text_40">{{orderInfo.pid}}</div>
|
||||
</div>
|
||||
<div @click="copyOrderId()" class="button_2">{{ '复制'.$t }}</div>
|
||||
</div>
|
||||
<div class="text-wrapper_44">
|
||||
<div class="text_39">{{ '拍摄门店'.$t }}</div>
|
||||
<div class="text_40">{{orderInfo.shop_name}}</div>
|
||||
</div>
|
||||
<div class="text-wrapper_44">
|
||||
<div class="text_39">{{ '拍摄时间'.$t }}</div>
|
||||
<div decode="true" class="text_40">{{orderInfo.takephoto_time}}</div>
|
||||
</div>
|
||||
|
||||
<!-- 分割线 -->
|
||||
<div class="line"></div>
|
||||
|
||||
<div class="group_13" @click="callClick">
|
||||
<div class="image-text_12">
|
||||
<div class="icon_2">
|
||||
<img class="icon_4" src="@/assets/order/tel.png" />
|
||||
</div>
|
||||
<div class="text-order_record">{{ '联系门店'.$t }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order_record">
|
||||
|
||||
<!-- 订单明细数据 -->
|
||||
<div class="section_2">
|
||||
<div class="order-title">
|
||||
<div class="title">{{ '订单记录'.$t }}</div>
|
||||
</div>
|
||||
<block v-for="item, index in orderList" :key="index">
|
||||
<div class="order-box">
|
||||
<div class="order-top">
|
||||
<div class="header-text">
|
||||
<div lines="1" class="order-name" v-if="item.digital_type == 0">{{ '手办'.$t }}</div>
|
||||
<div lines="1" class="order-name" v-else-if="item.digital_type == 4">{{'体验3D相册'.$t}}</div>
|
||||
<div lines="1" class="order-name" v-else-if="item.digital_type == 1">{{'3D相册'.$t}}</div>
|
||||
<div class="order-status" v-if="item.print_type == 2 && item.digital_type == 0">{{ '重打'.$t }}</div>
|
||||
<div class="order-status" v-else-if="item.print_type == 3 && item.digital_type == 0">{{ '加打'.$t }}</div>
|
||||
</div>
|
||||
<div class="text_13">{{item.create_time}}</div>
|
||||
</div>
|
||||
|
||||
<!-- 遍历数组 -->
|
||||
<div class="" v-if="item.digital_type == 0">
|
||||
<div class="text-wrapper_37" v-for="fItem, fIndex in item.filterSize" :key="fIndex" v-for-item="fItem">
|
||||
<div class="text_14">{{fItem.size}}</div>
|
||||
<div class="text_15">x{{fItem.num}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-wrapper_37">
|
||||
<div class="text_38">
|
||||
{{orderStatus(item.status,item.digital_type).$t}}
|
||||
<van-icon v-if="item.status>=9000 && item.digital_type == 0" @click="turnToDelivery" data-delivery_no="{{item.delivery_no}}" name="arrow" size="18px" color="#767676"/>
|
||||
</div>
|
||||
<div class="text_38">{{item.update_time}}</div>
|
||||
</div>
|
||||
|
||||
<div class="text-wrapper_37">
|
||||
<div class="text_38">{{ '费用合计'.$t }}</div>
|
||||
<div class="total">
|
||||
<div class="text_29">¥</div>
|
||||
<div class="text_30">{{ item.goods_amount / 100}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</block>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
position: relative;
|
||||
width: 375px;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
background: rgba(245, 245, 245, 1.000000);
|
||||
flex-direction: column;
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background: rgba(245, 245, 245, 1.000000);
|
||||
padding-bottom: 60px;
|
||||
box-sizing: border-box;
|
||||
.order_info {
|
||||
background-color: rgba(255, 255, 255, 1.000000);
|
||||
border-radius: 8px;
|
||||
width: 345px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 7.5px auto 0 auto;
|
||||
}
|
||||
|
||||
.order_record {
|
||||
background-color: rgba(255, 255, 255, 1.000000);
|
||||
border-radius: 8px;
|
||||
width: 345px;
|
||||
min-height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 15px auto;
|
||||
|
||||
.section_2 {
|
||||
position: relative;
|
||||
width: 315px;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
border-radius: 8px;
|
||||
|
||||
.order-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
margin-top: 24px;
|
||||
padding-bottom: 6px;
|
||||
margin-bottom: 11px;
|
||||
border-bottom: 2px solid #F0F0F0;
|
||||
|
||||
.title {
|
||||
color: #333333;
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Bold;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.order-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
background: #FAFDFB;
|
||||
.order-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: rgba(236, 244, 234, 1.000000);
|
||||
border-radius: 10px 10px 0px 0px;
|
||||
width: 315px;
|
||||
height: 44px;
|
||||
margin: 0 auto;
|
||||
padding: 0 15px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.header-text {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
.order-name {
|
||||
overflow-wrap: break-word;
|
||||
color: #1A1A1A;
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Medium;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 14px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 24px;
|
||||
background: #ffffff;
|
||||
font-size: 11px;
|
||||
color: #E6A23C;
|
||||
font-weight: 500;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.text_13 {
|
||||
height: 14px;
|
||||
overflow-wrap: break-word;
|
||||
color: #767676;
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Medium;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.higher {
|
||||
padding-bottom: 110px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.text-group_9 {
|
||||
width: 234px;
|
||||
height: 180px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.text-wrapper_37 {
|
||||
width: 285px;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #FAFDFB;
|
||||
border-bottom: 2px solid #F0F0F0;
|
||||
margin: 0 auto;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
||||
.total {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
.text_29 {
|
||||
width: 12px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 12px;
|
||||
font-family: Source Han Sans CN-Bold;
|
||||
font-weight: 700;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.text_30 {
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Bold;
|
||||
font-weight: 700;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.button_3 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
background-color: #009944;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 0 auto;
|
||||
width: 95%;
|
||||
height: 1px;
|
||||
background-color: #F0F0F0;
|
||||
border-bottom: 1px solid #F0F0F0;
|
||||
}
|
||||
|
||||
.text_4 {
|
||||
width: 48px;
|
||||
height: 16px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Medium;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 16px;
|
||||
}
|
||||
.text_14 {
|
||||
height: 12px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(102, 102, 102, 1.000000);
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.text_15 {
|
||||
height: 12px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(102, 102, 102, 1.000000);
|
||||
font-size: 12px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.text-wrapper_43 {
|
||||
position: relative;
|
||||
width: 315px;
|
||||
height: 24px;
|
||||
margin: 14px auto 11px auto;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid #F0F0F0;
|
||||
|
||||
.order-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 315px;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
.more {
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text_31 {
|
||||
width: 64px;
|
||||
height: 16px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Bold;
|
||||
font-weight: 700;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.text-wrapper_44 {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 315px;
|
||||
height: 20px;
|
||||
margin: 0 auto 10px auto;
|
||||
}
|
||||
|
||||
.text_38 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #1A1A1A;
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Medium;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text-wrapper_45 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 315px;
|
||||
margin: 0 auto 10px auto;
|
||||
|
||||
.order-id {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.text_39 {
|
||||
// width: 52px;
|
||||
height: 15px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(153, 153, 153, 1.000000);
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.text_40 {
|
||||
height: 15px;
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(51, 51, 51, 1.000000);
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 15px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.button_2 {
|
||||
width: 36px;
|
||||
height: 20px;
|
||||
color: #AAAAAA;
|
||||
border: 1px solid #AAAAAA;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
border-radius: 5px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.button_2::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.group_13 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
.image-text_12 {
|
||||
height: 16px;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.icon_2 {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
.icon_4 {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.text-order_record {
|
||||
height: 16px;
|
||||
overflow-wrap: break-word;
|
||||
color: #009944;
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Medium;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.group_9 {
|
||||
background-color: rgba(255, 255, 255, 1.000000);
|
||||
height: 72px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 375px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,543 @@
|
||||
<script lang="tsx" setup>
|
||||
import { getCurrentInstance } from 'vue'
|
||||
const instance = getCurrentInstance();
|
||||
import { normalizeStatus, getURLParameters } from '@/utils/utils'
|
||||
import * as myOrderApi from '@/api/my_order'
|
||||
import * as configApi from '@/api/config'
|
||||
import { imgSrc } from "@/utils/utils"
|
||||
import { useStore } from '@/stores'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
const store = useStore();
|
||||
import { useTokenStore } from '@/stores/token'
|
||||
import { showFailToast } from 'vant';
|
||||
const tokenStore = useTokenStore();
|
||||
const router = useRouter();
|
||||
const route = useRoute()
|
||||
const userInfo = ref(null)
|
||||
const refreshing = ref(false)
|
||||
const finished = ref(false)
|
||||
const loading = ref(false)
|
||||
const error = ref(false)
|
||||
const list = ref([])
|
||||
let page = 1
|
||||
const size = 6
|
||||
|
||||
const { isWechat } = tokenStore;
|
||||
const brandId = ref();
|
||||
|
||||
onMounted(() => {
|
||||
userInfo.value = tokenStore.userInfo;
|
||||
brandId.value = instance.proxy.$brandId;
|
||||
getBrand(brandId.value);
|
||||
})
|
||||
|
||||
function onLoad() {
|
||||
if (refreshing.value) {
|
||||
list.value = []
|
||||
page = 1
|
||||
refreshing.value = false
|
||||
}
|
||||
getPage();
|
||||
}
|
||||
|
||||
// 获取页面信息
|
||||
const getPage = () => {
|
||||
myOrderApi.page({
|
||||
page,
|
||||
brand_id: brandId.value || "",
|
||||
size,
|
||||
}).then((res: any) => {
|
||||
const data = res || []
|
||||
list.value = list.value.concat(normalizeStatus(data))
|
||||
if (data.length < size)
|
||||
finished.value = true
|
||||
page++
|
||||
}).catch(() => {
|
||||
error.value = true
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
// 获取品牌信息
|
||||
const getBrand = (val) => {
|
||||
configApi.brand(val).then((res: any) => {
|
||||
store.setBrandInfo(res); // 存储品牌信息
|
||||
setIcon(res)
|
||||
}).catch((err) => {
|
||||
console.log("configErr", err)
|
||||
}).finally(() => {
|
||||
})
|
||||
}
|
||||
|
||||
const setIcon = (res) => {
|
||||
const favicon = res.favicon
|
||||
if (favicon) {
|
||||
const link = document.querySelector("link[rel*='icon']") || document.createElement('link');
|
||||
link.type = 'image/x-icon';
|
||||
link.rel = 'icon';
|
||||
link.href = favicon;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
const onRefresh = () => {
|
||||
// 清空列表数据
|
||||
finished.value = false
|
||||
// 重新加载数据
|
||||
loading.value = true
|
||||
onLoad()
|
||||
}
|
||||
|
||||
// 跳转到3D相册
|
||||
const toAlbum = (data) => {
|
||||
|
||||
store.updateOrderInfo(data)
|
||||
if (data.has_experience || data.status >= 4100) {
|
||||
// 高斯跳转到web
|
||||
router.push({
|
||||
path: data.is_gsplat == 1 ? '/photo3d/gsplat' : '/photo3d',
|
||||
})
|
||||
}else {
|
||||
showFailToast('3D相册制作中'.$t)
|
||||
return
|
||||
}
|
||||
console.log("toAlbum", data)
|
||||
|
||||
// const u = wx.getStorageSync('userInfo');
|
||||
// var pid = e.currentTarget.dataset.pid;
|
||||
// var cn = e.currentTarget.dataset.cn;
|
||||
// var oid = e.currentTarget.dataset.oid;
|
||||
// var cid = e.currentTarget.dataset.cid;
|
||||
// var status = e.currentTarget.dataset.status;
|
||||
// var remainingExperienceStatus = e.currentTarget.dataset.remain_status;
|
||||
// var expireTime = e.currentTarget.dataset.expire_time;
|
||||
// var digitalOrderId = e.currentTarget.dataset.digital_order_id;
|
||||
// var digitalType = e.currentTarget.dataset.digital_type;
|
||||
// var createTime = e.currentTarget.dataset.create_time;
|
||||
// var titleCode = e.currentTarget.dataset.title_code;
|
||||
// console.log(e.currentTarget.dataset)
|
||||
// //判断createTime时间是否在2023-04-15 00:00:00 之后
|
||||
// wx.request({
|
||||
// url: config.url + '/miniProgram/judgeP3dLogOrderTime',
|
||||
// data: {photoTime: createTime, pid},
|
||||
// header: {'content-type': 'application/json'},
|
||||
// success: (res) => {
|
||||
// if (res.data.data.use_status != 1) {
|
||||
// wx.showToast({
|
||||
// title: '该订单不支持3D相册,需重新拍照',
|
||||
// icon: 'none',
|
||||
// duration: 2000
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// const url = `/package3D/pages/3d/3d?openid=${u.openid}`
|
||||
// + `&unionid=${u.unionid}&id=${pid}&oid=${oid}`
|
||||
// + `&cn=${cn}&cid=${cid}&expireTime=${expireTime}`
|
||||
// + `&digitalType=${digitalType}`
|
||||
// + `&status=${status}`
|
||||
// + `&titleCode=${titleCode}`
|
||||
// + `&remainingExperienceStatus=${remainingExperienceStatus}`
|
||||
|
||||
// console.log("url", url);
|
||||
|
||||
// if (digitalOrderId == 0) {
|
||||
// wx.navigateTo({
|
||||
// url: url,
|
||||
// });
|
||||
// return
|
||||
// }
|
||||
|
||||
// if (status < 4100) {
|
||||
// wx.showToast({
|
||||
// title: '3D相册制作中',
|
||||
// icon: 'none',
|
||||
// duration: 2000
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
|
||||
// //获取时间戳
|
||||
// // const timestamp = Date.parse(new Date());
|
||||
// // const url = `http://172.16.20.5:3000/?t=${Date.now()}#/model?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}&expireTime=${expireTime}&remainingExperienceStatus=${remainingExperienceStatus}`
|
||||
// // const url = `https://wechat.suwa3d.com/3d/index.html?t=${Date.now()}#/model?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}`
|
||||
// // const navtitle = '3D相册'; // 这个标题是你自己可以设置的
|
||||
// wx.navigateTo({
|
||||
// // 跳转到webview页面
|
||||
// // url: `/pages/webview/webview?nav=${navtitle}&url=${encodeURIComponent(url)}`,
|
||||
// url: url,
|
||||
// });
|
||||
// },
|
||||
// fail: (err) => {
|
||||
// console.log(err);
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
function getExpeienceText(item: any) {
|
||||
switch (item.remaining_experience?.title_code) {
|
||||
case 1:
|
||||
return '3D相册体验中'.$t
|
||||
case 2:
|
||||
return '3D相册体验结束'.$t
|
||||
case 3:
|
||||
return '您购买的3D相册正在精修中!'.$t
|
||||
}
|
||||
}
|
||||
|
||||
function showExperience(item: any) {
|
||||
return item.remaining_experience?.status !== 0
|
||||
}
|
||||
|
||||
const detailClick = (data: any) => {
|
||||
store.updateOrderInfo(data)
|
||||
router.push({
|
||||
path: '/myOrder/detail',
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" safe-area-inset-top />
|
||||
<div class="page">
|
||||
<div class="container">
|
||||
<div class="box-wrap">
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<Brand />
|
||||
<van-list v-model:loading="loading" v-model:error="error" :error-text="'请求失败,点击重新加载'.$t"
|
||||
:finished-text="'没有更多了'.$t" :finished="finished" @load="onLoad">
|
||||
<van-card v-for="item in list" :key="item.pid">
|
||||
<template #title>
|
||||
<van-cell :title="item.pid" is-link :value="'详情'.$t" class="title" @click="detailClick(item)" />
|
||||
</template>
|
||||
<template #thumb>
|
||||
<img v-if="item.texture_cover_img" :src="imgSrc(item.texture_cover_img)" alt="" @click="toAlbum(item)">
|
||||
<div v-else class="empty_img" @click="toAlbum(item)" ></div>
|
||||
</template>
|
||||
<template #tags>
|
||||
{{ item.head_count }}{{ '人'.$t }}/{{ item.model_json.$t }}
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="van-wrap">
|
||||
<div class="van-status">
|
||||
<div :class="['status', item.statusColor == 0 ? 'undone' : '']">{{ item.statusName.$t }}</div>
|
||||
<div class="created_time">{{ item.update_time }}</div>
|
||||
</div>
|
||||
<div class="btns">
|
||||
<div class="check_btn" v-if="item.status >= 4100 || item.has_experience" @click="toAlbum(item)">{{ '查看3D相册'.$t }}</div>
|
||||
<div class="check_btn disabled" v-else>{{ '查看3D相册'.$t }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="['photograph-box', { expire: item.remaining_experience?.status === 2 }]"
|
||||
v-if="showExperience(item)">
|
||||
<div class="box-wrap">
|
||||
<div class="experience">{{ getExpeienceText(item) }}</div>
|
||||
<div class="right" v-if="item.remaining_experience.day > 0">
|
||||
<div class="countdown">{{ '倒计时'.$t }}<div class="bold">{{ item.remaining_experience?.day }}</div>
|
||||
{{ '天'.$t }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</van-card>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
</div>
|
||||
</div>
|
||||
<Tabbar></Tabbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
box-sizing: border-box;
|
||||
// padding-bottom: calc(env(safe-area-inset-bottom) + 96px);
|
||||
background-color: #F3F3F3;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: block;
|
||||
padding: 5px 15px 0 15px;
|
||||
|
||||
>.box-wrap {
|
||||
overflow-y: scroll;
|
||||
height: 100vh;
|
||||
padding-bottom: 100px;
|
||||
// height: calc(100vh - 96px);
|
||||
}
|
||||
}
|
||||
|
||||
.text-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cover {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: #ffffff;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
background-color: #1aad19;
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
padding-left: 14px;
|
||||
padding-right: 14px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
:deep(.van-card) {
|
||||
background: #ffffff;
|
||||
margin-top: 10px;
|
||||
border: 3px solid #F0F2F5;
|
||||
border-radius: 8px;
|
||||
padding: 0;
|
||||
|
||||
.van-card__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 315px;
|
||||
height: 90px;
|
||||
flex-direction: row;
|
||||
margin: 15px auto;
|
||||
}
|
||||
|
||||
.van-card__thumb {
|
||||
width: 120px;
|
||||
height: 90px;
|
||||
border-radius: 16px;
|
||||
margin-right: 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.empty_img {
|
||||
width: 120px;
|
||||
height: 90px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.van-card__content {
|
||||
display: flex;
|
||||
flex: unset;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 180px;
|
||||
height: 90px;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #666666;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
:deep(.van-cell__title) {
|
||||
flex: unset;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #333333;
|
||||
font-size: 17px;
|
||||
font-family: Source Han Sans CN-Bold;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.van-cell__value),
|
||||
:deep(.van-icon) {
|
||||
// width: 56px;
|
||||
color: #767676;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
:deep(.van-cell) {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
width: 180px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
:deep(.van-card__footer) .van-cell {
|
||||
margin-top: 0.4rem;
|
||||
background: #FAFAFA;
|
||||
}
|
||||
|
||||
:deep(.van-card__footer) .van-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 315px;
|
||||
margin: 0 auto;
|
||||
|
||||
.van-status {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 315px;
|
||||
height: 46px;
|
||||
background-color: #FAFAFA;
|
||||
margin: 0 auto;
|
||||
border-radius: 8px;
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.status {
|
||||
color: #009944;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.created_time {
|
||||
color: #AAAAAA;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.undone {
|
||||
color: #E6A23C;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.van-card__footer) .van-cell__title {
|
||||
text-align: left;
|
||||
color: #009944;
|
||||
}
|
||||
|
||||
.btns {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.check_btn {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
border-radius: 4px;
|
||||
height: 34px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
color: #009944;
|
||||
border: 1px solid#009944;
|
||||
padding: 0 12.5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: .3;
|
||||
}
|
||||
}
|
||||
|
||||
.photograph-box {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
background: #FCF5EB;
|
||||
overflow: hidden;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
border: .5px solid #FDE2E2;
|
||||
box-sizing: border-box;
|
||||
|
||||
.box-wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 315px;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
.experience {
|
||||
font-size: 15px;
|
||||
color: #E6A23C;
|
||||
font-weight: 700;
|
||||
font-family: Source Han Sans CN-Bold;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
color: #E6A23C;
|
||||
position: relative;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
|
||||
.countdown,
|
||||
.hint {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
|
||||
.bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.buy-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 106px;
|
||||
height: 17px;
|
||||
background: #E6A23C;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
font-size: 14px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.expire {
|
||||
border: .5px solid #FDE2E2;
|
||||
background: #FDF0F0;
|
||||
|
||||
.box-wrap {
|
||||
.experience {
|
||||
color: #F56C6C;
|
||||
}
|
||||
|
||||
.right {
|
||||
color: #F56C6C;
|
||||
|
||||
.buy-btn {
|
||||
background: #F56C6C;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,82 @@
|
||||
<script setup lang="ts">
|
||||
import hello from 'hellojs'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
interface Item {
|
||||
icon: string
|
||||
name: string
|
||||
text: string
|
||||
}
|
||||
|
||||
const logins: Ref<Item[]> = ref([
|
||||
// {
|
||||
// icon: 'microsoft',
|
||||
// name: 'windows',
|
||||
// text: '微软',
|
||||
// },
|
||||
{
|
||||
icon: 'googleplus',
|
||||
name: 'google',
|
||||
text: 'G+',
|
||||
},
|
||||
// {
|
||||
// icon: 'facebook',
|
||||
// name: 'facebook',
|
||||
// text: 'Facebook',
|
||||
// },
|
||||
// {
|
||||
// icon: 'apple',
|
||||
// name: 'apple',
|
||||
// text: 'apple',
|
||||
// },
|
||||
{
|
||||
icon: 'twitter',
|
||||
name: 'twitter',
|
||||
text: 'twitter',
|
||||
},
|
||||
// {
|
||||
// icon: 'wechat',
|
||||
// name: 'wechat',
|
||||
// text: 'wechat',
|
||||
// },
|
||||
])
|
||||
|
||||
function onBtn(item: Item) {
|
||||
console.log('onBtn', item)
|
||||
hello(item.name).login().then(() => {
|
||||
console.log('login success')
|
||||
}, () => {
|
||||
console.log('login failed')
|
||||
})
|
||||
}
|
||||
|
||||
hello.on('auth.login', (auth) => {
|
||||
hello(auth.network).api('/me', 'get').then((r) => {
|
||||
localStorage.setItem(auth.network+':r', JSON.stringify(r))
|
||||
console.log(r, '登录成功获取到用户的信息,调用排队接口')
|
||||
}).catch((e) => {
|
||||
localStorage.setItem(auth.network+':e', JSON.stringify(e))
|
||||
console.log(e)
|
||||
})
|
||||
})
|
||||
|
||||
hello.init({
|
||||
facebook: '1875721406193406',
|
||||
windows: '000000004403AD10',
|
||||
google: '495792315385-mj44iuov1bupumvl6evmmcvag39mi38t.apps.googleusercontent.com',
|
||||
twitter: 'ICw3GtdIivmHPI5qTLD0gZDbN',
|
||||
}, {
|
||||
redirect_uri: './oauth.html',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-divider>Loading...</van-divider>
|
||||
<!-- <van-grid :column-num="2">
|
||||
<van-grid-item v-for="(item, i) in logins" :key="i" icon-prefix="iconfont" :icon="item.icon" :text="item.text" @click="onBtn(item)" />
|
||||
</van-grid> -->
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<arMode :pid="pid" :modelFile="modelFile" @handleProgress="handleProgress"
|
||||
@handleLoaded="handleLoaded"></arMode>
|
||||
<!-- <arFrame :pid="pid" :modelFile="modelFile" @handleProgress="handleProgress"
|
||||
@handleLoaded="handleLoaded" @closeHint="closeHint"></arFrame> -->
|
||||
<div class="popup" v-if="showProcess">
|
||||
<div class="pcenter">
|
||||
<div class="text">{{ '渲染中...'.$t }}</div>
|
||||
<van-progress class="progress" :percentage="percent" stroke-width="8px" :show-pivot="false"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="hint_cover" v-if="hintVisible">
|
||||
<div class="hint">将设备</div>
|
||||
<div class="hint">向前和向后移动</div>
|
||||
</div> -->
|
||||
<div class="exit" @click="backTo">
|
||||
<img class="exit_img" :src="exit" />
|
||||
<div>{{'退出AR'.$t}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import exit from "@/assets/photo3D/icon_exit.png";
|
||||
import * as api from '@/api/photo_3d'
|
||||
const router = useRouter()
|
||||
import { showFailToast } from "vant";
|
||||
import { useStore } from '@/stores'
|
||||
const store = useStore();
|
||||
const backTo = () => router.back()
|
||||
const modelFile = ref()
|
||||
const percent = ref(0)
|
||||
const orderInfo = ref()
|
||||
const pid = ref();
|
||||
const showProcess = ref(false)
|
||||
const hintVisible = ref(true)
|
||||
onMounted(()=> {
|
||||
orderInfo.value = store.orderInfo;
|
||||
pid.value = store.orderInfo.pid
|
||||
getModel(pid.value)
|
||||
})
|
||||
|
||||
const closeHint = () => hintVisible.value = false;
|
||||
// 获取模型路径
|
||||
const getModel = (pid: any) => {
|
||||
api.glb(pid).then((data: any) => {
|
||||
if (data && data.s) {
|
||||
// let _data = {
|
||||
// iShare: data.s,
|
||||
// id: data.id,
|
||||
// }
|
||||
// 只有分享的才需要这么处理
|
||||
// if (data.isShare) {
|
||||
// _data.expireTime = data.expireTime || '';
|
||||
// _data.remainingExperienceStatus = data.remainingExperienceStatus || '';
|
||||
// _data.digitalType = data.digitalType || '';
|
||||
// _data.titleCode = data.titleCode || '';
|
||||
// _data.oid = data.oid || '';
|
||||
// }
|
||||
// that.setData(_data)
|
||||
}
|
||||
modelFile.value = data.url;
|
||||
|
||||
|
||||
}).catch(err=> {
|
||||
console.log("loaded failed", err);
|
||||
showFailToast(err && err.message);
|
||||
|
||||
})
|
||||
}
|
||||
// 模型加载进度
|
||||
const handleProgress = (detail) => {
|
||||
showProcess.value = true
|
||||
if (detail < percent.value) return;
|
||||
// 兼容其他机型渲染慢
|
||||
if (detail == 1) {
|
||||
setTimeout(() => {
|
||||
if (showProcess.value) {
|
||||
// 提示模型有问题
|
||||
showProcess.value = false
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
percent.value = detail
|
||||
}
|
||||
|
||||
// 模型加载完成
|
||||
const handleLoaded = (detail) => {
|
||||
setTimeout(() => {
|
||||
showProcess.value = false;
|
||||
}, 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.exit {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
bottom: 30px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
.exit_img {
|
||||
width: 38px;
|
||||
height: 39px;
|
||||
display: block;
|
||||
margin: 0 auto 6px;
|
||||
}
|
||||
}
|
||||
.popup {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 999;
|
||||
text-align: center;
|
||||
}
|
||||
.text {
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress {
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.pcenter {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hint_cover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
z-index: 2;
|
||||
.hint {
|
||||
width: 200px;
|
||||
height: 30px;
|
||||
font-size: 20px;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,610 @@
|
||||
<script setup lang="ts">
|
||||
import { getCurrentInstance } from 'vue'
|
||||
const instance = getCurrentInstance();
|
||||
import { contractMap } from '@/dict/status_dict'
|
||||
import dayjs from 'dayjs'
|
||||
import { showDialog, showFailToast } from 'vant'
|
||||
import { useRoute } from 'vue-router'
|
||||
import * as queueApi from '@/api/queue'
|
||||
import * as configApi from '@/api/config'
|
||||
import router from '@/router'
|
||||
import {getTreeData} from "@/utils/utils"
|
||||
// import {AttrResponse} from './utils/type'
|
||||
// import { AxiosResponse } from 'axios'
|
||||
import { useStore } from '@/stores'
|
||||
const store = useStore();
|
||||
const isProd = process.env.mode === 'production' || process.env.mode === 'gray'
|
||||
const hintShow = ref(false)
|
||||
const isAll = ref(true)
|
||||
const loading = ref(false)
|
||||
const choseManyType = ref([2, 4, 5])
|
||||
const name = ref(isProd ? '' : '测试')
|
||||
const mobile = ref(isProd ? '' : '13695004676')
|
||||
const birthday = ref(isProd ? '' : '1990-10-10')
|
||||
const attrBuyTypes = ref([])
|
||||
const buyTypes = ref([])
|
||||
const attrList = ref([])
|
||||
const goodsList = ref([])
|
||||
const choseList = ref({})
|
||||
const choseAttrsIds = ref([])
|
||||
const choseGoodsIds = ref([])
|
||||
const totalPrice = ref(0)
|
||||
const goodsTotalPrice = ref(0)
|
||||
const shopId = ref(0)
|
||||
const brandId = ref()
|
||||
const logo = ref('')
|
||||
const currency = ref('')
|
||||
const useLogo = ref(false)
|
||||
const v = ref('')
|
||||
const shopName = ref('')
|
||||
// const checkboxRefs = ref([])
|
||||
const agree = ref(false)
|
||||
const showPicker = ref(false)
|
||||
const showAgree = ref(false)
|
||||
const agreePage = ref('')
|
||||
const agreeTitle = ref('')
|
||||
const current = ref();
|
||||
const route = useRoute()
|
||||
const cate_map = ref({
|
||||
1: '数字模型',
|
||||
2: '手办尺寸',
|
||||
3: '额外携带',
|
||||
4: '',
|
||||
})
|
||||
const minDate = new Date(1900, 0, 1)
|
||||
const maxDate = new Date()
|
||||
const ignore = ref()
|
||||
const currentDate = ref(['1990', '10', '10'])
|
||||
|
||||
// const toggle = (index) => {
|
||||
// checkboxRefs.value[index].toggle();
|
||||
// };
|
||||
onMounted(() => {
|
||||
shopId.value = parseInt(String(route.query.shop_id), 10)
|
||||
brandId.value = parseInt(String(route.query.shop_id), 10)
|
||||
ignore.value = parseInt(String(route.query.ignore), 10)
|
||||
shopName.value = String(route.query.shop_name)
|
||||
currency.value = String(route.query.currency)
|
||||
useLogo.value = Boolean(route.query.use_logo)
|
||||
v.value = String(route.query.v)
|
||||
logo.value = String(route.query.logo)
|
||||
if (!logo.value) {
|
||||
// 主要给定制版客户他们需要展示logo
|
||||
logo.value = `/resource/img/logo/${shopId.value}.png?t=${new Date().getTime()}`
|
||||
}
|
||||
brandId.value = instance.proxy.$brandId;
|
||||
// isShowHint();
|
||||
getBrand(brandId.value);
|
||||
// init()
|
||||
})
|
||||
const isShowHint = ()=> {
|
||||
isAll.value = ignore.value == 0 ? false : true;
|
||||
if(ignore.value == 0) {
|
||||
hintShow.value = false
|
||||
}else {
|
||||
hintShow.value = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const closeHint = () => {
|
||||
hintShow.value = false;
|
||||
}
|
||||
|
||||
const checkChange = (val) => {
|
||||
console.log('123', val)
|
||||
agree.value = val;
|
||||
}
|
||||
|
||||
// 获取品牌信息
|
||||
const getBrand = (val) => {
|
||||
configApi.brand(val).then((res: any) => {
|
||||
store.setBrandInfo(res); // 存储品牌信息
|
||||
|
||||
setIcon(res)
|
||||
}).catch((err) => {
|
||||
console.log("configErr", err)
|
||||
}).finally(() => {
|
||||
})
|
||||
}
|
||||
|
||||
function onViewAgree(name: string, val: number) {
|
||||
let url;
|
||||
let sid = brandId.value;
|
||||
let timeStamp = Date.now();
|
||||
// TODO: 英文路径在/v1/en下面,之后要新增多语言支持时需要根据语言来切换协议
|
||||
// 版本号之后采用后端回传来确认协议版本号
|
||||
if(store.brandInfo.agrees) {
|
||||
store.brandInfo.agrees.filter((el: any)=> {
|
||||
if(el.agree_type == val) {
|
||||
url = el.url
|
||||
agreeTitle.value = el.title
|
||||
}
|
||||
})
|
||||
}else {
|
||||
if(sid == 130 || sid == 134) {
|
||||
url = `/pages/agreement/v1/cn/${sid}/${name}.html?` + timeStamp
|
||||
}else {
|
||||
url = `/pages/agreement/v1/${name}.html?` + timeStamp;
|
||||
}
|
||||
}
|
||||
agreeTitle.value = contractMap[val]
|
||||
showAgree.value = true
|
||||
agreePage.value = url
|
||||
}
|
||||
|
||||
const setIcon = (res) => {
|
||||
const favicon = res.favicon
|
||||
if (favicon) {
|
||||
const link = document.querySelector("link[rel*='icon']") || document.createElement('link');
|
||||
link.type = 'image/x-icon';
|
||||
link.rel = 'icon';
|
||||
link.href = favicon;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
const hidden = ref(false)
|
||||
const init = () => {
|
||||
nextTick(()=> {
|
||||
loading.value = true
|
||||
queueApi.attr({
|
||||
shop_id: shopId.value,
|
||||
brand_id: brandId.value || "",
|
||||
}).then((res: any) => {
|
||||
goodsList.value = res.goods;
|
||||
hidden.value = !!res.hidden;
|
||||
// setAttrList(res.attrs);
|
||||
// setGoodsList(res.goods);
|
||||
// 购买类型默认无效
|
||||
attrBuyTypes.value = res.attrBuyTypes || [];
|
||||
if (attrBuyTypes.value.length) buyTypes.value = [attrBuyTypes[0]?.value.id];
|
||||
|
||||
// 初始化
|
||||
defaultSelected();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('err', error)
|
||||
showDialog({ message: error.message }).then(() => {
|
||||
router.replace('/')
|
||||
})
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const selectedGoodsMap = ref({})
|
||||
const selectedGoodsAttrMap = ref({})
|
||||
const attributeMap = ref({})
|
||||
|
||||
const setGoodsList = (data) => {
|
||||
let _data = data || [];
|
||||
let list = [];
|
||||
let cateMap = {};
|
||||
_data.forEach((el) => {
|
||||
let cate = cateMap[el.cate_id];
|
||||
if (!cate) {
|
||||
cate = {
|
||||
id: el.cate_id,
|
||||
cate_name: el.cate_name,
|
||||
children: [],
|
||||
attrs: []
|
||||
};
|
||||
cateMap[el.cate_id] = cate;
|
||||
list.push(cate);
|
||||
selectedGoodsMap.value[el.cate_id] = [];
|
||||
selectedGoodsAttrMap.value[el.cate_id] = [];
|
||||
if (el.attr_ids != "") {
|
||||
JSON.parse(el.attr_ids).forEach((el) => {
|
||||
let c = attributeMap.value[el];
|
||||
if (c) {
|
||||
cate.attrs.push(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
cate.children.push(el);
|
||||
cate.children.sort((a, b) => a.sort - b.sort);
|
||||
});
|
||||
|
||||
list.sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
});
|
||||
attrList.value = list;
|
||||
}
|
||||
const selectedData = ref({})
|
||||
const attributeList = ref([])
|
||||
const setAttrList = (data) => {
|
||||
let _data = data || [];
|
||||
_data.map((e) => {
|
||||
e.parentId = e.parent_id;
|
||||
e.orderNum = e.id;
|
||||
attributeMap.value[e.id] = e;
|
||||
});
|
||||
|
||||
let __data = getTreeData(_data);
|
||||
__data.forEach((e) => {
|
||||
selectedData.value[e.id] = [];
|
||||
});
|
||||
|
||||
attributeList.value = __data;
|
||||
}
|
||||
|
||||
const selectBuyType = (buyType) => {
|
||||
buyTypes.value = buyType;
|
||||
getGoodsPrice();
|
||||
}
|
||||
const cate_map_list = ref({
|
||||
1: [],
|
||||
2: [],
|
||||
3: [],
|
||||
4: []
|
||||
})
|
||||
const currentGood = ref(null)
|
||||
const selectGoods = (cateId, goodsId) => {
|
||||
// 当前选择的分类
|
||||
current.value = cateId;
|
||||
currentGood.value = goodsId;
|
||||
}
|
||||
|
||||
const goodsChange = (e) => {
|
||||
|
||||
// 将选择的分类数据插入到总数据
|
||||
// if (index >= 0) {
|
||||
// cate_map_list.value[currentData]?.splice(index, 1)
|
||||
// } else {
|
||||
// cate_map_list.value[currentData]?.push(goodData);
|
||||
// }
|
||||
|
||||
getGoodsPrice();
|
||||
}
|
||||
|
||||
const selectGoodsAttr = (cateId, attrId) => {
|
||||
selectedGoodsAttrMap.value[cateId] = attrId;
|
||||
getGoodsPrice();
|
||||
}
|
||||
const calculated = ref(false)
|
||||
|
||||
watch(() => totalPrice.value, (val, preVal) => {
|
||||
totalPrice.value = calculated.value ? totalPrice.value : 0
|
||||
},{immediate: true})
|
||||
|
||||
// 计算价格
|
||||
function getGoodsPrice() {
|
||||
// 遍历选中的产品
|
||||
const attrIds = []
|
||||
const goodsIds = []
|
||||
Object.values(selectedGoodsMap.value).forEach((cl: any)=> {
|
||||
Object.values(cl).forEach((item)=> {
|
||||
goodsIds.push(item)
|
||||
})
|
||||
})
|
||||
Object.values(selectedGoodsAttrMap.value).forEach((dl: any) => {
|
||||
if(!Array.isArray(dl)) {
|
||||
attrIds.push(dl)
|
||||
}
|
||||
|
||||
});
|
||||
choseAttrsIds.value = attrIds
|
||||
choseGoodsIds.value = goodsIds
|
||||
queueApi.calc({
|
||||
buy_types: filterBuyTypes(),
|
||||
attr_ids: attrIds,
|
||||
goods_ids: goodsIds,
|
||||
shop_id: shopId.value,
|
||||
})
|
||||
.then((res: any) => {
|
||||
console.log('获取到价格', res)
|
||||
totalPrice.value = res.totalPrice * 100 || 0
|
||||
goodsTotalPrice.value = res.goodsTotalPrice * 100 || 0
|
||||
calculated.value = true
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('err', err)
|
||||
totalPrice.value = 0
|
||||
goodsTotalPrice.value = 0
|
||||
calculated.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function filterBuyTypes() {
|
||||
return (buyTypes.value || []).filter((item) => item > 0)
|
||||
}
|
||||
|
||||
// const onGoodsChange = (data) => {
|
||||
// totalPrice.value = data.total_amount;
|
||||
// goodsTotalPrice.value = data.total_goods_amount;
|
||||
// choseAttrsIds.value = data.attr_ids
|
||||
// choseGoodsIds.value = data.goods_ids
|
||||
// calculated.value = data.calculated;
|
||||
// }
|
||||
|
||||
// 提交订单
|
||||
function onSubmit() {
|
||||
loading.value = true
|
||||
// if (totalPrice.value === 0) {
|
||||
// if (choseGoodsIds.value.length === 0) {
|
||||
// showDialog({ message: '请先选择手办尺寸'.$t })
|
||||
// loading.value = false
|
||||
// return
|
||||
// }
|
||||
// if (choseAttrsIds.value.length === 0) {
|
||||
// showDialog({ message: '请先选择拍摄姿势'.$t })
|
||||
// loading.value = false
|
||||
// return
|
||||
// }
|
||||
// showDialog({ message: '请先选择手办尺寸'.$t })
|
||||
// loading.value = false
|
||||
// return
|
||||
// }
|
||||
|
||||
if (agree.value === false && isAll.value) {
|
||||
hintShow.value = true
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
submitQueue().finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function submitQueue() {
|
||||
const params = {
|
||||
// attr_ids: choseAttrsIds.value,
|
||||
// goods_ids: choseGoodsIds.value,
|
||||
shop_id: shopId.value,
|
||||
applyTime: dayjs(currentDate.value.join('-')).format('YYYY-MM-DD'),
|
||||
customer_mobile: mobile.value,
|
||||
customer_name: name.value,
|
||||
// buy_types: filterBuyTypes(),
|
||||
}
|
||||
|
||||
return queueApi.queueAdd(params)
|
||||
.then((res: any) => {
|
||||
// showDialog({ message: '排队成功' })
|
||||
// const path = `/queue/succeed?shop_id=${shopId.value}&shop_name=${shopName.value}¤cy=${currency.value}&use_logo=${useLogo.value ? 1 : ''
|
||||
// }&v=${v.value}&index=${res.index}`
|
||||
const path = `/queue/succeed?shop_id=${shopId.value}&shop_name=${shopName.value}&use_logo=${useLogo.value ? 1 : ''
|
||||
}&v=${v.value}&index=${res.index}`
|
||||
router.push(path)
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
showDialog({ message: err.message })
|
||||
})
|
||||
}
|
||||
const goodsHidden = () => {
|
||||
return hidden.value;
|
||||
// return this.shop_id == 86;
|
||||
}
|
||||
// 默认选中
|
||||
const defaultSelected = () => {
|
||||
|
||||
if(!goodsHidden()) {
|
||||
return;
|
||||
}
|
||||
attrList.value.forEach((el) => {
|
||||
if (el.id == 2) {
|
||||
el.children.forEach(child => {
|
||||
if (child.goods_name == '18cm') {
|
||||
selectGoods(el.id, child.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (el.attrs.length) {
|
||||
el.attrs.forEach(child => {
|
||||
if (child.attr_name == '站姿') {
|
||||
selectGoodsAttr(el.id, child.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
// console.log(JSON.stringify(el))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function onConfirm({ selectedValues }) {
|
||||
currentDate.value = selectedValues
|
||||
console.log('currentDate', currentDate.value);
|
||||
birthday.value = selectedValues.join('-')
|
||||
showPicker.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page" :class="[{'goods-hidden': goodsHidden()}]">
|
||||
<Hint :hintShow="hintShow" @onViewAgree="onViewAgree" @check="checkChange" @close="closeHint"></Hint>
|
||||
<van-form @submit="onSubmit">
|
||||
<img v-if="useLogo" :src="logo" class="logo">
|
||||
<van-cell-group inset>
|
||||
<van-field
|
||||
v-model="shopName" disabled readonly name="shopName" label-width="65px" :label="'门店'.$t"
|
||||
/>
|
||||
<van-field
|
||||
v-model="name" name="name" :label="'姓名'.$t" label-width="65px" :placeholder="'姓名'.$t"
|
||||
:rules="[{ required: true, message: '请填写姓名'.$t }]"
|
||||
/>
|
||||
<van-field
|
||||
v-model="mobile" name="mobile" :label="'手机'.$t" label-width="65px" :placeholder="'手机'.$t"
|
||||
:rules="[{ required: true, message: '请填写手机'.$t }]"
|
||||
/>
|
||||
<van-field
|
||||
v-model="birthday" is-link readonly name="birthday" label-width="65px" :label="'生日'.$t" :placeholder="'生日'.$t"
|
||||
:rules="[{ required: true, message: '请填写生日'.$t }]" @click="showPicker = true"
|
||||
/>
|
||||
|
||||
<!-- <van-field :label="'购买类型'.$t" label-width="65px" v-if="attrBuyTypes.length > 0">
|
||||
<template #input>
|
||||
<el-checkbox-group v-model="buyTypes" size="small" @change="selectBuyType">
|
||||
<el-checkbox-button v-for="al in attrBuyTypes" :key="al.id" :label="al.id">
|
||||
{{ al.name.$t }}
|
||||
</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</template>
|
||||
</van-field> -->
|
||||
<!-- <template v-for="item in attrList">
|
||||
<template
|
||||
v-if="item.children && item.children.length && item.children.length > 0"
|
||||
>
|
||||
<van-field :label="cate_map[item.id].$t" label-width="65px">
|
||||
<template #input>
|
||||
<el-checkbox-group v-model="selectedGoodsMap[item.id]" size="small" @change="goodsChange">
|
||||
<el-checkbox-button v-for="cl in item.children" :key="cl.id" :label="cl.id" @click="selectGoods(item.id, cl.id)">
|
||||
{{ item.id == 1 ? '选购'.$t : cl.goods_name.$t }}
|
||||
</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</template>
|
||||
</van-field>
|
||||
<template v-if="item.attrs.length">
|
||||
<van-field :label="'拍摄姿势'.$t" label-width="65px">
|
||||
<template #input>
|
||||
<el-radio-group v-model="selectedGoodsAttrMap[item.id]" size="small">
|
||||
<el-radio-button v-for="rl in item.attrs" :key="rl.id" :label="rl.id" @click="selectGoodsAttr(item.id, rl.id)" >
|
||||
{{ rl.attr_name.$t }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
</van-field>
|
||||
</template>
|
||||
</template>
|
||||
</template> -->
|
||||
<!-- <van-field>
|
||||
<template #input>
|
||||
<div class="warning-box">
|
||||
<img class="image" src="@/assets/common/warning.png" alt="" />
|
||||
<div class="tip">{{'以上为单人拍照参考价格,详细可与店员咨询'.$t}}</div>
|
||||
</div>
|
||||
</template>
|
||||
</van-field> -->
|
||||
</van-cell-group>
|
||||
|
||||
<div class="empty-footer" />
|
||||
<!-- <van-submit-bar
|
||||
v-if="!loading" :loading="loading" :currency="currency.$t" :price="totalPrice" :button-text="'提交'.$t"
|
||||
:label="'合计:'.$t"
|
||||
@submit="onSubmit"
|
||||
> -->
|
||||
<van-submit-bar
|
||||
v-if="!loading" :loading="loading" :button-text="'提交'.$t"
|
||||
@submit="onSubmit"
|
||||
>
|
||||
<!-- <van-checkbox v-model="checked">全选</van-checkbox> -->
|
||||
<template #tip v-if="isAll">
|
||||
<van-checkbox icon-size="18px" v-model="agree" checked-color="#07c160">
|
||||
<span style="font-size: 14px;">{{'我已阅读并同意'.$t}}</span>
|
||||
<a
|
||||
href="javascript:;" class="agreement"
|
||||
@click.stop="onViewAgree('user_service', 1)"
|
||||
>《{{'用户服务协议'.$t}}》</a>
|
||||
<a
|
||||
href="javascript:;" class="agreement"
|
||||
@click.stop="onViewAgree('user_privacy', 2)"
|
||||
>《{{'用户隐私政策'.$t}}》</a>和
|
||||
<a v-if="store.brandInfo.agrees?.length > 2"
|
||||
href="javascript:;" class="agreement"
|
||||
@click.stop="onViewAgree('child_privacy', 3)"
|
||||
>《{{'儿童隐私政策'.$t}}》</a>
|
||||
</van-checkbox>
|
||||
</template>
|
||||
</van-submit-bar>
|
||||
|
||||
<van-popup v-model:show="showPicker" position="bottom">
|
||||
<van-date-picker
|
||||
v-model="currentDate" :min-date="minDate" :max-date="maxDate" @confirm="onConfirm"
|
||||
@cancel="showPicker = false"
|
||||
/>
|
||||
</van-popup>
|
||||
</van-form>
|
||||
|
||||
<van-overlay :show="loading">
|
||||
<div class="loading-wrapper" @click.stop>
|
||||
<van-loading size="24px">
|
||||
{{'加载中'.$t}}...
|
||||
</van-loading>
|
||||
</div>
|
||||
</van-overlay>
|
||||
|
||||
<van-dialog v-model:show="showAgree" :title="agreeTitle.$t" :confirm-button-text="'我已知晓'.$t" width="100vw" class="agree-dialog">
|
||||
<iframe :src="agreePage" class="agree-iframe" />
|
||||
</van-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.el-checkbox-button) {
|
||||
--el-checkbox-button-checked-bg-color: #1aad19;
|
||||
--el-checkbox-button-checked-border-color: #1aad19;
|
||||
--el-checkbox-button-checked-color: #1aad19;
|
||||
}
|
||||
:deep(.el-radio-button) {
|
||||
--el-radio-button-checked-bg-color: #1aad19;
|
||||
--el-radio-button-checked-border-color: #1aad19;
|
||||
}
|
||||
:deep(.el-checkbox-button__inner:hover) {
|
||||
color: #000;
|
||||
}
|
||||
:deep(.el-radio-button__inner:hover) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:deep(.van-submit-bar__button--danger) {
|
||||
background: #1aad19;
|
||||
}
|
||||
.goods-hidden{
|
||||
display: none;
|
||||
}
|
||||
.page {
|
||||
background-color: #f5f5f5;
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
padding-top: 15px;
|
||||
|
||||
}
|
||||
.logo {
|
||||
width: 96%;
|
||||
margin: 0.5rem auto;
|
||||
/* min-height:10rem; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-footer {
|
||||
height: 10rem
|
||||
}
|
||||
|
||||
.loading-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.agree-iframe {
|
||||
height: 80vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.warning-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
.image {
|
||||
margin-right: 5px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
}
|
||||
.agreement {
|
||||
color: #1aad19;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<script setup lang="tsx">
|
||||
import { useRoute } from 'vue-router'
|
||||
import router from '@/router'
|
||||
const index = ref('0')
|
||||
|
||||
const route = useRoute()
|
||||
onMounted(() => {
|
||||
index.value = route.query.index as string
|
||||
})
|
||||
|
||||
function goBack() {
|
||||
router.back()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<van-empty :description="'排队成功'.$t" image="/resource/img/succeed.png">
|
||||
<div class="footer">
|
||||
<p class="text">
|
||||
{{"您前面还有".$t}} <span class="num">{{ index }}</span> {{"人请等待叫号".$t}}
|
||||
</p>
|
||||
<van-button @click="goBack">
|
||||
{{"返回".$t}}
|
||||
</van-button>
|
||||
</div>
|
||||
</van-empty>
|
||||
<div class="empty" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container{
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #ffffff;
|
||||
}
|
||||
.footer{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.text{
|
||||
font-size: 14px;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
.num{
|
||||
color: #009944;
|
||||
}
|
||||
}
|
||||
|
||||
.empty{
|
||||
height: 10vh;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
export interface AttrResponse {
|
||||
attrBuyTypes: AttrBuyType[]
|
||||
attrs: Attr[]
|
||||
goods: Good[]
|
||||
hidden: boolean
|
||||
}
|
||||
|
||||
export interface AttrBuyType {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface Attr {
|
||||
id: number
|
||||
attr_name: string
|
||||
parent_id: number
|
||||
attr_ratio: number
|
||||
version_id: number
|
||||
type_id: number
|
||||
model_repair_cost: number
|
||||
attr_level: number
|
||||
attr_desc: string
|
||||
attr_price: number
|
||||
digital_price: number
|
||||
createTime: string
|
||||
updateTime: string
|
||||
}
|
||||
|
||||
export interface Good {
|
||||
id: number
|
||||
version_id: number
|
||||
status: number
|
||||
cate_id: number
|
||||
base_attr_id: number
|
||||
goods_name: string
|
||||
goods_desc: string
|
||||
attr_ids: string
|
||||
attr_ids_list?: number[]
|
||||
with_attr_ids: string
|
||||
with_attr_ids_list: any
|
||||
shop_ids: any
|
||||
with_attr_discount: number
|
||||
goods_type: number
|
||||
goods_price: number
|
||||
createTime: string
|
||||
updateTime: string
|
||||
cate_name: string
|
||||
price: number
|
||||
src_price: number
|
||||
goods_count: number
|
||||
attr_id: number
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<script lang="tsx" setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
import * as Dict from './dict'
|
||||
import { actions as actionsApi } from '@/api/short_url'
|
||||
import router from '@/router'
|
||||
import Loading from '@/components/loading/index.vue'
|
||||
const code = ref('')
|
||||
const actions = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
const route = useRoute()
|
||||
onMounted(() => {
|
||||
code.value = route.query.code as string
|
||||
getActions()
|
||||
})
|
||||
|
||||
function onAction(action: any) {
|
||||
switch (action.value) {
|
||||
case Dict.OperationWebsiteId:
|
||||
window.location.href = action.jump_url
|
||||
break
|
||||
case Dict.OperationMiniProgramId:
|
||||
window.location.href = action.jump_url
|
||||
break
|
||||
case Dict.OrderHistoryId:
|
||||
router.push(`/shortUrl/orderTrack?code=${code.value}&action=orderTrack`)
|
||||
break
|
||||
case Dict.OrderInfoId:
|
||||
router.push(`/shortUrl/orderInfo?code=${code.value}&action=orderInfo`)
|
||||
break
|
||||
case Dict.PrintOrderInfoId:
|
||||
router.push(`/shortUrl/printOrderInfo?code=${code.value}&action=printOrderInfo`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function getActions() {
|
||||
loading.value = true
|
||||
actionsApi(code.value).then((res: any) => {
|
||||
actions.value = res || []
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
v-for="action in actions"
|
||||
:key="action.value"
|
||||
:title="action.label"
|
||||
:clickable="true"
|
||||
@click="onAction(action)"
|
||||
>
|
||||
点击查看
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<Loading :loading="loading" />
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -0,0 +1,54 @@
|
||||
<script setup lang="tsx">
|
||||
defineProps({
|
||||
activity: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
})
|
||||
function sortByTimeDesc(bjectInfo: any[]) {
|
||||
// 进行逆序降序排序
|
||||
const tempRes = (bjectInfo || []).filter((el: any) => el?.routes?.length > 0).sort((a, b) => {
|
||||
return new Date(b.acceptTime).getTime() - new Date(a.acceptTime).getTime()
|
||||
})
|
||||
return tempRes
|
||||
}
|
||||
|
||||
function getAcceptTime(item) {
|
||||
if (item && item.routes && item.routes[0])
|
||||
return item.routes[0].acceptTime
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
// function hasExpressRouter(routerList?: any[]) {
|
||||
// if (!routerList)
|
||||
// return false
|
||||
|
||||
// return routerList.some((item) => {
|
||||
// return item.routes && item.routes.length > 0
|
||||
// })
|
||||
// }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-step
|
||||
v-for="(item, index1) in sortByTimeDesc(
|
||||
activity.routerInfo,
|
||||
)" :key="index1"
|
||||
>
|
||||
<h3>
|
||||
{{ item.routes[0] ? item.routes[0].acceptAddress : '' }}
|
||||
({{ item.routes[0] ? item.routes[0].remark : '' }})
|
||||
</h3>
|
||||
<p>{{ getAcceptTime(item) }}</p>
|
||||
</van-step>
|
||||
<van-step>
|
||||
<h3>
|
||||
{{ activity.msg }} {{ activity.express_no
|
||||
}}
|
||||
</h3>
|
||||
<p>{{ activity.time }}</p>
|
||||
</van-step>
|
||||
</template>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,28 @@
|
||||
export const View3DPhotoAlbumCode = 'view_3d_photo_album'
|
||||
export const View3DPhotoAlbumName = '查看3D相册'
|
||||
export const View3DPhotoAlbumId = 1
|
||||
|
||||
// 运营网址
|
||||
export const OperationWebsiteCode = 'operation_website'
|
||||
export const OperationWebsiteName = '运营网址'
|
||||
export const OperationWebsiteId = 2
|
||||
|
||||
// 运营小程序
|
||||
export const OperationMiniProgramCode = 'operation_mini_program'
|
||||
export const OperationMiniProgramName = '运营小程序'
|
||||
export const OperationMiniProgramId = 3
|
||||
|
||||
// 订单履历
|
||||
export const OrderHistoryCode = 'order_history'
|
||||
export const OrderHistoryName = '订单履历'
|
||||
export const OrderHistoryId = 4
|
||||
|
||||
// 订单信息
|
||||
export const OrderInfoCode = 'order_info'
|
||||
export const OrderInfoName = '订单信息'
|
||||
export const OrderInfoId = 5
|
||||
|
||||
// 打印订单信息
|
||||
export const PrintOrderInfoCode = 'print_order_info'
|
||||
export const PrintOrderInfoName = '打印订单信息'
|
||||
export const PrintOrderInfoId = 6
|
||||
@@ -0,0 +1,171 @@
|
||||
<script lang="tsx" setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { Ref } from 'vue'
|
||||
import { modelSize as _modelSize, printType } from './utils'
|
||||
import { orderInfo as orderInfoApi } from '@/api/short_url'
|
||||
import Loading from '@/components/loading/index.vue'
|
||||
|
||||
import { filterMsgButton } from '@/dict/status_dict'
|
||||
|
||||
const code = ref('')
|
||||
const src = ref('')
|
||||
const data: Ref<any> = ref({})
|
||||
const tags = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
const modelSize = _modelSize
|
||||
|
||||
const route = useRoute()
|
||||
onMounted(() => {
|
||||
code.value = route.query.code as string
|
||||
getInfo()
|
||||
})
|
||||
|
||||
function getImage() {
|
||||
src.value = ''
|
||||
if (data.value.info && data.value.info.texture_cover_img)
|
||||
src.value = `https://3dview.suwa3d.com/${data.value.info.texture_cover_img}`
|
||||
}
|
||||
|
||||
function getTags() {
|
||||
// 判断是否有订单信息
|
||||
if (!data.value.info || !data.value.info.pid)
|
||||
return
|
||||
|
||||
// 遍历循环
|
||||
const arrTags = [];
|
||||
// 数据信息遍历
|
||||
[data.value].forEach((item: any) => {
|
||||
const arrTag = []
|
||||
// 加急单
|
||||
if (item.is_expedited) {
|
||||
// 插入数据
|
||||
arrTag.push('加急')
|
||||
}
|
||||
|
||||
// 超时单
|
||||
if (item.is_expires)
|
||||
arrTag.push('超时')
|
||||
|
||||
const msg = printType(item.info.print_type)
|
||||
if (msg !== '' && msg !== '正常')
|
||||
arrTag.push(msg)
|
||||
|
||||
arrTags.push(arrTag)
|
||||
})
|
||||
tags.value = arrTags
|
||||
}
|
||||
|
||||
function isSample() {
|
||||
return data.value.order_tag_type === 'sample'
|
||||
}
|
||||
|
||||
function getPrintTypeText() {
|
||||
switch (data.value?.info?.print_type) {
|
||||
case 1:
|
||||
return '首次打印'
|
||||
case 2:
|
||||
return '重打'
|
||||
case 3:
|
||||
return '加打'
|
||||
}
|
||||
}
|
||||
|
||||
function getStatusText() {
|
||||
return filterMsgButton(data.value?.info?.status, 'text')
|
||||
}
|
||||
|
||||
function getInfo() {
|
||||
loading.value = true
|
||||
orderInfoApi(code.value).then((res: any) => {
|
||||
data.value = res || {}
|
||||
getImage()
|
||||
getTags()
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="拍照订单">
|
||||
<span>
|
||||
{{ data?.info?.pid }}
|
||||
</span>
|
||||
</van-cell>
|
||||
<van-cell title="尺寸*数量">
|
||||
<van-tag v-for="(item, key) in modelSize(data?.info?.model_size)" :key="key" type="success" plain>
|
||||
{{ item }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
<van-cell title="提交建模时间" :value="data.submit_model_time" />
|
||||
<van-cell title="订单状态">
|
||||
<van-tag type="success">
|
||||
{{ loading ? '' : getStatusText() }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
<van-cell title="打印类型">
|
||||
<van-tag v-if="isSample()" type="success">
|
||||
样品
|
||||
</van-tag>
|
||||
<van-tag type="success">
|
||||
{{ getPrintTypeText() }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title=" ">
|
||||
<van-cell title="商品金额">
|
||||
<span>{{ data.goods_amount / 100 }} {{ data.currency }}</span>
|
||||
</van-cell>
|
||||
<van-cell v-if="data.other_fee_amount > 0 && data.other_fee_name !== ''" :title="`优惠金额(${data.other_fee_name})`">
|
||||
<span>{{ data.other_fee_amount / 100 }} {{ data.currency }}</span>
|
||||
</van-cell>
|
||||
<van-cell title="总计">
|
||||
<span>{{ data.total_amount / 100 }} {{ data.currency }}</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="门店客户信息">
|
||||
<van-cell title="门店" :value="data?.info?.shop_name" />
|
||||
<van-cell title="客户">
|
||||
{{ data?.info?.customer_name }} (TEL:{{ data?.info?.customer_mobile }})
|
||||
</van-cell>
|
||||
<van-cell title="寄送地址">
|
||||
<span>
|
||||
{{ data?.info?.province_name }}
|
||||
{{ data?.info?.city_name }}
|
||||
{{ data?.info?.country_name }}
|
||||
{{ data?.info?.address }}
|
||||
</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="重量">
|
||||
<van-cell title="毛重">
|
||||
<span>{{ data?.info?.model_gross_weight }}g</span>
|
||||
</van-cell>
|
||||
<van-cell title="净重">
|
||||
<span>{{ data?.info?.model_weight }}g</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group v-if="data.motherList && data.motherList.length > 0" title="其他">
|
||||
<van-cell title="子母单">
|
||||
<van-tag
|
||||
v-for="(item, key) in data.motherList" :key="key" type="success"
|
||||
class="mother-tag"
|
||||
plain
|
||||
>
|
||||
{{ item.pid }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<Loading :loading="loading" />
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.mother-tag{
|
||||
margin-right: 0.4rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,72 @@
|
||||
<script lang="tsx" setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { Ref } from 'vue'
|
||||
import OrderTrackItem from './components/orderTrackItem.vue'
|
||||
import { orderTrack as orderTrackApi } from '@/api/short_url'
|
||||
|
||||
const code = ref('')
|
||||
const data: Ref<any> = ref({})
|
||||
const activities = ref([])
|
||||
const route = useRoute()
|
||||
const loading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
code.value = route.query.code as string
|
||||
getInfo()
|
||||
})
|
||||
|
||||
function getInfo() {
|
||||
loading.value = true
|
||||
orderTrackApi(code.value).then((res: any) => {
|
||||
data.value = res || {}
|
||||
formatData(data.value)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function formatData(res: any) {
|
||||
const tempData = res
|
||||
// 进行逆序降序排序
|
||||
const tempRes = tempData.sort((a, b) => {
|
||||
return new Date(b.time).getTime() - new Date(a.time).getTime()
|
||||
})
|
||||
const tempNewRes = []
|
||||
for (const i in tempRes) {
|
||||
// 说明已经到头了
|
||||
// 判断当前是不是待修模状态
|
||||
const tempv1 = tempRes[i]
|
||||
const tempv2 = tempRes[parseInt(i) + 1]
|
||||
if (tempv1?.status === 5000) {
|
||||
// 判断上下两个状态是否为待修模,并且订单id 是一样的,这种情况是不科学的,前端先手动过滤,后续找到真实原因
|
||||
if (
|
||||
tempv2?.status === 5000
|
||||
&& tempv2?.order_id === tempv1?.order_id
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
const msg = tempRes[i]
|
||||
if (msg.msg.includes('已称完净重') && msg.msg.includes('等待打包')) {
|
||||
const pattern = /已称完净重\(([\d\.?]+)g\),等待打包/
|
||||
const matches = msg.msg.match(pattern)
|
||||
|
||||
if (matches)
|
||||
msg.msg = `${'已称完净重'}(${matches[1]}g),${'等待打包'}`
|
||||
}
|
||||
|
||||
tempNewRes.push(msg)
|
||||
}
|
||||
|
||||
activities.value = tempNewRes
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-steps direction="vertical" :active="0">
|
||||
<OrderTrackItem v-for="(activity, index) in activities" :key="index" :activity="activity" />
|
||||
</van-steps>
|
||||
<Loading :loading="loading" />
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -0,0 +1,170 @@
|
||||
<script lang="tsx" setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { Ref } from 'vue'
|
||||
import { modelSize as _modelSize, printType } from './utils'
|
||||
import { printOrderInfo as printOrderInfoApi } from '@/api/short_url'
|
||||
|
||||
import { filterMsgButton } from '@/dict/status_dict'
|
||||
|
||||
const code = ref('')
|
||||
const src = ref('')
|
||||
const data: Ref<any> = ref({})
|
||||
const tags = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
const modelSize = _modelSize
|
||||
|
||||
const route = useRoute()
|
||||
onMounted(() => {
|
||||
code.value = route.query.code as string
|
||||
getInfo()
|
||||
})
|
||||
|
||||
function getImage() {
|
||||
src.value = ''
|
||||
if (data.value.info && data.value.info.texture_cover_img)
|
||||
src.value = `https://3dview.suwa3d.com/${data.value.info.texture_cover_img}`
|
||||
}
|
||||
|
||||
function getTags() {
|
||||
// 判断是否有订单信息
|
||||
if (!data.value.info || !data.value.info.pid)
|
||||
return
|
||||
|
||||
// 遍历循环
|
||||
const arrTags = [];
|
||||
// 数据信息遍历
|
||||
[data.value].forEach((item: any) => {
|
||||
const arrTag = []
|
||||
// 加急单
|
||||
if (item.is_expedited) {
|
||||
// 插入数据
|
||||
arrTag.push('加急')
|
||||
}
|
||||
|
||||
// 超时单
|
||||
if (item.is_expires)
|
||||
arrTag.push('超时')
|
||||
|
||||
const msg = printType(item.info.print_type)
|
||||
if (!!msg && msg !== '正常')
|
||||
arrTag.push(msg)
|
||||
|
||||
arrTags.push(arrTag)
|
||||
})
|
||||
tags.value = arrTags
|
||||
}
|
||||
|
||||
function isSample() {
|
||||
return data.value.order_tag_type === 'sample'
|
||||
}
|
||||
|
||||
function getPrintTypeText() {
|
||||
switch (data.value?.info?.print_type) {
|
||||
case 1:
|
||||
return '首次打印'
|
||||
case 2:
|
||||
return '重打'
|
||||
case 3:
|
||||
return '加打'
|
||||
}
|
||||
}
|
||||
|
||||
function getStatusText() {
|
||||
return filterMsgButton(data.value?.info?.status, 'text')
|
||||
}
|
||||
|
||||
function getInfo() {
|
||||
loading.value = true
|
||||
printOrderInfoApi(code.value).then((res: any) => {
|
||||
data.value = res || {}
|
||||
getImage()
|
||||
getTags()
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="拍照订单">
|
||||
<span>
|
||||
{{ data?.info?.pid }}
|
||||
</span>
|
||||
</van-cell>
|
||||
<van-cell title="尺寸*数量">
|
||||
<van-tag v-for="(item, key) in modelSize(data?.info?.model_size)" :key="key" type="success" plain>
|
||||
{{ item }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
<van-cell title="提交建模时间" :value="data.submit_model_time" />
|
||||
<van-cell title="订单状态">
|
||||
<van-tag type="success">
|
||||
{{ loading ? '' : getStatusText() }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
<van-cell title="打印类型">
|
||||
<van-tag v-if="isSample()" type="success">
|
||||
样品
|
||||
</van-tag>
|
||||
<van-tag type="success">
|
||||
{{ getPrintTypeText() }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title=" ">
|
||||
<van-cell title="商品金额">
|
||||
<span>{{ data.goods_amount / 100 }} {{ data.currency }}</span>
|
||||
</van-cell>
|
||||
<van-cell v-if="data.other_fee_amount > 0 && data.other_fee_name" :title="`优惠金额(${data.other_fee_name})`">
|
||||
<span>{{ data.other_fee_amount / 100 }} {{ data.currency }}</span>
|
||||
</van-cell>
|
||||
<van-cell title="总计">
|
||||
<span>{{ data.total_amount / 100 }} {{ data.currency }}</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="门店客户信息">
|
||||
<van-cell title="门店" :value="data?.info?.shop_name" />
|
||||
<van-cell title="客户">
|
||||
{{ data?.info?.customer_name }} (TEL:{{ data?.info?.customer_mobile }})
|
||||
</van-cell>
|
||||
<van-cell title="寄送地址">
|
||||
<span>
|
||||
{{ data?.info?.province_name }}
|
||||
{{ data?.info?.city_name }}
|
||||
{{ data?.info?.country_name }}
|
||||
{{ data?.info?.address }}
|
||||
</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="重量">
|
||||
<van-cell title="毛重">
|
||||
<span>{{ data?.info?.model_gross_weight }}g</span>
|
||||
</van-cell>
|
||||
<van-cell title="净重">
|
||||
<span>{{ data?.info?.model_weight }}g</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group v-if="data.motherList && data.motherList.length > 0" title="其他">
|
||||
<van-cell title="子母单">
|
||||
<van-tag
|
||||
v-for="(item, key) in data.motherList" :key="key" type="success"
|
||||
class="mother-tag"
|
||||
plain
|
||||
>
|
||||
{{ item.pid }}
|
||||
</van-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<Loading :loading="loading" />
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.mother-tag{
|
||||
margin-right: 0.4rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,34 @@
|
||||
export function printType(val: number) {
|
||||
let type = ''
|
||||
switch (val) {
|
||||
case 1:
|
||||
type = '正常打印'
|
||||
break
|
||||
case 2:
|
||||
type = '重打'
|
||||
break
|
||||
case 3:
|
||||
type = '加打'
|
||||
break
|
||||
case 4:
|
||||
type = '样品'
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
return type
|
||||
}
|
||||
|
||||
export function modelSize(val: string) {
|
||||
if (!val)
|
||||
return ''
|
||||
|
||||
// 分割字符串
|
||||
const arrV = val.split('__')
|
||||
const data = []
|
||||
arrV.forEach((item) => {
|
||||
const temp = item.replace(/_x/g, '*').replace(/_/g, '')
|
||||
data.push(temp)
|
||||
})
|
||||
return data
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
<template>
|
||||
<van-popup v-model:show="actionShow" round position="bottom">
|
||||
<van-picker
|
||||
:columns="actions"
|
||||
@cancel="actionShow = false"
|
||||
@confirm="onSelect"
|
||||
/>
|
||||
</van-popup>
|
||||
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" safe-area-inset-top/>
|
||||
<div class="personalContainer">
|
||||
<div class="user-section">
|
||||
<div class="user-info-box" @click="toPerson">
|
||||
<div class="portrait-box">
|
||||
<img
|
||||
class="portrait"
|
||||
:src="headimgUrl"
|
||||
/>
|
||||
</div>
|
||||
<div class="info-box" v-if="userInfo">
|
||||
<div class="username">{{ nickname }}</div>
|
||||
<van-icon class="arrow" name="arrow" size="18px" color="#767676" />
|
||||
</div>
|
||||
<div class="info-box" v-else>
|
||||
<div @click="login" class="username">{{'请登录'.$t}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div v-if="shootPerms" class="my_item" @click="takephoto" data-method="2">
|
||||
<div class="item_wrap">
|
||||
拍照
|
||||
<div class="right_arrow" ></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my_item" @click="login" data-method="2">
|
||||
<div class="item_wrap">
|
||||
领取订单
|
||||
<div class="right_arrow" ></div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <div class="my_item" @click="toAddress" data-method="1">
|
||||
<div class="item_wrap">
|
||||
我的地址
|
||||
<div class="right_arrow" ></div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <div class="my_item">
|
||||
<div class="item_wrap">
|
||||
<button class="feedback" open-type="feedback">反馈意见</button>
|
||||
<div class="right_arrow" ></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my_item">
|
||||
<div class="item_wrap">
|
||||
<button class="feedback" open-type="contact">在线客服</button>
|
||||
<div class="right_arrow" ></div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <div class="my_item" @click="toAbout">
|
||||
<van-field
|
||||
is-link
|
||||
readonly
|
||||
:label="'关于我们'.$t"
|
||||
/>
|
||||
</div> -->
|
||||
<div class="my_item" @click="languageChange">
|
||||
<van-field
|
||||
v-model="fieldValue"
|
||||
is-link
|
||||
readonly
|
||||
:label="'语言'.$t"
|
||||
/>
|
||||
</div>
|
||||
<div class="version">
|
||||
<div class="version_wrap">
|
||||
<div>v1.0.0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Tabbar></Tabbar>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useTranslation } from "i18next-vue";
|
||||
// import { showFailToast, showToast, FormInstance } from 'vant'
|
||||
import { localStorage } from '@/utils/local-storage'
|
||||
import {useStore} from '@/stores'
|
||||
import { useTokenStore } from '@/stores/token'
|
||||
import {headimgurl, nickname as fNickname} from './utils';
|
||||
|
||||
import {set as setLang} from '@/lang/i18n';
|
||||
import {toValueWithout} from '@/lang/utils';
|
||||
|
||||
const { i18next } = useTranslation();
|
||||
|
||||
// const { t, locale } = useI18n();
|
||||
const userInfo = ref({})
|
||||
const store = useStore();
|
||||
const tokenStore = useTokenStore();
|
||||
const {isWechat} = tokenStore;
|
||||
const showAvaModal = ref(false)
|
||||
const version = ref('')
|
||||
const fieldValue = ref('简体中文');
|
||||
const actionShow = ref(false);
|
||||
|
||||
const actions = ref([
|
||||
{
|
||||
id: 1,
|
||||
value: "zh-CN",
|
||||
text: "简体中文".$t,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
value: "en",
|
||||
text: '英文'.$t,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
value: "zh-TW",
|
||||
text: '繁体中文'.$t,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
value: "ko",
|
||||
text: '韩文'.$t,
|
||||
},
|
||||
]);
|
||||
|
||||
const nickname = computed(() => {
|
||||
return fNickname();
|
||||
});
|
||||
|
||||
const initLang = actions.value.find((e: any) => e.value == i18next.language) || actions.value[0];
|
||||
fieldValue.value = initLang?.text;
|
||||
|
||||
const shootPerms = ref(false)
|
||||
const router = useRouter()
|
||||
|
||||
const headimgUrl = computed(() => {
|
||||
return headimgurl();
|
||||
});
|
||||
|
||||
onMounted(()=> {
|
||||
userInfo.value = tokenStore.userInfo;
|
||||
shootPerms.value = tokenStore.userInfo.shootPerms;
|
||||
// const accountInfo = wx.getAccountInfoSync();
|
||||
// this.setData({ version: accountInfo.miniProgram.version || accountInfo.miniProgram.envVersion })
|
||||
|
||||
// this.setData({
|
||||
// userInfo: userInfo,
|
||||
// shootPerms: userInfo?.shootPerms == true,
|
||||
// })
|
||||
})
|
||||
|
||||
// 更多点击
|
||||
const languageChange = () => {
|
||||
actionShow.value = !actionShow.value
|
||||
}
|
||||
|
||||
// 选择语言
|
||||
const onSelect = ({selectedOptions}) => {
|
||||
const lang = selectedOptions[0].value;
|
||||
// locale.value = selectedOptions[0].value;
|
||||
localStorage.set("i18nextLng", lang);
|
||||
actionShow.value = false;
|
||||
fieldValue.value = selectedOptions[0].text
|
||||
console.log("fieldValue.value", fieldValue.value)
|
||||
// 更新标题语言
|
||||
setLang(lang).then((data) => {
|
||||
console.log('switch lang succeed', data)
|
||||
store.updateTitle("个人中心".$t)
|
||||
}).catch((e) => {
|
||||
console.log('switch lang faield', e);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
const login = (e) => {
|
||||
// 登录
|
||||
// WxLogin(this)
|
||||
// if (!IsLogin()) {
|
||||
// this.setData({
|
||||
// shootPerms: false
|
||||
// });
|
||||
|
||||
// wx.navigateTo({
|
||||
// url: '/pages/login/login',
|
||||
// })
|
||||
// return
|
||||
// } else {
|
||||
// let method = e.currentTarget.dataset.method;
|
||||
// if (method == 1) {
|
||||
// wx.navigateTo({
|
||||
// url: "/packageAddress/pages/address/address?select=true"
|
||||
// })
|
||||
// } else if (method == 2) {
|
||||
// wx.navigateTo({
|
||||
// url: "/pages/receive/receive"
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// 测试
|
||||
const takephoto = () => {
|
||||
// router.push({
|
||||
// path: "/packageTakePhoto/pages/takePhoto/takePhoto"
|
||||
// })
|
||||
}
|
||||
// 跳转到个人资料页
|
||||
const toPerson = () => {
|
||||
// if (IsLogin()) {
|
||||
router.push({
|
||||
path: '/person'
|
||||
})
|
||||
// } else {
|
||||
// showToast("请先登录");
|
||||
// setTimeout(() => {
|
||||
// router.push({
|
||||
// path: '/pages/login/login',
|
||||
// })
|
||||
// }, 1500)
|
||||
// return
|
||||
// }
|
||||
}
|
||||
|
||||
const toAddress = () => {
|
||||
router.push({
|
||||
path: '/address'
|
||||
})
|
||||
}
|
||||
|
||||
const toAbout = () => {
|
||||
router.push({
|
||||
path: "/about"
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
/* height: 100%; */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
/* padding: 200px 0; */
|
||||
box-sizing: border-box;
|
||||
background-color: rgba(245, 245, 245, 1.000000);
|
||||
padding: 50px 0;
|
||||
}
|
||||
|
||||
.feedback {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
||||
.userinfo {
|
||||
display: flex;
|
||||
/* flex-direction: column;
|
||||
align-items: center; */
|
||||
}
|
||||
|
||||
|
||||
.personalContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(245, 245, 245, 1.000000);
|
||||
}
|
||||
|
||||
.personalContainer .user-section {
|
||||
height: 150px;
|
||||
position: relative;
|
||||
padding: 50px 15px 0;
|
||||
}
|
||||
|
||||
.user-info-box {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
.portrait {
|
||||
width: 65px;
|
||||
height: 65px;
|
||||
border: 2.5px solid #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.username {
|
||||
font-size: 20px;
|
||||
color: #333333;
|
||||
margin-left: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.info-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.arrow {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.right_arrow {
|
||||
border: solid gray;
|
||||
border-width: 0 3px 3px 0;
|
||||
padding: 3px;
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.my_item {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
background: #ffffff;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid gainsboro;
|
||||
.item_wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
.my_item button{line-height: 1.1;}
|
||||
.my_item button::after{display: none;}
|
||||
|
||||
.button {
|
||||
width: 100%;
|
||||
background: white;
|
||||
border: none;
|
||||
text-align: left;
|
||||
padding: 0px;
|
||||
margin: 0 !important;
|
||||
line-height: 1.3;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.button::after {
|
||||
border: none;
|
||||
border-radius: 0
|
||||
}
|
||||
|
||||
.version {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
color: #606266;
|
||||
background: #ffffff;
|
||||
.version_wrap {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" left-text="返回" left-arrow
|
||||
@click-left="returnClick" safe-area-inset-top/>
|
||||
<div class="page">
|
||||
<van-dialog
|
||||
:title="'确认退出登录?'.$t"
|
||||
v-model:show="dialogShow"
|
||||
:confirmButtonText="'确认退出'.$t"
|
||||
:cancelButtonText="'我再想想'.$t"
|
||||
@confirm="onLogout"
|
||||
showCancelButton
|
||||
confirm-button-color="#AAAAAA"
|
||||
cancel-button-color="#009944"
|
||||
round
|
||||
/>
|
||||
<div class="container">
|
||||
<div class="person-box">
|
||||
<div class="column">
|
||||
<div class="text">{{'头像'.$t}}</div>
|
||||
<div class="avatar-box">
|
||||
<img :src="headimgUrl" class="avatar"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="text">{{'账号'.$t}}</div>
|
||||
<div class="nickname">{{ nickname }}</div>
|
||||
<!-- <div class="input_box">
|
||||
<input type="nickname" class="nickname" :value="userInfo.nickname"/>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <div class="column">
|
||||
<div class="text">{{'性别'.$t}}</div>
|
||||
<div class="sex">{{sex}}</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="logout">
|
||||
<div class="logout-btn" @click="showLogout">{{'退出登录'.$t}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStore } from '@/stores';
|
||||
import { useTokenStore } from '@/stores/token';
|
||||
import { closeToast, showLoadingToast, showToast } from 'vant';
|
||||
import {headimgurl, logout, nickname as fNickname} from './utils';
|
||||
|
||||
const store = useStore()
|
||||
const tokenStore = useTokenStore()
|
||||
const router = useRouter()
|
||||
const {isWechat} = tokenStore;
|
||||
|
||||
const userInfo = ref("")
|
||||
const dialogShow = ref(false)
|
||||
const sex = ref("")
|
||||
|
||||
const headimgUrl = computed(() => {
|
||||
return headimgurl();
|
||||
});
|
||||
|
||||
const nickname = computed(() => {
|
||||
return fNickname();
|
||||
})
|
||||
|
||||
onMounted(()=> {
|
||||
userInfo.value = tokenStore.userInfo;
|
||||
let sexId = userInfo.value.sex;
|
||||
switch(sexId) {
|
||||
case 1: sex.value = "男";break;
|
||||
case 2: sex.value = "女";break;
|
||||
default: sex.value = "未知";break;
|
||||
}
|
||||
})
|
||||
|
||||
const returnClick = () => history.back();
|
||||
// 点击是否要退出登录
|
||||
const showLogout = () => {
|
||||
dialogShow.value = true
|
||||
}
|
||||
// 退出登录
|
||||
const onLogout = () => {
|
||||
showLoadingToast({message: "退出登录中...".$t, forbidClick: true,});
|
||||
setTimeout(()=> {
|
||||
// TODO: 退出社会化登录
|
||||
tokenStore.logout();
|
||||
logout();
|
||||
// wx.removeStorage({
|
||||
// key: 'authorization',
|
||||
// })
|
||||
router.push({
|
||||
path: '/myOrder',
|
||||
})
|
||||
closeToast();
|
||||
}, 1500)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
background-color: #F5F5F5;
|
||||
/* 利用新增的 env() 和 constant() 特性,自动计算底部安全距离 */
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
/* 可计算 */
|
||||
// padding-bottom: calc(124px + env(safe-area-inset-bottom));
|
||||
}
|
||||
.container {
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
height: auto;
|
||||
.person-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 345px;
|
||||
height: 175px;
|
||||
margin: 0 auto;
|
||||
padding: 12px 0;
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
.column {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
padding: 9px 16px;
|
||||
box-sizing: border-box;
|
||||
.text {
|
||||
color: #767676;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
}
|
||||
.avatar-box {
|
||||
position: relative;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
.avatar {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.input_box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 90px;
|
||||
.nickname {
|
||||
text-align: right;
|
||||
appearance: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.logout {
|
||||
position: absolute;
|
||||
bottom: 0%;
|
||||
left: 50%;
|
||||
width: 345px;
|
||||
height: 192px;
|
||||
margin-left: -172.5px;
|
||||
.logout-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
background: #ffffff;
|
||||
color: #F56C6C;
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN-Regular;
|
||||
font-weight: 400;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,34 @@
|
||||
import defaultHeadimgUrl from '@/assets/common/avatar.png'
|
||||
import { useTokenStore } from '@/stores/token'
|
||||
import hello from 'hellojs'
|
||||
|
||||
export function headimgurl() {
|
||||
const tokenStore = useTokenStore();
|
||||
const user = tokenStore.userInfo;
|
||||
if (user?.headimgurl) {
|
||||
return user?.headimgurl;
|
||||
}
|
||||
return defaultHeadimgUrl;
|
||||
}
|
||||
|
||||
export function nickname() {
|
||||
const tokenStore = useTokenStore();
|
||||
const user = tokenStore.userInfo;
|
||||
console.log("tokenStore.userInfo", tokenStore.userInfo)
|
||||
if (user.nickname) {
|
||||
return user.nickname;
|
||||
} else {
|
||||
return user.social_type + user.id;
|
||||
}
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
const tokenStore = useTokenStore();
|
||||
const user = tokenStore.userInfo;
|
||||
const socialType = user.social_type;
|
||||
if (!socialType) {
|
||||
return Promise.reject('未知的登录方式');
|
||||
}
|
||||
|
||||
return hello(socialType).logout();
|
||||
}
|
||||
Reference in new issue
Block a user