// 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) }) }) } })