diff --git a/pwuniapp/pages/expert/hall.vue b/pwuniapp/pages/expert/hall.vue index e6e093b..08f3e35 100644 --- a/pwuniapp/pages/expert/hall.vue +++ b/pwuniapp/pages/expert/hall.vue @@ -386,12 +386,14 @@ onUnmounted(() => { }); -const categories = ref([ - { key: 'all', name: '全部可接', count: 12, icon: ICONS.gridAll }, - { key: 'food', name: '同城美食', count: 4, icon: ICONS.utensils }, - { key: 'drink', name: '清吧咖啡', count: 3, icon: ICONS.coffee }, - { key: 'sing', name: 'KTV麦霸', count: 2, icon: ICONS.micVocal }, - { key: 'game', name: '线上电竞', count: 3, icon: ICONS.gameCrosshair } +const countByType = (cls: string) => orders.value.filter((o: any) => o.typeClass === cls).length; + +const categories = computed(() => [ + { key: 'all', name: '全部可接', count: orders.value.length, icon: ICONS.gridAll }, + { key: 'food', name: '同城美食', count: countByType('cat-food'), icon: ICONS.utensils }, + { key: 'drink', name: '清吧咖啡', count: countByType('cat-drink'), icon: ICONS.coffee }, + { key: 'sing', name: 'KTV麦霸', count: countByType('cat-sing'), icon: ICONS.micVocal }, + { key: 'game', name: '线上电竞', count: countByType('cat-game'), icon: ICONS.gameCrosshair } ]); const orders = ref([]); diff --git a/pwuniapp/pages/expert/radar.vue b/pwuniapp/pages/expert/radar.vue index 71ed07f..14fd92e 100644 --- a/pwuniapp/pages/expert/radar.vue +++ b/pwuniapp/pages/expert/radar.vue @@ -189,7 +189,7 @@ import { ICONS } from '@/common/icons.js'; import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js'; import { isExpertCertified } from '@/common/role.js'; import { getNavBarInfo } from '@/common/nav.js'; -import { getOrdersPool, claimOrder, createOrder, reverseGeocode } from '@/common/api.js'; +import { getOrdersPool, claimOrder, reverseGeocode } from '@/common/api.js'; import { getUserLocation } from '@/common/location.js'; const navInfo = ref(getNavBarInfo()); @@ -394,42 +394,28 @@ const handleTakeOrder = (order) => { if (res.confirm) { uni.showLoading({ title: '正在锁定订单...' }); try { + const cachedUser = uni.getStorageSync('userInfo') || {}; await claimOrder(order.id, { - expertId: 101, - companionName: '我 (接单大神)', - expertAvatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150' + expertId: Number(uni.getStorageSync('userId')) || 0, + companionName: cachedUser.nickname || '接单大神', + expertAvatar: cachedUser.avatar || 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150' }); } catch (claimErr) { - // 若为新需求单,尝试自动落盘创建 - try { - await createOrder({ - buyerId: 2001, - clientName: order.buyerName || '同城客户', - expertId: 101, - companionName: '我 (接单大神)', - track: order.categoryName, - serviceTitle: order.title, - hourlyRate: order.reward, - durationHours: 2, - amount: order.reward, - location: '北京市朝阳区商圈', - expenseBurden: '费用AA', - status: '履约中' - }); - } catch (createErr) { - uni.hideLoading(); - uni.showToast({ - title: (createErr && createErr.message) || (claimErr && claimErr.message) || '抢单失败,请稍后重试', - icon: 'none' - }); - return; - } + // 抢单失败必须如实告知(已被抢/不可接/未认证),严禁伪造成功 + uni.hideLoading(); + uni.showToast({ + title: (claimErr && claimErr.message) || '抢单失败,请稍后重试', + icon: 'none' + }); + await loadNearbyOrdersFromPool(); + return; } uni.hideLoading(); uni.showToast({ title: '恭喜抢单成功!已锁定订单', icon: 'success' }); + await loadNearbyOrdersFromPool(); setTimeout(() => { uni.navigateTo({ url: '/pages/order/list' diff --git a/server/tests/lbs-distance.spec.ts b/server/tests/lbs-distance.spec.ts index 9e59c86..f4000e8 100644 --- a/server/tests/lbs-distance.spec.ts +++ b/server/tests/lbs-distance.spec.ts @@ -78,4 +78,11 @@ describe('第九十四批真实距离与 LBS 闸门', () => { expect(apiCode).toContain('qs.push(`lat=${lat}`, `lng=${lng}`)'); expect(apiCode).toContain('radius=${radius}'); }); + + it('接单失败不得伪造订单,分类数量必须来自真实数据', () => { + expect(radar).not.toContain('buyerId: 2001'); + expect(radar).not.toContain("status: '履约中'"); + expect(hall).toContain('countByType'); + expect(hall).not.toContain('count: 12'); + }); });