consume.vue
7.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<template>
<view class="page-shell booking-consume-page">
<view class="page-blur"></view>
<view class="page-blur-secondary"></view>
<view class="page-blur-tertiary"></view>
<view class="page-content subpage-content">
<view class="subpage-nav">
<view class="subpage-back" @tap="goBack">‹</view>
<view class="subpage-title-wrap">
<text class="subpage-title">{{ consumePageTitle }}</text>
<text class="subpage-subtitle">{{ consumePageSubtitle }}</text>
</view>
</view>
<view class="subpage-hero glass-card">
<text class="hero-kicker">{{ consumeStatus }}</text>
<text class="hero-title">{{ booking.store }}</text>
<text class="hero-desc">{{ booking.date }} · {{ booking.displayTime || booking.time }}</text>
</view>
<view class="subpage-card">
<view class="section-head">
<text class="section-title">确认流程</text>
<text class="section-link">到店安排</text>
</view>
<view class="flow-list">
<view v-for="(item, index) in flowSteps" :key="item.title" class="flow-item">
<view class="flow-mark" :class="{ active: item.active, pending: !item.active }">{{ index + 1 }}</view>
<view class="flow-copy">
<text class="flow-title">{{ item.title }}</text>
<text class="flow-desc">{{ item.desc }}</text>
</view>
</view>
</view>
</view>
<view class="subpage-card">
<view class="info-list">
<view class="info-row">
<text class="info-label">预约编号</text>
<text class="info-value">LQBK{{ booking.id || 'TEMP' }}</text>
</view>
<view class="info-row">
<text class="info-label">电话确认</text>
<text class="info-value">{{ booking.confirmState || '门店稍后联系' }}</text>
</view>
<view class="info-row">
<text class="info-label">护理品项</text>
<text class="info-value">{{ itemText }}</text>
</view>
<view class="info-row">
<text class="info-label">护理房间</text>
<text class="info-value">{{ consume ? consume.room : '到店确认' }}</text>
</view>
<view class="info-row">
<text class="info-label">健康师</text>
<text class="info-value">{{ consume ? consume.therapist : '电话确认后安排' }}</text>
</view>
</view>
</view>
<view class="subpage-card">
<view class="soft-panel">
<text class="panel-title">门店说明</text>
<text class="panel-desc">{{ noteText }}</text>
<text class="panel-desc sub">{{ onsiteText }}</text>
</view>
</view>
<view class="cta-row">
<view class="secondary-button" @tap="goRecord">查看预约</view>
<view class="primary-button" @tap="contactStore">联系门店</view>
</view>
</view>
</view>
</template>
<script>
import { findRecordById, findConsumeByRecordId } from '@/data/mock'
export default {
data() {
return {
booking: {
id: 'TEMP',
store: '绿纤大源店',
date: '今天 03/19',
time: '14:00',
displayTime: '14:00 到店',
confirmState: '门店稍后电话联系'
},
consume: null
}
},
computed: {
consumePageTitle() {
return this.consume ? '护理安排' : '确认进度'
},
consumePageSubtitle() {
return this.consume ? '电话确认后的到店安排,会在这里慢慢补充完整' : '预约已提交,门店电话确认后将生成护理安排'
},
consumeStatus() {
return this.consume ? this.consume.status : '待门店联系'
},
itemText() {
return this.consume && this.consume.itemList.length ? this.consume.itemList.join(' / ') : '电话确认后补充'
},
noteText() {
return this.consume ? this.consume.managerNote : '预约提交后,门店会先与你电话确认,再为你补充本次到店安排。'
},
onsiteText() {
return this.consume ? this.consume.onsiteConfirm : '如有房间、健康师或护理细节暂未确认,会在电话沟通或到店后再完成补充。'
},
flowSteps() {
const hasConsume = !!this.consume
return [
{ title: '提交预约', desc: '你的到店需求已经妥帖送达门店', active: true },
{ title: '门店电话联系', desc: hasConsume ? '门店已完成预约电话确认' : '门店将按预约顺序联系你确认', active: hasConsume },
{ title: '补充护理安排', desc: hasConsume ? '护理内容、房间与健康师已补充完成' : '确认后由后台创建护理安排', active: hasConsume },
{ title: '到店再做微调', desc: '部分细节可根据现场状态由门店再确认', active: true }
]
}
},
onLoad(options) {
if (options.recordId) {
this.booking = findRecordById(options.recordId)
this.consume = findConsumeByRecordId(options.recordId)
return
}
this.booking = {
id: 'TEMP',
store: options.store ? decodeURIComponent(options.store) : this.booking.store,
date: options.date ? decodeURIComponent(options.date) : this.booking.date,
time: options.time ? decodeURIComponent(options.time) : this.booking.time,
displayTime: options.time ? `${decodeURIComponent(options.time)} 到店` : this.booking.displayTime,
confirmState: '门店稍后电话联系'
}
},
methods: {
goBack() {
uni.navigateBack({ fail: () => uni.redirectTo({ url: '/packageBooking/record/record' }) })
},
goRecord() {
if (this.booking.id && this.booking.id !== 'TEMP') {
uni.redirectTo({ url: `/packageBooking/detail/detail?id=${this.booking.id}` })
return
}
uni.redirectTo({ url: '/packageBooking/record/record' })
},
contactStore() {
uni.showToast({ title: '门店会按预约顺序尽快联系你', icon: 'none' })
}
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/mixins.scss';
@import '@/styles/subpage.scss';
.flow-item {
display: flex;
align-items: flex-start;
padding: 16rpx 0;
animation: lfRevealUp 760ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.flow-item:nth-child(1) { animation-delay: 0.08s; }
.flow-item:nth-child(2) { animation-delay: 0.16s; }
.flow-item:nth-child(3) { animation-delay: 0.24s; }
.flow-item:nth-child(4) { animation-delay: 0.32s; }
.flow-mark {
width: 44rpx;
height: 44rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
font-weight: 700;
color: #fff;
background: $brand-primary-deep;
flex-shrink: 0;
animation: lfPulseSoft 4.8s ease-in-out infinite;
}
.flow-mark.pending {
color: $text-secondary;
background: rgba(210, 191, 156, 0.16);
animation: none;
}
.flow-copy {
flex: 1;
margin-left: 18rpx;
}
.flow-title,
.flow-desc,
.panel-title,
.panel-desc {
display: block;
}
.flow-title,
.panel-title {
font-size: 28rpx;
font-weight: 600;
color: $text-primary;
}
.flow-desc,
.panel-desc {
margin-top: 8rpx;
font-size: 24rpx;
line-height: 1.8;
color: $text-secondary;
}
.panel-desc.sub {
margin-top: 14rpx;
}
</style>