chore: 抢单端UI回退前备份当前完整工作区

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-29 17:59:23 +08:00
parent 6e2f7bc39f
commit e8fb32c1fe
53 changed files with 3410 additions and 1065 deletions

View File

@@ -10,6 +10,7 @@ import { reconnectForRole } from '../../utils/role-tab-bar.js';
import { ensurePhoneAuth } from '../../utils/phone-auth.js';
import { fetchGonggaoLunbo, isGonggaoCacheValid } from '../../utils/display-config.js';
import { checkPenaltyForGrab } from '../../utils/grab-order-gate.js';
import { fetchMyZhidingOrders, submitZhidingResponse, processZhidingList, filterZhidingBannerList, ZHIDING_HF_MAP } from '../../utils/zhiding-order.js';
Page({
data: {
@@ -58,9 +59,25 @@ Page({
examRequired: false,
examPassed: false,
_examChecked: false,
myZhidingList: [],
highlightOrderId: '',
myZhidingCount: 0,
defaultAvatarUrl: '',
showZhidingDetail: false,
zhidingDetailOrder: null,
showLaterModal: false,
laterOrderId: '',
laterNote: '',
},
async onLoad() {
async onLoad(options) {
const defAvatar = getDefaultAvatarUrl(app);
const highlight = (options && options.highlight) ? String(options.highlight) : '';
this.setData({ defaultAvatarUrl: defAvatar, highlightOrderId: highlight });
if (options && options.highlight) {
this._pendingHighlight = String(options.highlight);
}
if (app.globalData._acceptOrderSessionReady && app.globalData._acceptOrderPageCache) {
const cache = { ...app.globalData._acceptOrderPageCache };
this.data.shangpinleixing = cache.shangpinleixing || [];
@@ -90,6 +107,7 @@ Page({
}
this.persistPageCache();
this._skipShowRefresh = true;
await this.loadMyZhidingOrders(true);
return;
}
@@ -97,6 +115,7 @@ Page({
const banner = await this.loadGonggaoAndLunbo(false);
await this.syncDashouProfileFromServer();
await this.loadShangpinLeixing(true, false, false);
await this.loadMyZhidingOrders(true);
this.persistPageCache(banner);
app.globalData._acceptOrderSessionReady = true;
@@ -149,6 +168,16 @@ Page({
await this.checkExamStatus(false);
this.setData({ defaultAvatarUrl: getDefaultAvatarUrl(app) });
await this.loadMyZhidingOrders(true);
const hl = app.globalData._acceptOrderHighlight;
if (hl) {
app.globalData._acceptOrderHighlight = '';
this.setData({ highlightOrderId: hl });
await this.loadMyZhidingOrders(true);
}
if (this._skipShowRefresh) {
this._skipShowRefresh = false;
return;
@@ -172,6 +201,7 @@ Page({
await this.loadDingdanList(true, true);
await this.loadBankuaiBiaoqian();
}
await this.loadMyZhidingOrders(true);
this.loadGlobalStatus();
this.persistPageCache(banner);
} catch (e) {
@@ -464,8 +494,11 @@ Page({
}
const isZhiding = item.zhuangtai === 7;
const uid = this.data.uid;
const isMyZhiding = isZhiding && uid && String(item.zhiding_uid) === String(uid);
let zhidingAvatar = '';
const defAvatar = getDefaultAvatarUrl(app);
let zhidingAvatar = defAvatar;
if (item.zhiding_avatar) {
zhidingAvatar = !item.zhiding_avatar.startsWith('http')
? ossUrl + item.zhiding_avatar
@@ -493,6 +526,11 @@ Page({
leixing_icon_url: fullTupianUrl,
shangjia_avatar_full: shangjiaAvatar,
isZhiding: isZhiding,
isMyZhiding,
isHighlighted: this.data.highlightOrderId && item.dingdan_id === this.data.highlightOrderId,
zhiding_hf: item.zhiding_hf,
zhiding_hf_text: item.zhiding_hf_text || ZHIDING_HF_MAP[item.zhiding_hf] || '',
zhiding_dhj_sm: item.zhiding_dhj_sm || '',
isPingtai: item.pingtai == 1,
isShangjia: item.pingtai == 2,
zhiding_avatar_full: zhidingAvatar,
@@ -684,6 +722,7 @@ Page({
);
that.setData({ dingdanList: newList });
that.persistPageCache();
that.loadMyZhidingOrders(true);
} else {
wx.showToast({
title: qiangdanRes.data.msg || '抢单失败',
@@ -714,6 +753,125 @@ Page({
});
},
async loadMyZhidingOrders(silent = false) {
if (!this.data.uid && !wx.getStorageSync('uid')) return;
try {
const raw = await fetchMyZhidingOrders();
const uid = this.data.uid || wx.getStorageSync('uid');
const highlight = this.data.highlightOrderId || this._pendingHighlight || '';
const list = filterZhidingBannerList(processZhidingList(raw, app, uid, highlight));
this.setData({ myZhidingList: list, myZhidingCount: list.length });
if (highlight && list.some((o) => o.dingdan_id === highlight)) {
this.setData({ highlightOrderId: highlight });
this._pendingHighlight = '';
}
} catch (e) {
if (!silent) console.warn('loadMyZhidingOrders', e);
}
},
openZhidingDetail(e) {
const item = e.currentTarget.dataset.item;
if (!item) return;
this.setData({ showZhidingDetail: true, zhidingDetailOrder: item });
},
closeZhidingDetail() {
this.setData({ showZhidingDetail: false, zhidingDetailOrder: null });
},
async onZhidingReject(e) {
const item = e.currentTarget.dataset.item;
if (!item) return;
wx.showModal({
title: '确认婉拒',
content: '婉拒后订单将退回抢单大厅,确定不想接此单吗?',
confirmText: '不想接',
confirmColor: '#e64340',
success: async (res) => {
if (!res.confirm) return;
wx.showLoading({ title: '提交中...', mask: true });
try {
const body = await submitZhidingResponse(item.dingdan_id, 2);
wx.hideLoading();
if (body && (body.code === 200 || body.code === 0)) {
wx.showToast({ title: body.msg || '已婉拒', icon: 'none' });
this.closeZhidingDetail();
await this.loadMyZhidingOrders(true);
await this.loadDingdanList(true, true);
} else {
wx.showToast({ title: body?.msg || '操作失败', icon: 'none' });
}
} catch (err) {
wx.hideLoading();
wx.showToast({ title: '网络错误', icon: 'none' });
}
},
});
},
onZhidingLater(e) {
const item = e.currentTarget.dataset.item;
if (!item) return;
this.setData({
showZhidingDetail: false,
zhidingDetailOrder: null,
showLaterModal: true,
laterOrderId: item.dingdan_id,
laterNote: item.zhiding_dhj_sm || '',
});
},
closeLaterModal() {
this.setData({ showLaterModal: false, laterOrderId: '', laterNote: '' });
},
onLaterNoteInput(e) {
this.setData({ laterNote: e.detail.value });
},
async confirmZhidingLater() {
const { laterOrderId, laterNote } = this.data;
if (!laterNote.trim()) {
wx.showToast({ title: '请填写预计接待时间', icon: 'none' });
return;
}
wx.showLoading({ title: '提交中...', mask: true });
try {
const body = await submitZhidingResponse(laterOrderId, 3, laterNote.trim());
wx.hideLoading();
if (body && (body.code === 200 || body.code === 0)) {
const note = laterNote.trim();
wx.showToast({ title: `已记录:${note}`, icon: 'none', duration: 3500 });
this.closeLaterModal();
this.closeZhidingDetail();
await this.loadMyZhidingOrders(true);
await this.loadDingdanList(true, true);
} else {
wx.showToast({ title: body?.msg || '操作失败', icon: 'none' });
}
} catch (e) {
wx.hideLoading();
wx.showToast({ title: '网络错误', icon: 'none' });
}
},
async onZhidingAccept(e) {
const item = e.currentTarget.dataset.item;
if (!item) return;
wx.showLoading({ title: '处理中...', mask: true });
try {
await submitZhidingResponse(item.dingdan_id, 1);
wx.hideLoading();
} catch (e) {
wx.hideLoading();
}
const processed = this.processDingdanItem(item);
this.onQiangdanTap({ currentTarget: { dataset: { item: processed } } });
},
noop() {},
onReachBottom() {
if (this.data.isLoading || this.data.isLoadingMore) return;
if (this.data.hasMore && !this.data.isLoading && this.data.xuanzhongLeixingId) {
@@ -744,6 +902,7 @@ Page({
await this.loadBankuaiBiaoqian();
await this.loadDingdanList(true);
}
await this.loadMyZhidingOrders(true);
this.loadGlobalStatus();
this.persistPageCache(banner);
} catch (e) {

View File

@@ -9,6 +9,7 @@
"backgroundColor": "#f5f3ff",
"usingComponents": {
"chenghao-tag": "/components/chenghao-tag/chenghao-tag",
"global-notification": "/components/global-notification/global-notification"
"global-notification": "/components/global-notification/global-notification",
"kefu-float": "/components/kefu-float/kefu-float"
}
}

View File

@@ -44,6 +44,32 @@
<text class="xym-gonggao-txt">{{gonggao}}</text>
</view>
<!-- 被指定订单提醒 -->
<view class="my-zhiding-banner" wx:if="{{myZhidingList.length > 0}}">
<view class="my-zhiding-banner-head">
<view class="my-zhiding-head-left">
<text class="my-zhiding-badge">指定给您</text>
<text class="my-zhiding-count-num">{{myZhidingCount || myZhidingList.length}}单</text>
</view>
<text class="my-zhiding-sub">请确认是否接待</text>
</view>
<view wx:for="{{myZhidingList}}" wx:key="dingdan_id" class="my-zhiding-card {{item.isHighlighted ? 'my-zhiding-card--highlight' : ''}}">
<view class="my-zhiding-card-main" data-item="{{item}}" bindtap="openZhidingDetail">
<view class="my-zhiding-card-top">
<text class="my-zhiding-order-id">单号 {{item.dingdan_id}}</text>
<text class="my-zhiding-reward">¥{{item.dashou_fencheng || 0}}</text>
</view>
<text class="my-zhiding-desc line2">{{item.jieshao || '暂无介绍'}}</text>
<text class="my-zhiding-status" wx:if="{{item.zhiding_hf_text}}">您的回复:{{item.zhiding_hf_text}}{{item.zhiding_dhj_sm ? ' · ' + item.zhiding_dhj_sm : ''}}</text>
</view>
<view class="my-zhiding-actions">
<view class="zhiding-act zhiding-act--ghost" data-item="{{item}}" catchtap="onZhidingReject">不想接</view>
<view class="zhiding-act zhiding-act--ghost" data-item="{{item}}" catchtap="onZhidingLater">等会接</view>
<view class="zhiding-act zhiding-act--primary" data-item="{{item}}" catchtap="onZhidingAccept">立即接待</view>
</view>
</view>
</view>
<!-- 商品轮播(只读 globalData与点单端同源 -->
<view class="xym-lunbo-container" wx:if="{{lunboList.length > 0}}">
@@ -182,7 +208,7 @@
<!-- 平台订单(逍遥梦卡片布局) -->
<view wx:if="{{item.isPingtai}}" class="xym-order-item xym-pingtai-order" data-item="{{item}}">
<view wx:if="{{item.isPingtai}}" class="xym-order-item xym-pingtai-order {{item.isMyZhiding ? 'order-my-zhiding' : ''}} {{item.isHighlighted ? 'order-zhiding-highlight' : ''}}" data-item="{{item}}">
<view class="xym-pingtai-head flexb">
@@ -212,7 +238,7 @@
<view class="zhiding-strip light">
<view class="zhiding-strip-top myflex">
<text class="zhiding-label">指定</text>
<image wx:if="{{item.zhiding_avatar_full}}" class="zhiding-avatar" src="{{item.zhiding_avatar_full}}" mode="aspectFill"/>
<image class="zhiding-avatar" src="{{item.zhiding_avatar_full || defaultAvatarUrl}}" mode="aspectFill"/>
<text class="zhiding-name">{{item.zhiding_nicheng || '指定接单员'}}</text>
</view>
<view wx:if="{{item.dashou_biaoqian.length > 0 || item.zhiding_identity_biaoqian.length > 0}}" class="zhiding-strip-tags">
@@ -258,7 +284,7 @@
<text class="o-amt light">平台派单</text>
<view class="qiangdan flexa btn-bg btn-qiang btn-qiang-brown" data-item="{{item}}" bindtap="onQiangdanTap">抢单</view>
<view class="qiangdan flexa btn-bg btn-qiang btn-qiang-brown" data-item="{{item}}" bindtap="onQiangdanTap">{{item.isMyZhiding ? '立即接待' : '抢单'}}</view>
</view>
@@ -271,7 +297,7 @@
<!-- 优质商家订单(金牌卡片) -->
<view wx:elif="{{item.isShangjia && item.shangjia_youzhi}}" class="xym-order-item gold-card" data-item="{{item}}">
<view wx:elif="{{item.isShangjia && item.shangjia_youzhi}}" class="xym-order-item gold-card {{item.isMyZhiding ? 'order-my-zhiding' : ''}} {{item.isHighlighted ? 'order-zhiding-highlight' : ''}}" data-item="{{item}}">
<view class="gold-head flexb">
<view class="kehuduan-banner-wrap">
<image class="gold-banner" src="https://bintao.xmxym88.com/xcx/bintao/82.png" mode="widthFix"/>
@@ -292,7 +318,7 @@
<view class="zhiding-strip">
<view class="zhiding-strip-top myflex">
<text class="zhiding-label">指定</text>
<image wx:if="{{item.zhiding_avatar_full}}" class="zhiding-avatar" src="{{item.zhiding_avatar_full}}" mode="aspectFill"/>
<image class="zhiding-avatar" src="{{item.zhiding_avatar_full || defaultAvatarUrl}}" mode="aspectFill"/>
<text class="zhiding-name">{{item.zhiding_nicheng || '指定接单员'}}</text>
</view>
<view wx:if="{{item.dashou_biaoqian.length > 0 || item.zhiding_identity_biaoqian.length > 0}}" class="zhiding-strip-tags">
@@ -336,7 +362,7 @@
<view class="m-sn m-sn-light">发布于 {{item.creat_time}}</view>
</view>
</view>
<view class="qiangdan flexa btn-bg btn-qiang" data-item="{{item}}" bindtap="onQiangdanTap">抢单</view>
<view class="qiangdan flexa btn-bg btn-qiang" data-item="{{item}}" bindtap="onQiangdanTap">{{item.isMyZhiding ? '立即接待' : '抢单'}}</view>
</view>
<view class="o-foot flexb kehuduan-foot gold-foot-text-only">
<text class="o-amt-grey">商家派单</text>
@@ -347,7 +373,7 @@
<!-- 商家订单(逍遥梦卡片布局) -->
<view wx:elif="{{item.isShangjia}}" class="xym-order-item xym-shangjia-order" data-item="{{item}}">
<view wx:elif="{{item.isShangjia}}" class="xym-order-item xym-shangjia-order {{item.isMyZhiding ? 'order-my-zhiding' : ''}} {{item.isHighlighted ? 'order-zhiding-highlight' : ''}}" data-item="{{item}}">
<view class="xym-shangjia-head flexb">
@@ -365,7 +391,7 @@
<view class="zhiding-strip">
<view class="zhiding-strip-top myflex">
<text class="zhiding-label">指定</text>
<image wx:if="{{item.zhiding_avatar_full}}" class="zhiding-avatar" src="{{item.zhiding_avatar_full}}" mode="aspectFill"/>
<image class="zhiding-avatar" src="{{item.zhiding_avatar_full || defaultAvatarUrl}}" mode="aspectFill"/>
<text class="zhiding-name">{{item.zhiding_nicheng || '指定接单员'}}</text>
</view>
<view wx:if="{{item.dashou_biaoqian.length > 0 || item.zhiding_identity_biaoqian.length > 0}}" class="zhiding-strip-tags">
@@ -442,7 +468,7 @@
<text class="o-amt">商家派单</text>
<view class="qiangdan flexa btn-bg btn-qiang" data-item="{{item}}" bindtap="onQiangdanTap">抢单</view>
<view class="qiangdan flexa btn-bg btn-qiang" data-item="{{item}}" bindtap="onQiangdanTap">{{item.isMyZhiding ? '立即接待' : '抢单'}}</view>
</view>
@@ -482,8 +508,58 @@
<global-notification id="global-notification" />
<kefu-float bottom="200rpx" />
<popup-notice id="popupNotice" />
<!-- 指定单详情 -->
<view class="zhiding-modal-mask" wx:if="{{showZhidingDetail}}" catchtap="closeZhidingDetail">
<view class="zhiding-modal" catchtap="noop">
<view class="zhiding-modal-head">
<text class="zhiding-modal-title">指定订单详情</text>
<text class="zhiding-modal-close" catchtap="closeZhidingDetail">×</text>
</view>
<view class="zhiding-modal-body" wx:if="{{zhidingDetailOrder}}">
<view class="zhiding-modal-row"><text class="lbl">单号</text><text>{{zhidingDetailOrder.dingdan_id}}</text></view>
<view class="zhiding-modal-row"><text class="lbl">分成</text><text class="reward">¥{{zhidingDetailOrder.dashou_fencheng || 0}}</text></view>
<view class="zhiding-modal-row col"><text class="lbl">介绍</text><text>{{zhidingDetailOrder.jieshao || '暂无'}}</text></view>
<view class="zhiding-modal-row col" wx:if="{{zhidingDetailOrder.beizhu}}"><text class="lbl">备注</text><text>{{zhidingDetailOrder.beizhu}}</text></view>
<view class="zhiding-modal-row" wx:if="{{zhidingDetailOrder.zhiding_hf_text}}"><text class="lbl">您的回复</text><text>{{zhidingDetailOrder.zhiding_hf_text}}</text></view>
</view>
<view class="my-zhiding-actions zhiding-modal-actions" wx:if="{{zhidingDetailOrder}}">
<view class="zhiding-act zhiding-act--ghost" data-item="{{zhidingDetailOrder}}" catchtap="onZhidingReject">不想接</view>
<view class="zhiding-act zhiding-act--ghost" data-item="{{zhidingDetailOrder}}" catchtap="onZhidingLater">等会接</view>
<view class="zhiding-act zhiding-act--primary" data-item="{{zhidingDetailOrder}}" catchtap="onZhidingAccept">立即接待</view>
</view>
</view>
</view>
<!-- 等会接时间 -->
<view class="zhiding-modal-mask zhiding-modal-mask--top" wx:if="{{showLaterModal}}" catchtap="closeLaterModal">
<view class="zhiding-modal zhiding-modal--sm" catchtap="noop">
<view class="zhiding-modal-head">
<text class="zhiding-modal-title">等会接</text>
<text class="zhiding-modal-close" catchtap="closeLaterModal">×</text>
</view>
<view class="zhiding-modal-body">
<text class="later-hint">请填写预计接待时间例如「30分钟后」「今晚8点」</text>
<input
class="later-input"
placeholder="预计接待时间"
placeholder-class="later-input-ph"
value="{{laterNote}}"
bindinput="onLaterNoteInput"
maxlength="50"
focus="{{showLaterModal}}"
adjust-position="{{true}}"
confirm-type="done"
bindconfirm="confirmZhidingLater"
/>
</view>
<view class="later-confirm" catchtap="confirmZhidingLater">确认</view>
</view>
</view>
<tab-bar />
</view>

View File

@@ -770,3 +770,180 @@ page {
margin-left: auto;
max-width: 50%;
}
/* 被指定订单 */
.my-zhiding-banner {
margin: 16rpx 24rpx 0;
padding: 22rpx;
border-radius: 20rpx;
background: linear-gradient(135deg, #ff9500 0%, #ff6b00 100%);
border: 3rpx solid #ff4500;
box-shadow: 0 12rpx 32rpx rgba(255, 69, 0, 0.45);
position: relative;
z-index: 20;
}
.my-zhiding-banner-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16rpx;
}
.my-zhiding-head-left {
display: flex;
align-items: center;
gap: 12rpx;
}
.my-zhiding-badge {
font-size: 26rpx;
font-weight: 800;
color: #ff4500;
background: #fff;
padding: 8rpx 18rpx;
border-radius: 999rpx;
}
.my-zhiding-count-num {
font-size: 32rpx;
font-weight: 800;
color: #fff;
}
.my-zhiding-sub {
font-size: 26rpx;
color: #fff;
font-weight: 700;
}
.my-zhiding-card {
background: #fff;
border-radius: 16rpx;
padding: 18rpx;
margin-bottom: 12rpx;
border: 2rpx solid #ffe0b2;
}
.my-zhiding-card--highlight {
border-color: #ff8c00;
box-shadow: 0 0 0 4rpx rgba(255, 140, 0, 0.15);
}
.my-zhiding-card-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8rpx;
}
.my-zhiding-order-id {
font-size: 24rpx;
color: #666;
}
.my-zhiding-reward {
font-size: 30rpx;
font-weight: 700;
color: #e64340;
}
.my-zhiding-desc {
font-size: 28rpx;
color: #333;
line-height: 1.5;
}
.my-zhiding-status {
display: block;
margin-top: 8rpx;
font-size: 24rpx;
color: #059669;
}
.my-zhiding-actions {
display: flex;
gap: 12rpx;
margin-top: 16rpx;
}
.zhiding-act {
flex: 1;
text-align: center;
padding: 14rpx 0;
border-radius: 999rpx;
font-size: 26rpx;
font-weight: 600;
}
.zhiding-act--ghost {
background: #f3f4f6;
color: #666;
}
.zhiding-act--primary {
background: linear-gradient(90deg, #ff8c00, #ff6b00);
color: #fff;
}
.order-my-zhiding {
border: 3rpx solid #ff4500 !important;
box-shadow: 0 0 0 6rpx rgba(255, 69, 0, 0.25), 0 12rpx 36rpx rgba(255, 69, 0, 0.35) !important;
}
.order-zhiding-highlight {
animation: zhidingPulse 1.5s ease-in-out 2;
}
@keyframes zhidingPulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(255, 140, 0, 0.3); }
50% { box-shadow: 0 0 0 12rpx rgba(255, 140, 0, 0); }
}
.zhiding-modal-mask {
position: fixed;
left: 0; right: 0; top: 0; bottom: 0;
background: rgba(0, 0, 0, 0.62);
z-index: 10050;
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx;
}
.zhiding-modal-mask--top {
z-index: 10060;
}
.zhiding-modal {
width: 100%;
max-width: 640rpx;
background: #ffffff;
border-radius: 24rpx;
overflow: hidden;
box-shadow: 0 24rpx 64rpx rgba(0, 0, 0, 0.35);
}
.zhiding-modal--sm { max-width: 580rpx; }
.zhiding-modal-head {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 28rpx;
border-bottom: 1rpx solid #eee;
background: #fff;
}
.zhiding-modal-title { font-size: 32rpx; font-weight: 700; color: #222; }
.zhiding-modal-close { font-size: 44rpx; color: #666; line-height: 1; padding: 0 8rpx; }
.zhiding-modal-body { padding: 24rpx 28rpx; background: #fff; }
.zhiding-modal-row {
display: flex;
justify-content: space-between;
margin-bottom: 16rpx;
font-size: 28rpx;
color: #333;
}
.zhiding-modal-row.col { flex-direction: column; gap: 8rpx; }
.zhiding-modal-row .lbl { color: #999; font-size: 24rpx; }
.zhiding-modal-row .reward { color: #e64340; font-weight: 700; }
.zhiding-modal-actions { padding: 0 28rpx 28rpx; margin-top: 0; background: #fff; }
.later-hint { font-size: 26rpx; color: #444; display: block; margin-bottom: 16rpx; }
.later-input {
width: 100%;
box-sizing: border-box;
border: 2rpx solid #ddd;
border-radius: 12rpx;
padding: 22rpx 20rpx;
font-size: 28rpx;
color: #222;
background: #f9fafb;
min-height: 88rpx;
}
.later-input-ph { color: #aaa; }
.later-confirm {
margin: 0 28rpx 28rpx;
text-align: center;
padding: 24rpx;
background: linear-gradient(90deg, #ff8c00, #ff4500);
color: #fff;
border-radius: 999rpx;
font-size: 30rpx;
font-weight: 700;
}