fix(miniapp): 接单大厅分类数量取真实数据,抢单失败不再伪造订单
- 分类 chip 的 12/4/3 写死数量改为按真实订单统计 - 雷达页抢单失败时删除「自动落盘创建订单」兜底(原逻辑会伪造一笔 buyerId=2001 的订单并提示成功),改为如实提示已被抢/状态不可接/未认证 - 抢单使用当前登录身份(userId 由服务端 token 覆盖),成功后刷新列表 - 110 套件/730 用例全绿
这个提交包含在:
@@ -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) || '抢单失败,请稍后重试',
|
||||
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'
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
在新工单中引用
屏蔽一个用户