190 lines
5.8 KiB
JavaScript
190 lines
5.8 KiB
JavaScript
const { request, ensureLogin, cents } = require('../../utils/api.js')
|
|
|
|
Page({
|
|
data: {
|
|
orderId: '',
|
|
loading: false,
|
|
errorMessage: '',
|
|
successMessage: '',
|
|
order: null,
|
|
history: [],
|
|
cancellation: null,
|
|
renewMinutes: 60,
|
|
changeRoomId: '',
|
|
shareTtlMinutes: 30,
|
|
shareToken: '',
|
|
sharePermissions: ['VIEW_ROOM', 'OPEN_DOOR'],
|
|
},
|
|
|
|
onLoad(options) {
|
|
this.setData({ orderId: options.orderId || '' })
|
|
if (options.orderId) this.loadOrder(options.orderId)
|
|
},
|
|
|
|
async loadOrder(orderId = this.data.orderId) {
|
|
const targetOrderId = typeof orderId === 'string' ? orderId : this.data.orderId
|
|
this.setData({ loading: true, errorMessage: '', successMessage: '' })
|
|
try {
|
|
await ensureLogin()
|
|
const [orderResponse, historyResponse] = await Promise.all([
|
|
request(`/orders/${encodeURIComponent(targetOrderId)}`),
|
|
request(`/orders/${encodeURIComponent(targetOrderId)}/history`),
|
|
])
|
|
this.setData({
|
|
order: formatOrder(orderResponse.data),
|
|
history: (historyResponse.data || []).map((item) => ({
|
|
...item,
|
|
createdText: formatTime(item.createdAt),
|
|
})),
|
|
})
|
|
} catch (error) {
|
|
this.setData({ errorMessage: error.message || '订单加载失败' })
|
|
} finally {
|
|
this.setData({ loading: false })
|
|
}
|
|
},
|
|
|
|
async loadCancellationQuote() {
|
|
if (!this.data.orderId) return
|
|
await this.withOrderRequest(async () => {
|
|
const response = await request(`/orders/${encodeURIComponent(this.data.orderId)}/cancellation-quote`)
|
|
this.setData({
|
|
cancellation: {
|
|
...response.data,
|
|
feeText: cents(response.data.feeCents),
|
|
refundableText: cents(response.data.refundableCents),
|
|
},
|
|
successMessage: '取消测算已更新',
|
|
})
|
|
})
|
|
},
|
|
|
|
async cancelOrder() {
|
|
if (!this.data.orderId) return
|
|
await this.withOrderRequest(async () => {
|
|
await request(`/orders/${encodeURIComponent(this.data.orderId)}/cancel`, {
|
|
method: 'POST',
|
|
data: { reason: '用户小程序取消' },
|
|
})
|
|
this.setData({ successMessage: '订单已提交取消' })
|
|
await this.loadOrder(this.data.orderId)
|
|
})
|
|
},
|
|
|
|
async openDoor() {
|
|
if (!this.data.orderId) return
|
|
await this.withOrderRequest(async () => {
|
|
const response = await request(`/orders/${encodeURIComponent(this.data.orderId)}/open-door`, {
|
|
method: 'POST',
|
|
data: { delayTime: 4 },
|
|
})
|
|
this.setData({
|
|
successMessage: `开门指令已发送:${response.data.status || 'PUBLISHED'}`,
|
|
})
|
|
})
|
|
},
|
|
|
|
onRenewMinutesInput(event) {
|
|
this.setData({ renewMinutes: Number(event.detail.value || 0) })
|
|
},
|
|
|
|
onChangeRoomInput(event) {
|
|
this.setData({ changeRoomId: String(event.detail.value || '').trim() })
|
|
},
|
|
|
|
onShareTtlInput(event) {
|
|
this.setData({ shareTtlMinutes: Number(event.detail.value || 0) })
|
|
},
|
|
|
|
async renewOrder() {
|
|
if (!this.data.orderId || !this.data.order) return
|
|
const minutes = Number(this.data.renewMinutes || 0)
|
|
if (!Number.isFinite(minutes) || minutes < 15) {
|
|
this.setData({ errorMessage: '续费时长至少 15 分钟' })
|
|
return
|
|
}
|
|
const currentEnd = new Date(this.data.order.endAt)
|
|
const nextEnd = new Date(currentEnd.getTime() + minutes * 60000)
|
|
await this.withOrderRequest(async () => {
|
|
const response = await request(`/orders/${encodeURIComponent(this.data.orderId)}/renew`, {
|
|
method: 'POST',
|
|
data: {
|
|
endAt: nextEnd.toISOString(),
|
|
pricingPolicy: 'CURRENT',
|
|
reason: `顾客小程序续费 ${minutes} 分钟`,
|
|
},
|
|
})
|
|
await this.loadOrder(this.data.orderId)
|
|
this.setData({
|
|
successMessage: `续费已提交,补差 ${cents(response.data.amountDeltaCents)}`,
|
|
})
|
|
})
|
|
},
|
|
|
|
async changeRoom() {
|
|
if (!this.data.orderId || !this.data.changeRoomId) {
|
|
this.setData({ errorMessage: '请输入目标房间 ID' })
|
|
return
|
|
}
|
|
await this.withOrderRequest(async () => {
|
|
const response = await request(`/orders/${encodeURIComponent(this.data.orderId)}/change-room`, {
|
|
method: 'POST',
|
|
data: {
|
|
roomId: this.data.changeRoomId,
|
|
reason: '顾客小程序换房',
|
|
},
|
|
})
|
|
await this.loadOrder(this.data.orderId)
|
|
this.setData({
|
|
successMessage: `换房已提交,差价 ${cents(response.data.amountDeltaCents)}`,
|
|
})
|
|
})
|
|
},
|
|
|
|
async createShare() {
|
|
if (!this.data.orderId) return
|
|
const ttlMinutes = Math.min(Math.max(Number(this.data.shareTtlMinutes || 30), 5), 1440)
|
|
await this.withOrderRequest(async () => {
|
|
const response = await request(`/orders/${encodeURIComponent(this.data.orderId)}/shares`, {
|
|
method: 'POST',
|
|
data: {
|
|
permissions: this.data.sharePermissions,
|
|
ttlMinutes,
|
|
},
|
|
})
|
|
this.setData({
|
|
shareToken: response.data.token,
|
|
successMessage: `分享口令已生成,${response.data.expiresInMinutes} 分钟内有效`,
|
|
})
|
|
})
|
|
},
|
|
|
|
async withOrderRequest(work) {
|
|
this.setData({ loading: true, errorMessage: '', successMessage: '' })
|
|
try {
|
|
await ensureLogin()
|
|
await work()
|
|
} catch (error) {
|
|
this.setData({ errorMessage: error.message || '订单操作失败' })
|
|
} finally {
|
|
this.setData({ loading: false })
|
|
}
|
|
},
|
|
})
|
|
|
|
function formatOrder(order) {
|
|
return {
|
|
...order,
|
|
totalText: cents(order.totalAmountCents),
|
|
paidText: cents(order.paidAmountCents),
|
|
startText: formatTime(order.startAt),
|
|
endText: formatTime(order.endAt),
|
|
}
|
|
}
|
|
|
|
function formatTime(value) {
|
|
const date = new Date(value)
|
|
const pad = (input) => String(input).padStart(2, '0')
|
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
|
|
}
|