332 lines
8.5 KiB
JavaScript
332 lines
8.5 KiB
JavaScript
// pages/order-detail/order-detail.js
|
|
// 订单详情页面 - 对接后端API
|
|
|
|
const api = require('../../utils/api')
|
|
|
|
// 评价标签预设
|
|
const REVIEW_TAGS = [
|
|
'专业', '耐心', '温暖', '有效果', '善于倾听',
|
|
'有同理心', '高效', '支持', '不评判', '细心',
|
|
'温柔', '有帮助', '值得信赖', '回复及时'
|
|
]
|
|
|
|
Page({
|
|
data: {
|
|
statusBarHeight: 44,
|
|
navBarHeight: 44,
|
|
totalNavHeight: 88,
|
|
loading: true,
|
|
order: null,
|
|
// 评价弹窗相关
|
|
showReviewModal: false,
|
|
reviewRating: 5,
|
|
reviewContent: '',
|
|
reviewTags: REVIEW_TAGS,
|
|
selectedTags: [],
|
|
isAnonymous: false,
|
|
submittingReview: false
|
|
},
|
|
|
|
onLoad(options) {
|
|
const systemInfo = wx.getSystemInfoSync()
|
|
const statusBarHeight = systemInfo.statusBarHeight || 44
|
|
const menuButton = wx.getMenuButtonBoundingClientRect()
|
|
const navBarHeight = menuButton.height + (menuButton.top - statusBarHeight) * 2
|
|
const totalNavHeight = statusBarHeight + navBarHeight
|
|
|
|
const orderId = options.id
|
|
|
|
this.setData({
|
|
statusBarHeight,
|
|
navBarHeight,
|
|
totalNavHeight
|
|
})
|
|
|
|
if (orderId) {
|
|
this.loadOrderDetail(orderId)
|
|
} else {
|
|
wx.showToast({ title: '参数错误', icon: 'none' })
|
|
setTimeout(() => wx.navigateBack(), 1500)
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 加载订单详情
|
|
*/
|
|
async loadOrderDetail(id) {
|
|
this.setData({ loading: true })
|
|
|
|
try {
|
|
const res = await api.order.getDetail(id)
|
|
|
|
if (res.success && res.data) {
|
|
const order = this.transformOrder(res.data)
|
|
this.setData({ order, loading: false })
|
|
} else {
|
|
throw new Error(res.message || '加载失败')
|
|
}
|
|
} catch (err) {
|
|
console.error('加载订单详情失败', err)
|
|
this.setData({ loading: false })
|
|
wx.showToast({ title: '加载失败', icon: 'none' })
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 转换订单数据格式
|
|
*/
|
|
transformOrder(data) {
|
|
const typeConfig = {
|
|
recharge: { typeName: '爱心充值', icon: '/images/icon-heart.png', iconBg: 'pink' },
|
|
vip: { typeName: '会员服务', icon: '/images/icon-star.png', iconBg: 'purple' },
|
|
gift: { typeName: '礼物购买', icon: '/images/icon-gift.png', iconBg: 'orange' },
|
|
companion: { typeName: '陪聊服务', icon: '/images/icon-chat.png', iconBg: 'blue' }
|
|
}
|
|
|
|
const config = typeConfig[data.type] || typeConfig.recharge
|
|
|
|
const statusMap = {
|
|
pending: '待支付',
|
|
paid: '交易成功',
|
|
completed: '交易成功',
|
|
cancelled: '已取消',
|
|
refunded: '已退款',
|
|
in_service: '服务中'
|
|
}
|
|
|
|
const statusDescMap = {
|
|
pending: '请尽快完成支付',
|
|
paid: '您的订单已完成支付',
|
|
completed: '订单已完成',
|
|
cancelled: '订单已取消',
|
|
refunded: '订单已退款',
|
|
in_service: '服务进行中'
|
|
}
|
|
|
|
return {
|
|
id: data.id,
|
|
typeName: config.typeName,
|
|
icon: config.icon,
|
|
iconBg: config.iconBg,
|
|
status: statusMap[data.status] || data.status,
|
|
statusDesc: statusDescMap[data.status] || '',
|
|
productName: data.product_name || data.description || '',
|
|
priceSymbol: data.currency === 'flower' ? '🌿' : '¥',
|
|
price: data.amount || data.price || '0',
|
|
payMethod: data.payment_method === 'wechat' ? '微信支付' : (data.payment_method === 'flower' ? '爱心支付' : data.payment_method || ''),
|
|
orderNo: data.order_no || data.id,
|
|
createTime: this.formatTime(data.created_at),
|
|
payTime: data.paid_at ? this.formatTime(data.paid_at) : '',
|
|
canRefund: data.status === 'paid' && data.can_refund !== false,
|
|
canCancel: data.status === 'pending',
|
|
canReview: data.status === 'completed' && !data.reviewed
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 格式化时间
|
|
*/
|
|
formatTime(dateStr) {
|
|
if (!dateStr) return ''
|
|
const date = new Date(dateStr)
|
|
const year = date.getFullYear()
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
const hour = String(date.getHours()).padStart(2, '0')
|
|
const minute = String(date.getMinutes()).padStart(2, '0')
|
|
const second = String(date.getSeconds()).padStart(2, '0')
|
|
return `${year}-${month}-${day} ${hour}:${minute}:${second}`
|
|
},
|
|
|
|
goBack() {
|
|
wx.navigateBack()
|
|
},
|
|
|
|
onCopyOrderNo() {
|
|
const { orderNo } = this.data.order
|
|
wx.setClipboardData({
|
|
data: String(orderNo),
|
|
success: () => {
|
|
wx.showToast({
|
|
title: '已复制订单号',
|
|
icon: 'success'
|
|
})
|
|
}
|
|
})
|
|
},
|
|
|
|
onContactService() {
|
|
wx.navigateTo({
|
|
url: '/pages/service/service'
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 取消订单
|
|
*/
|
|
async onCancel() {
|
|
const confirmed = await this.showConfirm('取消订单', '确定要取消订单吗?')
|
|
if (!confirmed) return
|
|
|
|
wx.showLoading({ title: '取消中...' })
|
|
|
|
try {
|
|
const res = await api.order.cancel(this.data.order.id)
|
|
|
|
wx.hideLoading()
|
|
|
|
if (res.success) {
|
|
wx.showToast({ title: '订单已取消', icon: 'success' })
|
|
// 刷新订单详情
|
|
this.loadOrderDetail(this.data.order.id)
|
|
} else {
|
|
wx.showToast({ title: res.message || '取消失败', icon: 'none' })
|
|
}
|
|
} catch (err) {
|
|
wx.hideLoading()
|
|
wx.showToast({ title: '取消失败', icon: 'none' })
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 申请退款
|
|
*/
|
|
async onRefund() {
|
|
const confirmed = await this.showConfirm('申请退款', '确定要申请退款吗?')
|
|
if (!confirmed) return
|
|
|
|
wx.showLoading({ title: '提交中...' })
|
|
|
|
try {
|
|
const res = await api.order.cancel(this.data.order.id, '用户申请退款')
|
|
|
|
wx.hideLoading()
|
|
|
|
if (res.success) {
|
|
wx.showToast({ title: '退款申请已提交', icon: 'success' })
|
|
this.loadOrderDetail(this.data.order.id)
|
|
} else {
|
|
wx.showToast({ title: res.message || '申请失败', icon: 'none' })
|
|
}
|
|
} catch (err) {
|
|
wx.hideLoading()
|
|
wx.showToast({ title: '申请失败', icon: 'none' })
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 评价订单 - 打开评价弹窗
|
|
*/
|
|
onReview() {
|
|
this.setData({
|
|
showReviewModal: true,
|
|
reviewRating: 5,
|
|
reviewContent: '',
|
|
selectedTags: [],
|
|
isAnonymous: false
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 关闭评价弹窗
|
|
*/
|
|
closeReviewModal() {
|
|
this.setData({ showReviewModal: false })
|
|
},
|
|
|
|
/**
|
|
* 选择评分
|
|
*/
|
|
selectRating(e) {
|
|
const rating = e.currentTarget.dataset.rating
|
|
this.setData({ reviewRating: rating })
|
|
},
|
|
|
|
/**
|
|
* 切换标签选择
|
|
*/
|
|
toggleTag(e) {
|
|
const tag = e.currentTarget.dataset.tag
|
|
const { selectedTags } = this.data
|
|
const index = selectedTags.indexOf(tag)
|
|
|
|
if (index > -1) {
|
|
selectedTags.splice(index, 1)
|
|
} else {
|
|
if (selectedTags.length < 5) {
|
|
selectedTags.push(tag)
|
|
} else {
|
|
wx.showToast({ title: '最多选择5个标签', icon: 'none' })
|
|
return
|
|
}
|
|
}
|
|
|
|
this.setData({ selectedTags })
|
|
},
|
|
|
|
/**
|
|
* 输入评价内容
|
|
*/
|
|
onReviewInput(e) {
|
|
this.setData({ reviewContent: e.detail.value })
|
|
},
|
|
|
|
/**
|
|
* 切换匿名评价
|
|
*/
|
|
toggleAnonymous() {
|
|
this.setData({ isAnonymous: !this.data.isAnonymous })
|
|
},
|
|
|
|
/**
|
|
* 提交评价
|
|
*/
|
|
async submitReview() {
|
|
const { order, reviewRating, reviewContent, selectedTags, isAnonymous } = this.data
|
|
|
|
if (this.data.submittingReview) return
|
|
|
|
this.setData({ submittingReview: true })
|
|
wx.showLoading({ title: '提交中...' })
|
|
|
|
try {
|
|
const res = await api.order.review(order.id, {
|
|
rating: reviewRating,
|
|
content: reviewContent,
|
|
tags: selectedTags,
|
|
isAnonymous: isAnonymous
|
|
})
|
|
|
|
wx.hideLoading()
|
|
this.setData({ submittingReview: false })
|
|
|
|
if (res.success) {
|
|
wx.showToast({ title: '评价成功', icon: 'success' })
|
|
this.setData({ showReviewModal: false })
|
|
// 刷新订单详情
|
|
this.loadOrderDetail(order.id)
|
|
} else {
|
|
wx.showToast({ title: res.message || res.error || '评价失败', icon: 'none' })
|
|
}
|
|
} catch (err) {
|
|
wx.hideLoading()
|
|
this.setData({ submittingReview: false })
|
|
console.error('提交评价失败', err)
|
|
wx.showToast({ title: '评价失败', icon: 'none' })
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 显示确认弹窗
|
|
*/
|
|
showConfirm(title, content) {
|
|
return new Promise((resolve) => {
|
|
wx.showModal({
|
|
title,
|
|
content,
|
|
success: (res) => resolve(res.confirm)
|
|
})
|
|
})
|
|
}
|
|
})
|