初始化
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="card filters">
|
||||
<view class="row between">
|
||||
<view class="title">消费记录</view>
|
||||
<view class="row">
|
||||
<view class="chip2" :class="{ on: range === 7 }" @tap="setRange(7)">近7天</view>
|
||||
<view class="chip2" :class="{ on: range === 30 }" @tap="setRange(30)">近30天</view>
|
||||
<view class="chip2" :class="{ on: range === 0 }" @tap="setRange(0)">全部</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="!viewList || !viewList.length" class="card empty">
|
||||
<view class="btn btn-primary ebtn" @tap="goProjects">去看看项目</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="list">
|
||||
<view v-for="o in viewList" :key="o.id" class="card item" @tap="open(o.id)">
|
||||
<view class="row between">
|
||||
<view class="n">{{ o.projectName }}</view>
|
||||
<view
|
||||
class="st"
|
||||
:class="{
|
||||
w: o.status === '待付款',
|
||||
g: o.status === '已完成',
|
||||
d: o.status === '已取消',
|
||||
p: o.status !== '待付款' && o.status !== '已完成' && o.status !== '已取消'
|
||||
}"
|
||||
>
|
||||
{{ o.status }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="row between meta">
|
||||
<view class="muted">{{ o.orderType === 'booking' ? '预约' : '购买' }}</view>
|
||||
<view class="amt">¥{{ o.amount }}</view>
|
||||
</view>
|
||||
<view class="muted meta2">{{ fmt(o.createdAt) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<AiFloat />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AiFloat from '@/components/AiFloat.vue'
|
||||
import { demoOrders } from '@/common/demoOrders'
|
||||
|
||||
function tsToText(ts) {
|
||||
const d = new Date(ts)
|
||||
const y = d.getFullYear()
|
||||
const m = `${d.getMonth() + 1}`.padStart(2, '0')
|
||||
const dd = `${d.getDate()}`.padStart(2, '0')
|
||||
const hh = `${d.getHours()}`.padStart(2, '0')
|
||||
const mm = `${d.getMinutes()}`.padStart(2, '0')
|
||||
return `${y}-${m}-${dd} ${hh}:${mm}`
|
||||
}
|
||||
|
||||
function buildOrders() {
|
||||
const now = Date.now()
|
||||
const extra = [
|
||||
{
|
||||
id: 'rc_demo_001',
|
||||
createdAt: now - 2 * 60 * 60 * 1000,
|
||||
status: '已完成',
|
||||
amount: 99,
|
||||
projectId: 'p1',
|
||||
projectName: '水氧净透体验',
|
||||
durationMin: 60,
|
||||
orderType: 'booking',
|
||||
appointmentDate: '2026-06-21',
|
||||
appointmentSlot: '12:30',
|
||||
technicianName: '系统分配',
|
||||
note: '',
|
||||
verifyCode: 'VCRC20260621001'
|
||||
},
|
||||
{
|
||||
id: 'rc_demo_002',
|
||||
createdAt: now - 20 * 60 * 60 * 1000,
|
||||
status: '已完成',
|
||||
amount: 168,
|
||||
projectId: 'p2',
|
||||
projectName: '深层清洁黑头管理',
|
||||
durationMin: 75,
|
||||
orderType: 'coupon',
|
||||
couponTitle: '深层清洁黑头管理',
|
||||
couponPlanKey: 'single',
|
||||
couponPlanLabel: '单次券',
|
||||
validText: '有效期 30 天',
|
||||
remainingTimes: 0,
|
||||
verifyCode: 'VCRC20260621002'
|
||||
},
|
||||
{
|
||||
id: 'rc_demo_003',
|
||||
createdAt: now - 5 * 24 * 60 * 60 * 1000,
|
||||
status: '已取消',
|
||||
amount: 238,
|
||||
projectId: 'p3',
|
||||
projectName: '补水修护屏障护理',
|
||||
durationMin: 80,
|
||||
orderType: 'booking',
|
||||
appointmentDate: '2026-06-18',
|
||||
appointmentSlot: '15:00',
|
||||
technicianName: '许言',
|
||||
note: '',
|
||||
verifyCode: 'VCRC20260621003'
|
||||
},
|
||||
{
|
||||
id: 'rc_demo_004',
|
||||
createdAt: now - 12 * 24 * 60 * 60 * 1000,
|
||||
status: '已完成',
|
||||
amount: 899,
|
||||
projectId: 'p5',
|
||||
projectName: '皮肤管理次卡 5 次',
|
||||
durationMin: 60,
|
||||
orderType: 'coupon',
|
||||
couponTitle: '皮肤管理次卡 5 次',
|
||||
couponPlanKey: 'times5',
|
||||
couponPlanLabel: '次卡 5 次',
|
||||
validText: '有效期 180 天',
|
||||
remainingTimes: 4,
|
||||
verifyCode: 'VCRC20260621004'
|
||||
},
|
||||
{
|
||||
id: 'rc_demo_005',
|
||||
createdAt: now - 35 * 24 * 60 * 60 * 1000,
|
||||
status: '已完成',
|
||||
amount: 188,
|
||||
projectId: 'p4',
|
||||
projectName: '肩颈舒缓筋膜放松',
|
||||
durationMin: 60,
|
||||
orderType: 'booking',
|
||||
appointmentDate: '2026-05-17',
|
||||
appointmentSlot: '19:00',
|
||||
technicianName: '周晴',
|
||||
note: '',
|
||||
verifyCode: 'VCRC20260621005'
|
||||
},
|
||||
{
|
||||
id: 'rc_demo_006',
|
||||
createdAt: now - 62 * 24 * 60 * 60 * 1000,
|
||||
status: '已完成',
|
||||
amount: 299,
|
||||
projectId: 'p9',
|
||||
projectName: '新客体验套餐 · 3 次',
|
||||
durationMin: 60,
|
||||
orderType: 'coupon',
|
||||
couponTitle: '新客体验套餐 · 3 次',
|
||||
couponPlanKey: 'package',
|
||||
couponPlanLabel: '套餐',
|
||||
validText: '有效期 90 天',
|
||||
remainingTimes: 2,
|
||||
verifyCode: 'VCRC20260621006'
|
||||
}
|
||||
]
|
||||
|
||||
return [...demoOrders, ...extra].slice().sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0))
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { AiFloat },
|
||||
data() {
|
||||
return {
|
||||
range: 30,
|
||||
orders: buildOrders(),
|
||||
viewList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.apply()
|
||||
},
|
||||
onShow() {
|
||||
this.orders = buildOrders()
|
||||
this.apply()
|
||||
},
|
||||
methods: {
|
||||
apply() {
|
||||
if (this.range === 0) {
|
||||
this.viewList = this.orders && this.orders.length ? this.orders : []
|
||||
return
|
||||
}
|
||||
const from = Date.now() - this.range * 24 * 60 * 60 * 1000
|
||||
this.viewList = this.orders.filter((x) => (x.createdAt || 0) >= from)
|
||||
if (!this.viewList || !this.viewList.length) this.viewList = this.orders.slice(0, 6)
|
||||
},
|
||||
setRange(n) {
|
||||
this.range = n
|
||||
this.apply()
|
||||
},
|
||||
open(id) {
|
||||
const o = this.orders.find((x) => x.id === id) || this.orders[0]
|
||||
const payload = encodeURIComponent(JSON.stringify(o))
|
||||
uni.navigateTo({ url: `/pages/orders/detail?payload=${payload}` })
|
||||
},
|
||||
goProjects() {
|
||||
uni.switchTab({ url: '/pages/projects/list' })
|
||||
},
|
||||
fmt(ts) {
|
||||
return ts ? tsToText(ts) : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.filters {
|
||||
padding: 18rpx;
|
||||
}
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 950;
|
||||
}
|
||||
.chip2 {
|
||||
padding: 10rpx 14rpx;
|
||||
margin-left: 10rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 24rpx;
|
||||
background: rgba(17, 24, 39, 0.06);
|
||||
color: #111827;
|
||||
}
|
||||
.on {
|
||||
background: rgba(59, 130, 246, 0.14);
|
||||
color: #1d4ed8;
|
||||
}
|
||||
.empty {
|
||||
margin-top: 18rpx;
|
||||
padding: 26rpx;
|
||||
}
|
||||
.e1 {
|
||||
font-size: 36rpx;
|
||||
font-weight: 950;
|
||||
}
|
||||
.e2 {
|
||||
margin-top: 10rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.ebtn {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
.list {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
.item {
|
||||
padding: 22rpx;
|
||||
margin-bottom: 18rpx;
|
||||
}
|
||||
.n {
|
||||
font-size: 32rpx;
|
||||
font-weight: 950;
|
||||
max-width: 520rpx;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.meta {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
.amt {
|
||||
font-weight: 950;
|
||||
}
|
||||
.meta2 {
|
||||
margin-top: 10rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user