fix(miniapp): 接单大厅分类数量取真实数据,抢单失败不再伪造订单

- 分类 chip 的 12/4/3 写死数量改为按真实订单统计

- 雷达页抢单失败时删除「自动落盘创建订单」兜底(原逻辑会伪造一笔 buyerId=2001 的订单并提示成功),改为如实提示已被抢/状态不可接/未认证

- 抢单使用当前登录身份(userId 由服务端 token 覆盖),成功后刷新列表

- 110 套件/730 用例全绿
这个提交包含在:
xcbyy
2026-10-21 14:55:01 +08:00
父节点 68e41ca962
当前提交 5538d8ce7e
共有 3 个文件被更改,包括 29 次插入 和 34 次删除

查看文件

@@ -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([]);

查看文件

@@ -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) || '抢单失败,请稍后重试',
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'

查看文件

@@ -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');
});
});