统一排行榜对齐星雀UI,页面资源后台配置实时刷新
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
707
miniprogram/pages/sjddxq/sjddxq.js
Normal file
707
miniprogram/pages/sjddxq/sjddxq.js
Normal file
@@ -0,0 +1,707 @@
|
||||
// pages/sjddxq/sjddxq.js - 商家订单详情(完整版,已添加罚款/退款操作及教程按钮)
|
||||
const app = getApp()
|
||||
import request from '../../utils/request.js'
|
||||
import connectionManager from '../../utils/xiaoxilj.js'
|
||||
import PopupService from '../../services/popupService.js' // 新增:导入弹窗服务
|
||||
|
||||
Page({
|
||||
data: {
|
||||
jibenShuju: {
|
||||
dingdan_id: '', tupian: '', jieshao: '', create_time: '',
|
||||
jine: '', nicheng: '', beizhu: '', zhuangtai: 0, fadanpingtai: 0, is_cross: 0
|
||||
},
|
||||
dashouInfo: { yonghuid: '', nicheng: '', avatar: '' },
|
||||
xiangxiShuju: {
|
||||
dashou_jiaofu: [], dashou_liuyan: '', tuikuan_liyou: '', shangjia_liuyan: ''
|
||||
},
|
||||
fadanData: null,
|
||||
fenhongLilv: 0,
|
||||
xinDingdanId: '',
|
||||
zhuangtaiYanseMap: {
|
||||
1: '#E8F5E9', 2: '#E3F2FD', 3: '#F3E5F5', 4: '#FFF3E0',
|
||||
5: '#FFEBEE', 6: '#EFEBE9', 7: '#E0F7FA', 8: '#FFF8E1'
|
||||
},
|
||||
zhuangtaiWenziMap: {
|
||||
1: '已下单', 2: '进行中', 3: '已完成', 4: '退款中',
|
||||
5: '已退款', 6: '退款失败', 7: '指定中', 8: '结算中'
|
||||
},
|
||||
isLoading: true,
|
||||
showChexiaoModal: false, chexiaoLiyou: '', isChexiaoLoading: false,
|
||||
showTuikuanModal: false, tuikuanLiyou: '', isTuikuanLoading: false,
|
||||
showFakuanModal: false, fakuanLiyou: '', fakuanJine: '', yingxiangQiangdan: true, isFakuanLoading: false,
|
||||
showGhDashouModal: false, isGhDashouLoading: false,
|
||||
showJiesuanConfirm: false, isJiesuanLoading: false,
|
||||
jiesuanPingfen: 0, jiesuanLiuyan: '',
|
||||
xingxingData: [
|
||||
{ id: 1, active: false }, { id: 2, active: false }, { id: 3, active: false },
|
||||
{ id: 4, active: false }, { id: 5, active: false }
|
||||
],
|
||||
currentIMUserId: '',
|
||||
|
||||
// ========== 新增:罚单/订单操作弹窗控制 ==========
|
||||
showModifyFakuanModal: false, // 修改罚款弹窗
|
||||
modifyFakuanLiyou: '', // 修改后的罚款理由
|
||||
modifyFakuanJine: '', // 修改后的罚款金额
|
||||
showCancelFakuanModal: false, // 撤销罚款弹窗
|
||||
cancelFakuanLiyou: '', // 撤销驳回理由
|
||||
showResubmitFakuanModal: false, // 再次申请罚款弹窗
|
||||
resubmitFakuanLiyou: '', // 再次申请的理由
|
||||
resubmitFakuanJine: '', // 再次申请的金额
|
||||
showCancelTuikuanModal: false, // 撤销退款申请弹窗
|
||||
cancelTuikuanLiyou: '', // 撤销退款理由
|
||||
showModifyTuikuanModal: false, // 修改退款理由弹窗
|
||||
modifyTuikuanLiyou: '', // 修改后的退款理由
|
||||
// 教程按钮状态
|
||||
tutorialBtnHidden: false
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
wx.setNavigationBarTitle({ title: '订单详情' })
|
||||
this.ensureIMConnection()
|
||||
this.jiexiTiaozhuanCanshu(options)
|
||||
// 新增:启动教程按钮定时器
|
||||
this.startTutorialBtnTimer()
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.registerNotificationComponent()
|
||||
this.ensureIMConnection()
|
||||
},
|
||||
|
||||
onHide() {
|
||||
// 页面隐藏时重置弹窗服务状态,避免影响其他页面
|
||||
PopupService.reset()
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
// 清除缩进定时器,避免内存泄漏
|
||||
if (this.tutorialTimer) {
|
||||
clearTimeout(this.tutorialTimer)
|
||||
}
|
||||
// 页面卸载时重置弹窗服务
|
||||
PopupService.reset()
|
||||
},
|
||||
|
||||
registerNotificationComponent() {
|
||||
const notificationComp = this.selectComponent('#global-notification')
|
||||
if (notificationComp && notificationComp.showNotification) {
|
||||
app.globalData.globalNotification = {
|
||||
show: (data) => notificationComp.showNotification(data),
|
||||
hide: () => notificationComp.hideNotification()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ensureIMConnection() {
|
||||
const uid = wx.getStorageSync('uid')
|
||||
if (!uid) return
|
||||
app.globalData.currentRole = 'shangjia'
|
||||
wx.setStorageSync('currentRole', 'shangjia')
|
||||
const targetUserId = 'Sj' + uid
|
||||
const status = wx.goEasy?.getConnectionStatus?.() || 'disconnected'
|
||||
const currentUserId = wx.goEasy?.im?.userId
|
||||
if ((status === 'connected' || status === 'reconnected') && currentUserId === targetUserId) {
|
||||
this.setData({ currentIMUserId: targetUserId })
|
||||
return
|
||||
}
|
||||
if (app.ensureConnection) app.ensureConnection()
|
||||
this.setData({ currentIMUserId: targetUserId })
|
||||
},
|
||||
|
||||
jiexiTiaozhuanCanshu(options) {
|
||||
try {
|
||||
const dingdanDataStr = options.dingdanData || ''
|
||||
if (!dingdanDataStr) {
|
||||
wx.showToast({ title: '订单数据错误', icon: 'none' })
|
||||
setTimeout(() => wx.navigateBack(), 1500)
|
||||
return
|
||||
}
|
||||
const dingdanData = JSON.parse(decodeURIComponent(dingdanDataStr))
|
||||
let tupianUrl = dingdanData.tupian || ''
|
||||
if (!tupianUrl) tupianUrl = this.getTupianUrl()
|
||||
let jine = parseFloat(dingdanData.jine || 0)
|
||||
if (isNaN(jine)) jine = 0
|
||||
this.setData({
|
||||
'jibenShuju.dingdan_id': dingdanData.dingdan_id || '',
|
||||
'jibenShuju.tupian': tupianUrl,
|
||||
'jibenShuju.jieshao': dingdanData.jieshao || '',
|
||||
'jibenShuju.create_time': dingdanData.create_time || '',
|
||||
'jibenShuju.jine': jine.toFixed(2),
|
||||
'jibenShuju.nicheng': dingdanData.nicheng || '',
|
||||
'jibenShuju.beizhu': dingdanData.beizhu || '',
|
||||
'jibenShuju.zhuangtai': dingdanData.zhuangtai || 0,
|
||||
'jibenShuju.fadanpingtai': dingdanData.fadanpingtai || 0,
|
||||
'jibenShuju.is_cross': dingdanData.is_cross || 0,
|
||||
isLoading: false
|
||||
})
|
||||
this.jiazaiXiangxiShuju(dingdanData.dingdan_id)
|
||||
} catch (error) {
|
||||
console.error('解析订单数据失败', error)
|
||||
wx.showToast({ title: '数据解析失败', icon: 'none' })
|
||||
setTimeout(() => wx.navigateBack(), 1500)
|
||||
}
|
||||
},
|
||||
|
||||
getTupianUrl() {
|
||||
const cacheTouxiang = wx.getStorageSync('touxiang') || ''
|
||||
let tupianPath = cacheTouxiang || app.globalData.morentouxiang || ''
|
||||
const ossImageUrl = app.globalData.ossImageUrl || ''
|
||||
if (tupianPath && ossImageUrl) {
|
||||
if (tupianPath.startsWith('/')) tupianPath = tupianPath.substring(1)
|
||||
return ossImageUrl + tupianPath
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
async jiazaiXiangxiShuju(dingdanId) {
|
||||
if (!dingdanId) return
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjddxq',
|
||||
method: 'POST',
|
||||
data: { dingdan_id: dingdanId },
|
||||
header: { 'content-type': 'application/json' }
|
||||
})
|
||||
if (res && res.data.code === 0 && res.data.data) {
|
||||
const d = res.data.data
|
||||
let jiaofuList = d.dashou_jiaofu || []
|
||||
jiaofuList = jiaofuList.map(url => {
|
||||
if (url && !url.startsWith('http')) {
|
||||
const oss = app.globalData.ossImageUrl || ''
|
||||
return oss + url
|
||||
}
|
||||
return url
|
||||
})
|
||||
let dashouAvatar = d.dashou_avatar || ''
|
||||
if (dashouAvatar && !dashouAvatar.startsWith('http')) {
|
||||
dashouAvatar = (app.globalData.ossImageUrl || '') + dashouAvatar
|
||||
}
|
||||
this.setData({
|
||||
'dashouInfo.yonghuid': d.dashou_yonghuid || '',
|
||||
'dashouInfo.nicheng': d.dashou_nicheng || '',
|
||||
'dashouInfo.avatar': dashouAvatar,
|
||||
'xiangxiShuju.dashou_jiaofu': jiaofuList,
|
||||
'xiangxiShuju.dashou_liuyan': d.dashou_liuyan || '',
|
||||
'xiangxiShuju.tuikuan_liyou': d.tuikuan_liyou || '',
|
||||
'xiangxiShuju.shangjia_liuyan': d.shangjia_liuyan || '',
|
||||
fadanData: d.fadan || null,
|
||||
fenhongLilv: parseFloat(d.fenhong_lilv) || 0,
|
||||
xinDingdanId: d.xin_dingdan_id || '',
|
||||
'jibenShuju.zhuangtai': d.zhuangtai || this.data.jibenShuju.zhuangtai,
|
||||
'jibenShuju.is_cross': d.is_cross != null ? d.is_cross : this.data.jibenShuju.is_cross,
|
||||
'jibenShuju.fadanpingtai': d.fadanpingtai != null ? d.fadanpingtai : this.data.jibenShuju.fadanpingtai,
|
||||
})
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '获取详情失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载详情失败', err)
|
||||
wx.showToast({ title: '网络错误', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
fuzhiWenben(e) {
|
||||
const text = e.currentTarget.dataset.text
|
||||
if (!text) return
|
||||
wx.setClipboardData({ data: text })
|
||||
wx.showToast({ title: '已复制', icon: 'success' })
|
||||
},
|
||||
|
||||
yulanTupian(e) {
|
||||
const current = e.currentTarget.dataset.url
|
||||
const urls = e.currentTarget.dataset.urls || [current]
|
||||
wx.previewImage({ current, urls })
|
||||
},
|
||||
|
||||
goToKefu() {
|
||||
const kefuLink = app.globalData.kefuConfig?.link || ''
|
||||
const corpId = app.globalData.kefuConfig?.enterpriseId || ''
|
||||
if (!kefuLink || !corpId) {
|
||||
wx.showToast({ title: '客服配置未加载', icon: 'none' })
|
||||
return
|
||||
}
|
||||
wx.openCustomerServiceChat({
|
||||
extInfo: { url: kefuLink },
|
||||
corpId: corpId,
|
||||
success: (res) => console.log('跳转客服成功', res),
|
||||
fail: (err) => {
|
||||
console.error('跳转客服失败', err)
|
||||
wx.showToast({ title: '暂时无法连接客服', icon: 'none' })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// ===== 联系打手(后端准备配对群 + 稳定跳转) =====
|
||||
goToChatWithDashou() {
|
||||
const uid = wx.getStorageSync('uid')
|
||||
if (!uid) return
|
||||
|
||||
const orderId = this.data.jibenShuju.dingdan_id
|
||||
if (!orderId) {
|
||||
wx.showToast({ title: '订单ID缺失', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
connectionManager.connectToGroupChat({
|
||||
identityType: 'shangjia',
|
||||
userId: 'Sj' + uid,
|
||||
orderId,
|
||||
partnerUid: this.data.dashouInfo.yonghuid,
|
||||
fadanPingtai: this.data.jibenShuju.fadanpingtai || 0,
|
||||
groupName: (this.data.dashouInfo.nicheng || this.data.jibenShuju.nicheng) + '的订单群',
|
||||
isCross: this.data.jibenShuju.is_cross || 0
|
||||
}).catch(err => {
|
||||
console.error('跳转群聊失败', err)
|
||||
})
|
||||
},
|
||||
|
||||
// ========== 以下所有业务功能完全保持不变 ==========
|
||||
showGhDashouConfirm() { this.setData({ showGhDashouModal: true }) },
|
||||
closeGhDashouModal() { this.setData({ showGhDashouModal: false }) },
|
||||
async tijiaoGhDashou() {
|
||||
if (this.data.isGhDashouLoading) return
|
||||
this.setData({ isGhDashouLoading: true })
|
||||
wx.showLoading({ title: '更换中...', mask: true })
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/zxsjghds',
|
||||
method: 'POST',
|
||||
data: { dingdan_id: this.data.jibenShuju.dingdan_id },
|
||||
header: { 'content-type': 'application/json' }
|
||||
})
|
||||
wx.hideLoading()
|
||||
this.setData({ isGhDashouLoading: false, showGhDashouModal: false })
|
||||
if (res && res.data.code === 0) {
|
||||
this.setData({ xinDingdanId: res.data.data?.xin_dingdan_id || '' })
|
||||
wx.showToast({ title: '更换成功', icon: 'success' })
|
||||
this.jiazaiXiangxiShuju(this.data.jibenShuju.dingdan_id)
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '更换失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading()
|
||||
this.setData({ isGhDashouLoading: false, showGhDashouModal: false })
|
||||
wx.showToast({ title: '网络错误', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
showFakuanModal() { this.setData({ showFakuanModal: true, fakuanLiyou: '', fakuanJine: '', yingxiangQiangdan: true }) },
|
||||
closeFakuanModal() { this.setData({ showFakuanModal: false }) },
|
||||
inputFakuanLiyou(e) { this.setData({ fakuanLiyou: e.detail.value.slice(0, 50) }) },
|
||||
inputFakuanJine(e) { this.setData({ fakuanJine: e.detail.value }) },
|
||||
toggleQiangdan() { this.setData({ yingxiangQiangdan: !this.data.yingxiangQiangdan }) },
|
||||
jisuanFenhong() {
|
||||
const jine = parseFloat(this.data.fakuanJine)
|
||||
if (isNaN(jine) || jine <= 0) return '0.00'
|
||||
return (jine * this.data.fenhongLilv).toFixed(2)
|
||||
},
|
||||
async tijiaoFakuan() {
|
||||
const { fakuanLiyou, fakuanJine, jibenShuju, dashouInfo } = this.data
|
||||
if (!fakuanLiyou.trim()) { wx.showToast({ title: '请输入罚款原因', icon: 'none' }); return }
|
||||
const jineNum = parseFloat(fakuanJine)
|
||||
if (isNaN(jineNum) || jineNum <= 0) { wx.showToast({ title: '请输入正确的罚款金额', icon: 'none' }); return }
|
||||
if (this.data.isFakuanLoading) return
|
||||
this.setData({ isFakuanLoading: true })
|
||||
wx.showLoading({ title: '提交中...', mask: true })
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjfksq',
|
||||
method: 'POST',
|
||||
data: {
|
||||
dingdan_id: jibenShuju.dingdan_id,
|
||||
chufa_liyou: fakuanLiyou,
|
||||
fakuanjine: jineNum.toFixed(2),
|
||||
yingxiang_qiangdan: this.data.yingxiangQiangdan ? 1 : 0,
|
||||
dashou_id: dashouInfo.yonghuid
|
||||
},
|
||||
header: { 'content-type': 'application/json' }
|
||||
})
|
||||
wx.hideLoading()
|
||||
this.setData({ isFakuanLoading: false })
|
||||
if (res && res.data.code === 0) {
|
||||
wx.showToast({ title: '罚款申请已提交', icon: 'success' })
|
||||
this.setData({ showFakuanModal: false })
|
||||
this.jiazaiXiangxiShuju(jibenShuju.dingdan_id)
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '提交失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading()
|
||||
this.setData({ isFakuanLoading: false })
|
||||
wx.showToast({ title: '网络错误', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
showChexiaoBtn() { this.setData({ showChexiaoModal: true, chexiaoLiyou: '' }) },
|
||||
closeChexiaoModal() { this.setData({ showChexiaoModal: false }) },
|
||||
shuruChexiaoLiyou(e) { this.setData({ chexiaoLiyou: e.detail.value.slice(0, 50) }) },
|
||||
async tijiaoChexiao() {
|
||||
if (this.data.isChexiaoLoading) return
|
||||
const { chexiaoLiyou, jibenShuju } = this.data
|
||||
if (!chexiaoLiyou.trim()) { wx.showToast({ title: '请输入撤销原因', icon: 'none' }); return }
|
||||
this.setData({ isChexiaoLoading: true })
|
||||
wx.showLoading({ title: '撤销中...', mask: true })
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjchexiao',
|
||||
method: 'POST',
|
||||
data: { dingdan_id: jibenShuju.dingdan_id, chexiao_liyou: chexiaoLiyou },
|
||||
header: { 'content-type': 'application/json' }
|
||||
})
|
||||
wx.hideLoading()
|
||||
this.setData({ isChexiaoLoading: false })
|
||||
if (res && res.data.code === 0) {
|
||||
this.setData({ 'jibenShuju.zhuangtai': 5, showChexiaoModal: false })
|
||||
wx.showToast({ title: '撤销成功', icon: 'success' })
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '撤销失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading()
|
||||
this.setData({ isChexiaoLoading: false })
|
||||
wx.showToast({ title: '网络错误', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
showTuikuanBtn() { this.setData({ showTuikuanModal: true, tuikuanLiyou: '' }) },
|
||||
closeTuikuanModal() { this.setData({ showTuikuanModal: false }) },
|
||||
shuruTuikuanLiyou(e) { this.setData({ tuikuanLiyou: e.detail.value.slice(0, 50) }) },
|
||||
async tijiaoTuikuan() {
|
||||
if (this.data.isTuikuanLoading) return
|
||||
const { tuikuanLiyou, jibenShuju } = this.data
|
||||
if (!tuikuanLiyou.trim()) { wx.showToast({ title: '请输入退款原因', icon: 'none' }); return }
|
||||
this.setData({ isTuikuanLoading: true })
|
||||
wx.showLoading({ title: '提交中...', mask: true })
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjtkshenqing',
|
||||
method: 'POST',
|
||||
data: { dingdan_id: jibenShuju.dingdan_id, tuikuan_liyou: tuikuanLiyou },
|
||||
header: { 'content-type': 'application/json' }
|
||||
})
|
||||
wx.hideLoading()
|
||||
this.setData({ isTuikuanLoading: false })
|
||||
if (res && res.data.code === 0) {
|
||||
this.setData({ 'jibenShuju.zhuangtai': 4, showTuikuanModal: false })
|
||||
wx.showToast({ title: '退款申请已提交', icon: 'success' })
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading()
|
||||
this.setData({ isTuikuanLoading: false })
|
||||
wx.showToast({ title: '网络错误', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
dianjiXingxing(e) {
|
||||
const pf = e.currentTarget.dataset.index
|
||||
const newStars = this.data.xingxingData.map((item, idx) => ({ ...item, active: idx < pf }))
|
||||
this.setData({ xingxingData: newStars, jiesuanPingfen: pf })
|
||||
},
|
||||
shuruLiuyan(e) { this.setData({ jiesuanLiuyan: e.detail.value.slice(0, 50) }) },
|
||||
showJiesuanConfirm() { this.setData({ showJiesuanConfirm: true }) },
|
||||
closeJiesuanConfirm() { this.setData({ showJiesuanConfirm: false }) },
|
||||
async tijiaoJiesuan() {
|
||||
if (this.data.isJiesuanLoading) return
|
||||
this.setData({ isJiesuanLoading: true })
|
||||
wx.showLoading({ title: '结算中...', mask: true })
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjjiesuan',
|
||||
method: 'POST',
|
||||
data: {
|
||||
dingdan_id: this.data.jibenShuju.dingdan_id,
|
||||
pingfen: this.data.jiesuanPingfen,
|
||||
liuyan: this.data.jiesuanLiuyan
|
||||
},
|
||||
header: { 'content-type': 'application/json' }
|
||||
})
|
||||
wx.hideLoading()
|
||||
this.setData({ isJiesuanLoading: false, showJiesuanConfirm: false })
|
||||
if (res && res.data.code === 0) {
|
||||
this.setData({ 'jibenShuju.zhuangtai': 3 })
|
||||
wx.showToast({ title: '结算成功', icon: 'success' })
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '结算失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading()
|
||||
this.setData({ isJiesuanLoading: false })
|
||||
wx.showToast({ title: '网络错误', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 新增:罚款操作(修改/撤销/再次申请) ==========
|
||||
// 显示修改罚款弹窗(仅当状态为待缴纳 或 申诉中 时可用)
|
||||
showModifyFakuan() {
|
||||
const status = this.data.fadanData?.zhuangtai;
|
||||
if (status !== 1 && status !== 3) {
|
||||
wx.showToast({ title: '当前状态不可修改罚款', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.setData({
|
||||
showModifyFakuanModal: true,
|
||||
modifyFakuanLiyou: this.data.fadanData?.chufaliyou || '',
|
||||
modifyFakuanJine: this.data.fadanData?.fakuanjine || ''
|
||||
});
|
||||
},
|
||||
closeModifyFakuanModal() {
|
||||
this.setData({ showModifyFakuanModal: false });
|
||||
},
|
||||
inputModifyFakuanLiyou(e) {
|
||||
this.setData({ modifyFakuanLiyou: e.detail.value.slice(0, 100) });
|
||||
},
|
||||
inputModifyFakuanJine(e) {
|
||||
this.setData({ modifyFakuanJine: e.detail.value });
|
||||
},
|
||||
async submitModifyFakuan() {
|
||||
const { modifyFakuanLiyou, modifyFakuanJine, fadanData, jibenShuju } = this.data;
|
||||
if (!modifyFakuanLiyou.trim()) {
|
||||
wx.showToast({ title: '请输入罚款理由', icon: 'none' }); return;
|
||||
}
|
||||
const jine = parseFloat(modifyFakuanJine);
|
||||
if (isNaN(jine) || jine <= 0) {
|
||||
wx.showToast({ title: '请输入正确的罚款金额', icon: 'none' }); return;
|
||||
}
|
||||
wx.showLoading({ title: '提交中...', mask: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjfkxgycx',
|
||||
method: 'POST',
|
||||
data: {
|
||||
operation: 'modify_penalty',
|
||||
fadan_id: fadanData.id,
|
||||
dingdan_id: jibenShuju.dingdan_id,
|
||||
liyou: modifyFakuanLiyou,
|
||||
jine: jine.toFixed(2)
|
||||
}
|
||||
});
|
||||
wx.hideLoading();
|
||||
if (res && res.data.code === 0) {
|
||||
wx.showToast({ title: '修改成功', icon: 'success' });
|
||||
this.setData({ showModifyFakuanModal: false });
|
||||
this.jiazaiXiangxiShuju(jibenShuju.dingdan_id); // 刷新数据
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '修改失败', icon: 'none' });
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
// 显示撤销罚款弹窗(待缴纳/申诉中 可撤销,变为已驳回)
|
||||
showCancelFakuan() {
|
||||
const status = this.data.fadanData?.zhuangtai;
|
||||
if (status !== 1 && status !== 3) {
|
||||
wx.showToast({ title: '当前状态不可撤销罚款', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.setData({ showCancelFakuanModal: true, cancelFakuanLiyou: '' });
|
||||
},
|
||||
closeCancelFakuanModal() {
|
||||
this.setData({ showCancelFakuanModal: false });
|
||||
},
|
||||
inputCancelFakuanLiyou(e) {
|
||||
this.setData({ cancelFakuanLiyou: e.detail.value.slice(0, 100) });
|
||||
},
|
||||
async submitCancelFakuan() {
|
||||
const { cancelFakuanLiyou, fadanData, jibenShuju } = this.data;
|
||||
if (!cancelFakuanLiyou.trim()) {
|
||||
wx.showToast({ title: '请输入驳回理由', icon: 'none' }); return;
|
||||
}
|
||||
wx.showLoading({ title: '提交中...', mask: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjfkxgycx',
|
||||
method: 'POST',
|
||||
data: {
|
||||
operation: 'cancel_penalty',
|
||||
fadan_id: fadanData.id,
|
||||
dingdan_id: jibenShuju.dingdan_id,
|
||||
liyou: cancelFakuanLiyou
|
||||
}
|
||||
});
|
||||
wx.hideLoading();
|
||||
if (res && res.data.code === 0) {
|
||||
wx.showToast({ title: '已撤销', icon: 'success' });
|
||||
this.setData({ showCancelFakuanModal: false });
|
||||
this.jiazaiXiangxiShuju(jibenShuju.dingdan_id);
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '撤销失败', icon: 'none' });
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
// 显示再次申请罚款弹窗(仅当状态为已驳回时可用)
|
||||
showResubmitFakuan() {
|
||||
if (this.data.fadanData?.zhuangtai !== 4) {
|
||||
wx.showToast({ title: '当前状态不可再次申请', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.setData({
|
||||
showResubmitFakuanModal: true,
|
||||
resubmitFakuanLiyou: '',
|
||||
resubmitFakuanJine: ''
|
||||
});
|
||||
},
|
||||
closeResubmitFakuanModal() {
|
||||
this.setData({ showResubmitFakuanModal: false });
|
||||
},
|
||||
inputResubmitFakuanLiyou(e) {
|
||||
this.setData({ resubmitFakuanLiyou: e.detail.value.slice(0, 100) });
|
||||
},
|
||||
inputResubmitFakuanJine(e) {
|
||||
this.setData({ resubmitFakuanJine: e.detail.value });
|
||||
},
|
||||
async submitResubmitFakuan() {
|
||||
const { resubmitFakuanLiyou, resubmitFakuanJine, fadanData, jibenShuju } = this.data;
|
||||
if (!resubmitFakuanLiyou.trim()) {
|
||||
wx.showToast({ title: '请输入罚款理由', icon: 'none' }); return;
|
||||
}
|
||||
const jine = parseFloat(resubmitFakuanJine);
|
||||
if (isNaN(jine) || jine <= 0) {
|
||||
wx.showToast({ title: '请输入正确的罚款金额', icon: 'none' }); return;
|
||||
}
|
||||
wx.showLoading({ title: '提交中...', mask: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjfkxgycx',
|
||||
method: 'POST',
|
||||
data: {
|
||||
operation: 'resubmit_penalty',
|
||||
fadan_id: fadanData.id,
|
||||
dingdan_id: jibenShuju.dingdan_id,
|
||||
liyou: resubmitFakuanLiyou,
|
||||
jine: jine.toFixed(2)
|
||||
}
|
||||
});
|
||||
wx.hideLoading();
|
||||
if (res && res.data.code === 0) {
|
||||
wx.showToast({ title: '申请成功', icon: 'success' });
|
||||
this.setData({ showResubmitFakuanModal: false });
|
||||
this.jiazaiXiangxiShuju(jibenShuju.dingdan_id);
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '申请失败', icon: 'none' });
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 新增:订单退款操作(撤销/修改理由) ==========
|
||||
showCancelTuikuan() {
|
||||
if (this.data.jibenShuju.zhuangtai !== 4) {
|
||||
wx.showToast({ title: '只有退款中的订单可撤销', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.setData({ showCancelTuikuanModal: true, cancelTuikuanLiyou: '' });
|
||||
},
|
||||
closeCancelTuikuanModal() {
|
||||
this.setData({ showCancelTuikuanModal: false });
|
||||
},
|
||||
inputCancelTuikuanLiyou(e) {
|
||||
this.setData({ cancelTuikuanLiyou: e.detail.value.slice(0, 100) });
|
||||
},
|
||||
async submitCancelTuikuan() {
|
||||
const { cancelTuikuanLiyou, jibenShuju } = this.data;
|
||||
if (!cancelTuikuanLiyou.trim()) {
|
||||
wx.showToast({ title: '请输入撤销理由', icon: 'none' }); return;
|
||||
}
|
||||
wx.showLoading({ title: '撤销中...', mask: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjfkxgycx',
|
||||
method: 'POST',
|
||||
data: {
|
||||
operation: 'cancel_refund',
|
||||
dingdan_id: jibenShuju.dingdan_id,
|
||||
liyou: cancelTuikuanLiyou
|
||||
}
|
||||
});
|
||||
wx.hideLoading();
|
||||
if (res && res.data.code === 0) {
|
||||
wx.showToast({ title: '已撤销退款申请', icon: 'success' });
|
||||
this.setData({ showCancelTuikuanModal: false });
|
||||
this.jiazaiXiangxiShuju(jibenShuju.dingdan_id);
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '撤销失败', icon: 'none' });
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
showModifyTuikuan() {
|
||||
if (this.data.jibenShuju.zhuangtai !== 4) {
|
||||
wx.showToast({ title: '只有退款中的订单可修改理由', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.setData({
|
||||
showModifyTuikuanModal: true,
|
||||
modifyTuikuanLiyou: this.data.xiangxiShuju.tuikuan_liyou || ''
|
||||
});
|
||||
},
|
||||
closeModifyTuikuanModal() {
|
||||
this.setData({ showModifyTuikuanModal: false });
|
||||
},
|
||||
inputModifyTuikuanLiyou(e) {
|
||||
this.setData({ modifyTuikuanLiyou: e.detail.value.slice(0, 100) });
|
||||
},
|
||||
async submitModifyTuikuan() {
|
||||
const { modifyTuikuanLiyou, jibenShuju } = this.data;
|
||||
if (!modifyTuikuanLiyou.trim()) {
|
||||
wx.showToast({ title: '请输入退款理由', icon: 'none' }); return;
|
||||
}
|
||||
wx.showLoading({ title: '修改中...', mask: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dingdan/sjfkxgycx',
|
||||
method: 'POST',
|
||||
data: {
|
||||
operation: 'modify_refund_reason',
|
||||
dingdan_id: jibenShuju.dingdan_id,
|
||||
liyou: modifyTuikuanLiyou
|
||||
}
|
||||
});
|
||||
wx.hideLoading();
|
||||
if (res && res.data.code === 0) {
|
||||
wx.showToast({ title: '修改成功', icon: 'success' });
|
||||
this.setData({ showModifyTuikuanModal: false });
|
||||
this.jiazaiXiangxiShuju(jibenShuju.dingdan_id);
|
||||
} else {
|
||||
wx.showToast({ title: res?.data?.msg || '修改失败', icon: 'none' });
|
||||
}
|
||||
} catch (err) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 新增:教程按钮 ==========
|
||||
startTutorialBtnTimer() {
|
||||
if (this.tutorialTimer) clearTimeout(this.tutorialTimer);
|
||||
this.tutorialTimer = setTimeout(() => {
|
||||
this.setData({ tutorialBtnHidden: true });
|
||||
}, 5000);
|
||||
},
|
||||
resetTutorialBtn() {
|
||||
if (this.data.tutorialBtnHidden) {
|
||||
this.setData({ tutorialBtnHidden: false });
|
||||
}
|
||||
if (this.tutorialTimer) clearTimeout(this.tutorialTimer);
|
||||
this.tutorialTimer = setTimeout(() => {
|
||||
this.setData({ tutorialBtnHidden: true });
|
||||
}, 5000);
|
||||
},
|
||||
onTutorialBtnTap() {
|
||||
this.resetTutorialBtn();
|
||||
PopupService.checkAndShow(this, 'sjddxq1');
|
||||
}
|
||||
})
|
||||
5
miniprogram/pages/sjddxq/sjddxq.json
Normal file
5
miniprogram/pages/sjddxq/sjddxq.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"global-notification": "/components/global-notification/global-notification"
|
||||
}
|
||||
}
|
||||
354
miniprogram/pages/sjddxq/sjddxq.wxml
Normal file
354
miniprogram/pages/sjddxq/sjddxq.wxml
Normal file
@@ -0,0 +1,354 @@
|
||||
<!--pages/sjddxq/sjddxq.wxml - 商家订单详情页完整结构(正方形九宫格,圆形头像)-->
|
||||
<!-- 页面根容器 -->
|
||||
<view class="sjddxq-page">
|
||||
<!-- 加载状态区域,当 isLoading 为 true 时显示 -->
|
||||
<view class="loading-container" wx:if="{{isLoading}}">
|
||||
<!-- 旋转的加载图标 -->
|
||||
<view class="loading-spinner"></view>
|
||||
<!-- 加载文字提示 -->
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 主要内容区域,数据加载完成后显示 -->
|
||||
<view class="content-container" wx:if="{{!isLoading}}">
|
||||
<!-- 商品图片和介绍卡片 -->
|
||||
<view class="card shangpin-card">
|
||||
<!-- 商品图片,固定宽高180rpx,已是正方形 -->
|
||||
<image class="shangpin-img" src="{{jibenShuju.tupian}}" mode="aspectFill"/>
|
||||
<!-- 商品介绍文本区域 -->
|
||||
<view class="shangpin-text">
|
||||
<!-- 订单介绍文字 -->
|
||||
<text class="jieshao-text">{{jibenShuju.jieshao || '无描述'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单信息卡片,左侧带状态颜色边框 -->
|
||||
<view class="card info-card" style="border-left: 8rpx solid {{zhuangtaiYanseMap[jibenShuju.zhuangtai]}}">
|
||||
<view class="card-title">订单信息</view>
|
||||
<!-- 游戏昵称行 -->
|
||||
<view class="info-row" wx:if="{{jibenShuju.nicheng}}"><text class="label">游戏昵称</text><text class="value">{{jibenShuju.nicheng}}</text></view>
|
||||
<!-- 备注信息行 -->
|
||||
<view class="info-row" wx:if="{{jibenShuju.beizhu}}"><text class="label">备注</text><text class="value">{{jibenShuju.beizhu}}</text></view>
|
||||
<!-- 订单ID行,可复制 -->
|
||||
<view class="info-row"><text class="label">订单ID</text><view class="value-with-copy"><text class="value">{{jibenShuju.dingdan_id}}</text><text class="copy-btn" bindtap="fuzhiWenben" data-text="{{jibenShuju.dingdan_id}}">📋</text></view></view>
|
||||
<!-- 创建时间行 -->
|
||||
<view class="info-row"><text class="label">创建时间</text><text class="value">{{jibenShuju.create_time}}</text></view>
|
||||
<!-- 订单金额行,红色高亮 -->
|
||||
<view class="info-row"><text class="label">订单金额</text><text class="value price-red">¥{{jibenShuju.jine}}</text></view>
|
||||
<!-- 订单状态行 -->
|
||||
<view class="info-row"><text class="label">状态</text><text class="value zhuangtai-text">{{zhuangtaiWenziMap[jibenShuju.zhuangtai]}}</text></view>
|
||||
<!-- 新增:退款操作按钮(仅退款中状态) -->
|
||||
<view class="refund-actions" wx:if="{{jibenShuju.zhuangtai == 4}}">
|
||||
<view class="action-btn action-cancel" bindtap="showCancelTuikuan">撤销退款申请</view>
|
||||
<view class="action-btn action-modify" bindtap="showModifyTuikuan">修改退款理由</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 打手信息卡片,仅当打手ID存在时显示 -->
|
||||
<view class="card dashou-card" wx:if="{{dashouInfo.yonghuid}}">
|
||||
<view class="card-title">服务打手</view>
|
||||
<view class="dashou-header">
|
||||
<!-- 打手头像,圆形 -->
|
||||
<image class="dashou-avatar" src="{{dashouInfo.avatar || '/images/default-avatar.png'}}" mode="aspectFill"/>
|
||||
<view class="dashou-detail">
|
||||
<!-- 打手昵称 -->
|
||||
<text class="dashou-nicheng">{{dashouInfo.nicheng || '未知昵称'}}</text>
|
||||
<!-- 打手用户ID行,可复制 -->
|
||||
<view class="dashou-id-row"><text class="label">用户ID</text><text class="value">{{dashouInfo.yonghuid}}</text><text class="copy-btn" bindtap="fuzhiWenben" data-text="{{dashouInfo.yonghuid}}">📋</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务详情卡片,展示交付图片、留言、退款理由等 -->
|
||||
<view class="card service-card" wx:if="{{xiangxiShuju.dashou_jiaofu.length > 0 || xiangxiShuju.dashou_liuyan || xiangxiShuju.tuikuan_liyou || xiangxiShuju.shangjia_liuyan}}">
|
||||
<view class="card-title">服务详情</view>
|
||||
<!-- 交付图片区域:使用 grid-img-wrapper 实现正方形九宫格 -->
|
||||
<block wx:if="{{xiangxiShuju.dashou_jiaofu.length > 0}}">
|
||||
<view class="sub-title">交付图片</view>
|
||||
<view class="image-grid">
|
||||
<!-- 循环渲染每张交付图片 -->
|
||||
<block wx:for="{{xiangxiShuju.dashou_jiaofu}}" wx:key="index">
|
||||
<!-- 正方形容器 -->
|
||||
<view class="grid-img-wrapper">
|
||||
<!-- 图片绝对定位填充容器 -->
|
||||
<image class="grid-img" src="{{item}}" mode="aspectFill" bindtap="yulanTupian" data-url="{{item}}" data-urls="{{xiangxiShuju.dashou_jiaofu}}"/>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 打手留言 -->
|
||||
<block wx:if="{{xiangxiShuju.dashou_liuyan}}">
|
||||
<view class="sub-title">打手留言</view>
|
||||
<view class="content-box">{{xiangxiShuju.dashou_liuyan}}</view>
|
||||
</block>
|
||||
<!-- 退款理由 -->
|
||||
<block wx:if="{{xiangxiShuju.tuikuan_liyou}}">
|
||||
<view class="sub-title">退款理由</view>
|
||||
<view class="content-box">{{xiangxiShuju.tuikuan_liyou}}</view>
|
||||
</block>
|
||||
<!-- 商家留言 -->
|
||||
<block wx:if="{{xiangxiShuju.shangjia_liuyan}}">
|
||||
<view class="sub-title">商家留言</view>
|
||||
<view class="content-box">{{xiangxiShuju.shangjia_liuyan}}</view>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 罚款信息卡片,仅当罚单数据存在时显示 -->
|
||||
<view class="card fakuan-card" wx:if="{{fadanData}}">
|
||||
<view class="card-title">罚款信息</view>
|
||||
<!-- 罚款金额,红色显示 -->
|
||||
<view class="info-row"><text class="label">罚款金额</text><text class="value price-red">¥{{fadanData.fakuanjine || '0.00'}}</text></view>
|
||||
<!-- 罚款理由 -->
|
||||
<view class="info-row"><text class="label">罚款理由</text><text class="value">{{fadanData.chufaliyou || '-'}}</text></view>
|
||||
<!-- 是否影响抢单 -->
|
||||
<view class="info-row"><text class="label">是否影响抢单</text><text class="value">{{fadanData.yingxiang_qiangdan == 1 ? '是' : '否'}}</text></view>
|
||||
<!-- 罚单状态 -->
|
||||
<view class="info-row"><text class="label">罚单状态</text><text class="value">{{fadanData.zhuangtai == 1 ? '待缴纳' : fadanData.zhuangtai == 2 ? '已缴纳' : fadanData.zhuangtai == 3 ? '申诉中' : '已驳回'}}</text></view>
|
||||
<!-- 如果有申诉理由,显示 -->
|
||||
<block wx:if="{{fadanData.shensuliyou}}"><view class="sub-title">申诉理由</view><view class="content-box">{{fadanData.shensuliyou}}</view></block>
|
||||
<!-- 如果有同意处罚理由,显示 -->
|
||||
<block wx:if="{{fadanData.tongyi_chufaliyou}}"><view class="sub-title">同意处罚理由</view><view class="content-box">{{fadanData.tongyi_chufaliyou}}</view></block>
|
||||
<!-- 如果有驳回理由,显示 -->
|
||||
<block wx:if="{{fadanData.bohuiliyou}}"><view class="sub-title">驳回理由</view><view class="content-box">{{fadanData.bohuiliyou}}</view></block>
|
||||
<!-- 创建时间 -->
|
||||
<view class="info-row"><text class="label">创建时间</text><text class="value">{{fadanData.create_time}}</text></view>
|
||||
<!-- 更新时间 -->
|
||||
<view class="info-row"><text class="label">更新时间</text><text class="value">{{fadanData.update_time}}</text></view>
|
||||
<!-- 新增:罚单操作按钮区域(根据状态显示) -->
|
||||
<view class="fakuan-actions" wx:if="{{fadanData}}">
|
||||
<!-- 待缴纳(1) 或 申诉中(3):显示修改和撤销按钮 -->
|
||||
<block wx:if="{{fadanData.zhuangtai == 1 || fadanData.zhuangtai == 3}}">
|
||||
<view class="action-btn action-modify" bindtap="showModifyFakuan">修改罚款</view>
|
||||
<view class="action-btn action-cancel" bindtap="showCancelFakuan">撤销罚款</view>
|
||||
</block>
|
||||
<!-- 已驳回(4):显示再次申请按钮 -->
|
||||
<block wx:if="{{fadanData.zhuangtai == 4}}">
|
||||
<view class="action-btn action-resubmit" bindtap="showResubmitFakuan">再次申请罚款</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 更换打手后生成的新订单ID展示卡片 -->
|
||||
<view class="card new-order-card" wx:if="{{xinDingdanId}}">
|
||||
<view class="card-title">更换打手成功</view>
|
||||
<view class="info-row"><text class="label">新订单ID</text><view class="value-with-copy"><text class="value">{{xinDingdanId}}</text><text class="copy-btn" bindtap="fuzhiWenben" data-text="{{xinDingdanId}}">📋</text></view></view>
|
||||
</view>
|
||||
|
||||
<!-- 结算区域卡片,仅当订单状态为8(结算中)时显示 -->
|
||||
<view class="card jiesuan-card" wx:if="{{jibenShuju.zhuangtai == 8}}">
|
||||
<view class="card-title">订单结算</view>
|
||||
<view class="star-row">
|
||||
<text class="label">打星评分</text>
|
||||
<view class="stars">
|
||||
<!-- 循环渲染五颗星星 -->
|
||||
<block wx:for="{{xingxingData}}" wx:key="id">
|
||||
<!-- 点击星星触发评分 -->
|
||||
<text class="star {{item.active ? 'star-active' : ''}}" bindtap="dianjiXingxing" data-index="{{index+1}}">{{item.active ? '★' : '☆'}}</text>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 结算留言输入框 -->
|
||||
<textarea class="liuyan-input" placeholder="留言(选填,50字)" maxlength="50" value="{{jiesuanLiuyan}}" bindinput="shuruLiuyan"/>
|
||||
<!-- 结算按钮 -->
|
||||
<view class="jiesuan-btn" bindtap="showJiesuanConfirm">立即结算</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部固定操作栏 -->
|
||||
<view class="bottom-bar">
|
||||
<!-- 第一行按钮:联系客服、联系打手 -->
|
||||
<view class="bottom-btn-group">
|
||||
<view class="btn-outline" bindtap="goToKefu">联系客服</view>
|
||||
<view class="btn-outline" bindtap="goToChatWithDashou" wx:if="{{dashouInfo.yonghuid}}">联系打手</view>
|
||||
</view>
|
||||
<!-- 第二行按钮:各种操作按钮,根据订单状态显示 -->
|
||||
<view class="bottom-btn-group">
|
||||
<!-- 撤销按钮:状态为1或7时显示 -->
|
||||
<view class="btn-warn" bindtap="showChexiaoBtn" wx:if="{{jibenShuju.zhuangtai == 1 || jibenShuju.zhuangtai == 7}}">撤销订单</view>
|
||||
<!-- 【暂时隐藏】更换打手按钮:恢复时取消下面整段注释即可 -->
|
||||
<!-- <view class="btn-primary" bindtap="showGhDashouConfirm" wx:if="{{(jibenShuju.zhuangtai == 2 || jibenShuju.zhuangtai == 8) && dashouInfo.yonghuid}}">更换打手</view> -->
|
||||
<!-- 申请退款按钮:状态为2或8时显示 -->
|
||||
<view class="btn-danger" bindtap="showTuikuanBtn" wx:if="{{jibenShuju.zhuangtai == 2 || jibenShuju.zhuangtai == 8}}">申请退款</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 撤销订单弹窗 -->
|
||||
<view class="modal" wx:if="{{showChexiaoModal}}">
|
||||
<view class="modal-mask" bindtap="closeChexiaoModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">撤销订单<text class="modal-close" bindtap="closeChexiaoModal">×</text></view>
|
||||
<textarea class="modal-input" placeholder="输入撤销原因(最多50字)" maxlength="50" value="{{chexiaoLiyou}}" bindinput="shuruChexiaoLiyou"/>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeChexiaoModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="tijiaoChexiao">{{isChexiaoLoading ? '处理中' : '确认撤销'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 申请退款弹窗 -->
|
||||
<view class="modal" wx:if="{{showTuikuanModal}}">
|
||||
<view class="modal-mask" bindtap="closeTuikuanModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">申请退款<text class="modal-close" bindtap="closeTuikuanModal">×</text></view>
|
||||
<textarea class="modal-input" placeholder="输入退款原因(最多50字)" maxlength="50" value="{{tuikuanLiyou}}" bindinput="shuruTuikuanLiyou"/>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeTuikuanModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="tijiaoTuikuan">{{isTuikuanLoading ? '处理中' : '确认申请'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 更换打手确认弹窗 -->
|
||||
<view class="modal" wx:if="{{showGhDashouModal}}">
|
||||
<view class="modal-mask" bindtap="closeGhDashouModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">更换打手<text class="modal-close" bindtap="closeGhDashouModal">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">确认更换打手吗?当前订单将被撤销,并生成一条相同内容的新订单(打手清空)。</text>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeGhDashouModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="tijiaoGhDashou">{{isGhDashouLoading ? '处理中' : '确认更换'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 申请罚款弹窗 -->
|
||||
<view class="modal" wx:if="{{showFakuanModal}}">
|
||||
<view class="modal-mask" bindtap="closeFakuanModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">申请罚款<text class="modal-close" bindtap="closeFakuanModal">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">罚款原因</text>
|
||||
<textarea class="modal-input" placeholder="输入罚款原因(最多50字)" maxlength="50" value="{{fakuanLiyou}}" bindinput="inputFakuanLiyou"/>
|
||||
<text class="modal-tip">罚款金额</text>
|
||||
<input class="modal-input-num" type="digit" placeholder="0.00" value="{{fakuanJine}}" bindinput="inputFakuanJine"/>
|
||||
<view class="toggle-row" bindtap="toggleQiangdan">
|
||||
<text class="label">是否影响抢单</text>
|
||||
<view class="toggle {{yingxiangQiangdan ? 'toggle-on' : ''}}">
|
||||
<view class="toggle-knob"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="fenhong-tip">此次罚款应得分红:¥{{jisuanFenhong()}}(利率 {{fenhongLilv*100}}%)</view>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeFakuanModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="tijiaoFakuan">{{isFakuanLoading ? '处理中' : '确认申请'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 结算确认弹窗 -->
|
||||
<view class="modal" wx:if="{{showJiesuanConfirm}}">
|
||||
<view class="modal-mask" bindtap="closeJiesuanConfirm"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">确认结算<text class="modal-close" bindtap="closeJiesuanConfirm">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">确认结算该订单吗?结算后状态变为“已完成”。</text>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeJiesuanConfirm">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="tijiaoJiesuan">{{isJiesuanLoading ? '处理中' : '确认结算'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- ========== 新增:修改罚款弹窗 ========== -->
|
||||
<view class="modal" wx:if="{{showModifyFakuanModal}}">
|
||||
<view class="modal-mask" bindtap="closeModifyFakuanModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">修改罚款<text class="modal-close" bindtap="closeModifyFakuanModal">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">罚款理由</text>
|
||||
<textarea class="modal-input" placeholder="输入罚款理由" maxlength="100" value="{{modifyFakuanLiyou}}" bindinput="inputModifyFakuanLiyou"/>
|
||||
<text class="modal-tip">罚款金额</text>
|
||||
<input class="modal-input-num" type="digit" placeholder="0.00" value="{{modifyFakuanJine}}" bindinput="inputModifyFakuanJine"/>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeModifyFakuanModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="submitModifyFakuan">确认修改</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 撤销罚款弹窗 -->
|
||||
<view class="modal" wx:if="{{showCancelFakuanModal}}">
|
||||
<view class="modal-mask" bindtap="closeCancelFakuanModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">撤销罚款<text class="modal-close" bindtap="closeCancelFakuanModal">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">驳回理由</text>
|
||||
<textarea class="modal-input" placeholder="输入驳回理由" maxlength="100" value="{{cancelFakuanLiyou}}" bindinput="inputCancelFakuanLiyou"/>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeCancelFakuanModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="submitCancelFakuan">确认撤销</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 再次申请罚款弹窗 -->
|
||||
<view class="modal" wx:if="{{showResubmitFakuanModal}}">
|
||||
<view class="modal-mask" bindtap="closeResubmitFakuanModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">再次申请罚款<text class="modal-close" bindtap="closeResubmitFakuanModal">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">罚款理由</text>
|
||||
<textarea class="modal-input" placeholder="输入罚款理由" maxlength="100" value="{{resubmitFakuanLiyou}}" bindinput="inputResubmitFakuanLiyou"/>
|
||||
<text class="modal-tip">罚款金额</text>
|
||||
<input class="modal-input-num" type="digit" placeholder="0.00" value="{{resubmitFakuanJine}}" bindinput="inputResubmitFakuanJine"/>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeResubmitFakuanModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="submitResubmitFakuan">确认申请</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 撤销退款申请弹窗 -->
|
||||
<view class="modal" wx:if="{{showCancelTuikuanModal}}">
|
||||
<view class="modal-mask" bindtap="closeCancelTuikuanModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">撤销退款申请<text class="modal-close" bindtap="closeCancelTuikuanModal">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">撤销理由</text>
|
||||
<textarea class="modal-input" placeholder="输入撤销理由" maxlength="100" value="{{cancelTuikuanLiyou}}" bindinput="inputCancelTuikuanLiyou"/>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeCancelTuikuanModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="submitCancelTuikuan">确认撤销</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 修改退款理由弹窗 -->
|
||||
<view class="modal" wx:if="{{showModifyTuikuanModal}}">
|
||||
<view class="modal-mask" bindtap="closeModifyTuikuanModal"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-hd">修改退款理由<text class="modal-close" bindtap="closeModifyTuikuanModal">×</text></view>
|
||||
<view class="modal-body">
|
||||
<text class="modal-tip">退款理由</text>
|
||||
<textarea class="modal-input" placeholder="输入新的退款理由" maxlength="100" value="{{modifyTuikuanLiyou}}" bindinput="inputModifyTuikuanLiyou"/>
|
||||
</view>
|
||||
<view class="modal-btns">
|
||||
<view class="modal-btn cancel" bindtap="closeModifyTuikuanModal">取消</view>
|
||||
<view class="modal-btn confirm" bindtap="submitModifyTuikuan">确认修改</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 全局通知组件 -->
|
||||
<global-notification id="global-notification" />
|
||||
|
||||
<!-- 教程按钮(紧贴右侧,右上角,5秒后缩进) -->
|
||||
<view
|
||||
class="tutorial-btn {{tutorialBtnHidden ? 'tutorial-btn-hidden' : ''}}"
|
||||
bindtap="onTutorialBtnTap"
|
||||
hover-class="tutorial-btn-hover"
|
||||
>
|
||||
<text class="tutorial-btn-text">教程</text>
|
||||
</view>
|
||||
|
||||
<!-- 使用教程弹窗组件 -->
|
||||
<popup-notice id="popupNotice" />
|
||||
</view>
|
||||
185
miniprogram/pages/sjddxq/sjddxq.wxss
Normal file
185
miniprogram/pages/sjddxq/sjddxq.wxss
Normal file
@@ -0,0 +1,185 @@
|
||||
/* pages/sjddxq/sjddxq.wxss - 商家订单详情页样式(正方形九宫格,圆形头像) */
|
||||
/* 页面全局背景 */
|
||||
page { background: #f5f7fa; }
|
||||
/* 页面底部留出固定栏的空间 */
|
||||
.sjddxq-page { padding-bottom: 160rpx; }
|
||||
|
||||
/* 加载状态居中布局 */
|
||||
.loading-container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 60vh; }
|
||||
/* 加载旋转动画图标 */
|
||||
.loading-spinner { width: 64rpx; height: 64rpx; border: 6rpx solid #e0e0e0; border-top-color: #4caf50; border-radius: 50%; animation: spin 1s linear infinite; margin-bottom: 20rpx; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
/* 加载文字 */
|
||||
.loading-text { color: #666; font-size: 28rpx; }
|
||||
|
||||
/* 内容区域的内边距 */
|
||||
.content-container { padding: 24rpx; }
|
||||
|
||||
/* 通用卡片样式 */
|
||||
.card { background: #fff; border-radius: 24rpx; padding: 28rpx; margin-bottom: 24rpx; box-shadow: 0 8rpx 24rpx rgba(0,0,0,0.04); }
|
||||
/* 卡片标题样式 */
|
||||
.card-title { font-size: 32rpx; font-weight: 600; color: #1a1a1a; margin-bottom: 20rpx; padding-bottom: 12rpx; border-bottom: 1rpx solid #f0f0f0; }
|
||||
|
||||
/* 商品卡片:左右布局 */
|
||||
.shangpin-card { display: flex; align-items: center; }
|
||||
/* 商品图片:固定宽高为正方形 */
|
||||
.shangpin-img { width: 180rpx; height: 180rpx; border-radius: 16rpx; background: #f5f5f5; margin-right: 24rpx; flex-shrink: 0; }
|
||||
.shangpin-text { flex: 1; }
|
||||
.jieshao-text { font-size: 28rpx; color: #333; line-height: 1.6; }
|
||||
|
||||
/* 信息行:左右分布,底部虚线 */
|
||||
.info-row { display: flex; justify-content: space-between; align-items: center; padding: 14rpx 0; border-bottom: 1rpx dashed #f5f5f5; }
|
||||
.info-row:last-child { border-bottom: none; }
|
||||
.label { font-size: 28rpx; color: #888; min-width: 140rpx; }
|
||||
.value { font-size: 28rpx; color: #333; text-align: right; word-break: break-all; }
|
||||
.value-with-copy { display: flex; align-items: center; }
|
||||
/* 复制按钮 */
|
||||
.copy-btn { margin-left: 12rpx; color: #4caf50; font-size: 26rpx; padding: 4rpx 12rpx; background: #e8f5e9; border-radius: 16rpx; }
|
||||
/* 红色价格 */
|
||||
.price-red { color: #ff4444; font-weight: 600; }
|
||||
.zhuangtai-text { font-weight: 600; }
|
||||
|
||||
/* 打手卡片头部 */
|
||||
.dashou-header { display: flex; align-items: center; }
|
||||
/* 打手头像:固定宽高,圆形 */
|
||||
.dashou-avatar { width: 88rpx; height: 88rpx; border-radius: 50%; margin-right: 20rpx; }
|
||||
.dashou-detail { flex: 1; }
|
||||
.dashou-nicheng { font-size: 30rpx; font-weight: 500; margin-bottom: 6rpx; }
|
||||
.dashou-id-row { display: flex; align-items: center; font-size: 26rpx; }
|
||||
|
||||
/* 服务详情子标题 */
|
||||
.sub-title { font-size: 28rpx; color: #555; margin: 16rpx 0 8rpx; }
|
||||
/* 内容框(留言、理由等) */
|
||||
.content-box { background: #f9f9f9; border-radius: 12rpx; padding: 16rpx; font-size: 26rpx; color: #444; line-height: 1.5; margin-bottom: 16rpx; }
|
||||
|
||||
/* ========= 核心:交付图片九宫格,强制正方形 ========= */
|
||||
.image-grid { display: flex; flex-wrap: wrap; margin-bottom: 16rpx; }
|
||||
/* 每个图片的外层容器 */
|
||||
.grid-img-wrapper {
|
||||
width: calc(33.33% - 8rpx); /* 每行三个,减去间距 */
|
||||
margin: 4rpx;
|
||||
position: relative; /* 为绝对定位的图片提供锚点 */
|
||||
overflow: hidden;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
/* 使用伪元素撑出 1:1 的正方形高度 */
|
||||
.grid-img-wrapper::after {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-bottom: 100%; /* 100% 相对于自身宽度,实现正方形 */
|
||||
}
|
||||
/* 图片绝对定位填满整个容器 */
|
||||
.grid-img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover; /* 保持比例裁剪,不变形 */
|
||||
}
|
||||
|
||||
/* 结算区域:星星评分 */
|
||||
.star-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20rpx; }
|
||||
.stars { display: flex; }
|
||||
.star { font-size: 48rpx; color: #ccc; margin-left: 8rpx; transition: all 0.2s; }
|
||||
.star-active { color: #ffc107; transform: scale(1.1); }
|
||||
/* 留言输入框 */
|
||||
.liuyan-input { width: 100%; height: 120rpx; background: #f9f9f9; border-radius: 12rpx; padding: 16rpx; font-size: 28rpx; margin-bottom: 20rpx; }
|
||||
/* 结算按钮 */
|
||||
.jiesuan-btn { background: #4caf50; color: #fff; text-align: center; padding: 20rpx; border-radius: 48rpx; font-size: 30rpx; font-weight: 600; margin-top: 10rpx; }
|
||||
|
||||
/* 底部固定操作栏 */
|
||||
.bottom-bar { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; padding: 16rpx 24rpx; box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.06); display: flex; flex-direction: column; gap: 12rpx; z-index: 100; }
|
||||
.bottom-btn-group { display: flex; gap: 16rpx; }
|
||||
.btn-outline { flex: 1; text-align: center; padding: 18rpx 0; border-radius: 44rpx; font-size: 28rpx; font-weight: 500; border: 2rpx solid #1976D2; color: #1976D2; background: #fff; }
|
||||
.btn-primary { background: #2196F3; color: #fff; flex: 1; text-align: center; padding: 18rpx 0; border-radius: 44rpx; font-weight: 600; font-size: 28rpx; }
|
||||
.btn-warn { background: #ff9800; color: #fff; flex: 1; text-align: center; padding: 18rpx 0; border-radius: 44rpx; font-weight: 600; font-size: 28rpx; }
|
||||
.btn-danger { background: #f44336; color: #fff; flex: 1; text-align: center; padding: 18rpx 0; border-radius: 44rpx; font-weight: 600; font-size: 28rpx; }
|
||||
|
||||
/* 弹窗通用样式 */
|
||||
.modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; }
|
||||
.modal-mask { position: absolute; width: 100%; height: 100%; background: rgba(0,0,0,0.45); }
|
||||
.modal-content { position: relative; width: 620rpx; background: #fff; border-radius: 32rpx; overflow: hidden; }
|
||||
.modal-hd { padding: 32rpx; font-size: 34rpx; font-weight: 600; display: flex; justify-content: space-between; border-bottom: 1rpx solid #f0f0f0; }
|
||||
.modal-close { color: #999; font-size: 40rpx; }
|
||||
.modal-body { padding: 32rpx; }
|
||||
.modal-tip { font-size: 28rpx; color: #555; margin-bottom: 12rpx; }
|
||||
.modal-input { width: 100%; height: 140rpx; background: #f5f5f5; border-radius: 12rpx; padding: 16rpx; font-size: 28rpx; margin-bottom: 20rpx; }
|
||||
.modal-input-num { width: 100%; height: 80rpx; background: #f5f5f5; border-radius: 12rpx; padding: 0 20rpx; font-size: 32rpx; margin-bottom: 20rpx; }
|
||||
.toggle-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20rpx; }
|
||||
.toggle { width: 100rpx; height: 50rpx; border-radius: 50rpx; background: #e0e0e0; display: flex; align-items: center; padding: 0 4rpx; transition: background 0.2s; }
|
||||
.toggle-on { background: #4caf50; }
|
||||
.toggle-knob { width: 42rpx; height: 42rpx; border-radius: 50%; background: #fff; transition: transform 0.2s; }
|
||||
.toggle-on .toggle-knob { transform: translateX(50rpx); }
|
||||
.fenhong-tip { text-align: center; font-size: 28rpx; color: #ff9800; margin: 16rpx 0 0; }
|
||||
.modal-btns { display: flex; border-top: 1rpx solid #f0f0f0; }
|
||||
.modal-btn { flex: 1; text-align: center; padding: 28rpx; font-size: 30rpx; font-weight: 500; }
|
||||
.modal-btn.cancel { color: #888; background: #f5f5f5; }
|
||||
.modal-btn.confirm { color: #4caf50; background: #e8f5e9; }
|
||||
|
||||
|
||||
|
||||
|
||||
/* ========== 新增:罚单/订单操作按钮样式 ========== */
|
||||
.fakuan-actions, .refund-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-top: 24rpx;
|
||||
padding-top: 16rpx;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
}
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 16rpx 0;
|
||||
border-radius: 44rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
.action-modify {
|
||||
background: #2196F3;
|
||||
color: #fff;
|
||||
}
|
||||
.action-cancel {
|
||||
background: #ff9800;
|
||||
color: #fff;
|
||||
}
|
||||
.action-resubmit {
|
||||
background: #4caf50;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ========== 新增:教程按钮样式 ========== */
|
||||
.tutorial-btn {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 20%;
|
||||
transform: translateY(-50%);
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
backdrop-filter: blur(15rpx);
|
||||
border-radius: 60rpx 0 0 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10001;
|
||||
box-shadow: -8rpx 0 20rpx rgba(0,0,0,0.3);
|
||||
transition: right 0.3s ease-out;
|
||||
border: 2rpx solid rgba(255,215,0,0.5);
|
||||
border-right: none;
|
||||
}
|
||||
.tutorial-btn-text {
|
||||
color: #FFD700;
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
writing-mode: vertical-rl;
|
||||
letter-spacing: 6rpx;
|
||||
}
|
||||
.tutorial-btn-hidden {
|
||||
right: -80rpx;
|
||||
}
|
||||
.tutorial-btn-hover {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
transform: translateY(-50%) scale(1.05);
|
||||
}
|
||||
Reference in New Issue
Block a user