初始化

This commit is contained in:
leiking
2026-06-29 10:54:33 +08:00
parent 761cee968e
commit 4983006317
156 changed files with 25687 additions and 0 deletions
+255
View File
@@ -0,0 +1,255 @@
<template>
<view class="container">
<view class="card head">
<view class="row between">
<view
class="st"
:class="{
w: o.status === '待付款',
g: o.status === '已完成',
d: o.status === '已取消',
p: o.status !== '待付款' && o.status !== '已完成' && o.status !== '已取消'
}"
>
{{ o.status }}
</view>
<view class="muted">订单号 {{ o.id }}</view>
</view>
<view class="name">{{ o.projectName }}</view>
<view class="muted meta">{{ typeLabel(o.orderType) }} · ¥{{ o.amount }}</view>
<view class="muted meta" v-if="o.orderType === 'booking'">
{{ o.appointmentDate }} {{ o.appointmentSlot }} · {{ o.technicianName }}
</view>
<view class="muted meta" v-else>剩余次数{{ o.remainingTimes }}</view>
</view>
<view class="card block">
<view class="title">核销码</view>
<view class="code row between">
<view class="c">{{ o.verifyCode }}</view>
<view class="tag" @tap="copy(o.verifyCode)">复制</view>
</view>
<view class="muted hint">到店出示核销码由门店扫码/输码核销此处为原型演示</view>
<view class="btn btn-ghost more" @tap="openCode">查看大码</view>
</view>
<view class="card block" v-if="o.note">
<view class="title">备注</view>
<view class="muted">{{ o.note }}</view>
</view>
<view class="actions">
<view v-if="o.status === '待付款'" class="btn btn-primary" @tap="pay">模拟支付</view>
<view v-if="o.status === '待核销'" class="btn btn-primary" @tap="verify">模拟核销</view>
<view v-if="o.orderType === 'booking' && o.status === '待核销'" class="btn btn-ghost" @tap="reschedule">改约</view>
<view v-if="o.status !== '已取消' && o.status !== '已完成'" class="btn btn-ghost" @tap="cancel">取消订单</view>
</view>
<AiFloat />
</view>
</template>
<script>
import AiFloat from '@/components/AiFloat.vue'
import { demoOrders } from '@/common/demoOrders'
function safeJsonParse(s) {
try {
return JSON.parse(s)
} catch (e) {
return null
}
}
const __DBG_URL = 'http://127.0.0.1:7777/event'
export default {
components: { AiFloat },
data() {
return {
order: null
}
},
onLoad(query) {
//#region debug-point orders-detail-load
try {
uni.request({
url: __DBG_URL,
method: 'POST',
timeout: 2000,
data: {
sessionId: 'orders-detail-blank',
runId: 'pre-fix',
hypothesisId: 'H2',
msg: 'orders/detail onLoad',
queryKeys: query ? Object.keys(query) : [],
payloadLen: query && query.payload ? String(query.payload).length : 0
}
})
} catch (e) {}
//#endregion debug-point orders-detail-load
const raw = query.payload ? safeJsonParse(decodeURIComponent(query.payload)) : null
if (raw) this.order = raw
},
computed: {
o() {
return this.order || demoOrders[0] || {}
}
},
onReady() {
//#region debug-point orders-detail-ready
try {
uni.request({
url: __DBG_URL,
method: 'POST',
timeout: 2000,
data: {
sessionId: 'orders-detail-blank',
runId: 'pre-fix',
hypothesisId: 'H2',
msg: 'orders/detail onReady',
hasOrder: !!this.order,
oKeys: this.o ? Object.keys(this.o) : []
}
})
} catch (e) {}
//#endregion debug-point orders-detail-ready
},
onError(err) {
//#region debug-point orders-detail-error
try {
uni.request({
url: __DBG_URL,
method: 'POST',
timeout: 2000,
data: {
sessionId: 'orders-detail-blank',
runId: 'pre-fix',
hypothesisId: 'H2',
msg: 'orders/detail onError',
err: String(err || '')
}
})
} catch (e) {}
//#endregion debug-point orders-detail-error
},
methods: {
typeLabel(t) {
return t === 'booking' ? '预约订单' : '购买卡券'
},
openCode() {
const payload = encodeURIComponent(JSON.stringify(this.o))
uni.navigateTo({ url: `/pages/verify/code?payload=${payload}` })
},
copy(text) {
uni.setClipboardData({ data: text })
},
pay() {
this.order = { ...this.o, status: '待核销', paidAt: Date.now() }
uni.showToast({ title: '支付成功(模拟)', icon: 'none' })
setTimeout(() => {
const payload = encodeURIComponent(JSON.stringify(this.o))
uni.navigateTo({ url: `/pages/verify/code?payload=${payload}` })
}, 200)
},
verify() {
if (this.o.orderType === 'coupon') {
const left = Math.max(0, (this.o.remainingTimes || 0) - 1)
this.order = { ...this.o, remainingTimes: left, status: left === 0 ? '已完成' : '待核销' }
uni.showToast({ title: left === 0 ? '已核销完成' : '核销成功,已扣次', icon: 'none' })
return
}
this.order = { ...this.o, status: '已完成', verifiedAt: Date.now() }
uni.showToast({ title: '已核销完成(模拟)', icon: 'none' })
},
reschedule() {
uni.navigateTo({ url: `/pages/booking/create?projectId=${this.o.projectId}` })
},
cancel() {
uni.showModal({
title: '确认取消',
content: '原型演示:取消后订单状态将变为已取消。',
success: (res) => {
if (!res.confirm) return
this.order = { ...this.o, status: '已取消', canceledAt: Date.now() }
}
})
},
goMember() {
uni.switchTab({ url: '/pages/member/index' })
}
}
}
</script>
<style lang="scss" scoped>
.head {
padding: 24rpx;
}
.st {
padding: 10rpx 14rpx;
border-radius: 999rpx;
font-size: 24rpx;
font-weight: 900;
}
.w {
background: rgba(245, 158, 11, 0.16);
color: #b45309;
}
.p {
background: rgba(59, 130, 246, 0.16);
color: #1d4ed8;
}
.g {
background: rgba(16, 185, 129, 0.16);
color: #047857;
}
.d {
background: rgba(239, 68, 68, 0.12);
color: #b91c1c;
}
.name {
margin-top: 14rpx;
font-size: 38rpx;
font-weight: 950;
}
.meta {
margin-top: 10rpx;
font-size: 26rpx;
}
.block {
padding: 22rpx;
margin-top: 18rpx;
}
.title {
font-weight: 950;
font-size: 30rpx;
margin-bottom: 14rpx;
}
.code {
padding: 16rpx;
border-radius: 18rpx;
background: rgba(17, 24, 39, 0.04);
border: 1rpx dashed rgba(17, 24, 39, 0.18);
}
.c {
font-size: 36rpx;
font-weight: 900;
letter-spacing: 1rpx;
}
.hint {
margin-top: 12rpx;
font-size: 24rpx;
}
.more {
margin-top: 16rpx;
}
.actions {
margin-top: 24rpx;
display: flex;
flex-direction: column;
gap: 16rpx;
}
</style>