- 分类 chip 的 12/4/3 写死数量改为按真实订单统计 - 雷达页抢单失败时删除「自动落盘创建订单」兜底(原逻辑会伪造一笔 buyerId=2001 的订单并提示成功),改为如实提示已被抢/状态不可接/未认证 - 抢单使用当前登录身份(userId 由服务端 token 覆盖),成功后刷新列表 - 110 套件/730 用例全绿
89 行
3.9 KiB
TypeScript
89 行
3.9 KiB
TypeScript
// 已读取AGENTS.md
|
||
import * as fs from 'fs';
|
||
import * as path from 'path';
|
||
|
||
/**
|
||
* 第九十四批:真实距离(LBS)落地闸门。
|
||
* 背景:雷达页/接单大厅的「650m / 1.4km / 1.2km内」全部是写死演示值,
|
||
* orders/activities 也没有经纬度字段,导致「按距离派单」实际不生效。
|
||
*/
|
||
describe('第九十四批真实距离与 LBS 闸门', () => {
|
||
const root = path.resolve(__dirname, '../../');
|
||
const read = (rel: string) => fs.readFileSync(path.join(root, rel), 'utf-8');
|
||
|
||
const mysql = read('server/src/db/mysql.ts');
|
||
const repo = read('server/src/db/repository.ts');
|
||
const indexCode = read('server/src/index.ts');
|
||
const apiCode = read('pwuniapp/common/api.js');
|
||
const radar = read('pwuniapp/pages/expert/radar.vue');
|
||
const hall = read('pwuniapp/pages/expert/hall.vue');
|
||
const orderCreate = read('pwuniapp/pages/order/create.vue');
|
||
const activityCreate = read('pwuniapp/pages/activity/create.vue');
|
||
|
||
it('订单与组局表必须存储经纬度', () => {
|
||
expect(mysql).toContain('latitude DECIMAL(10,6)');
|
||
expect(mysql).toContain('longitude DECIMAL(10,6)');
|
||
expect(mysql).toContain('ALTER TABLE activities ADD COLUMN latitude');
|
||
expect(mysql).toContain('ALTER TABLE orders ADD COLUMN latitude');
|
||
});
|
||
|
||
it('服务端按 Haversine 计算距离并返回距离文案', () => {
|
||
expect(repo).toContain('export function haversineKm');
|
||
expect(repo).toContain('export function formatDistanceText');
|
||
expect(repo).toContain('distanceText');
|
||
expect(repo).toContain('radiusKm');
|
||
expect(repo).toContain('async updateOrderGeo');
|
||
});
|
||
|
||
it('派单池接口接收定位并按半径过滤,历史地址走腾讯地理编码兜底', () => {
|
||
const start = indexCode.indexOf("app.get('/api/orders/pool'");
|
||
expect(start).toBeGreaterThan(-1);
|
||
const block = indexCode.slice(start, start + 2200);
|
||
expect(block).toContain('req.query.lat');
|
||
expect(block).toContain('req.query.radius');
|
||
expect(block).toContain('geocodeAddress');
|
||
expect(block).toContain('repo.updateOrderGeo');
|
||
});
|
||
|
||
it('逆地址解析接口仅服务端持有 Key,并要求登录', () => {
|
||
expect(indexCode).toContain("app.get('/api/lbs/reverse'");
|
||
expect(indexCode).toContain('resolveTencentMapKey');
|
||
expect(indexCode).toContain("resolveSecureUserId(req, Number(req.query.userId || 0), '解析当前位置')");
|
||
// Key 不允许出现在小程序端
|
||
expect(apiCode).not.toContain('7I4BZ');
|
||
});
|
||
|
||
it('小程序雷达与接单大厅改用真实距离,删除写死演示距离', () => {
|
||
expect(radar).toContain('getUserLocation');
|
||
expect(radar).toContain('p.distanceText');
|
||
expect(radar).not.toContain("distance: '650m'");
|
||
expect(radar).not.toContain("dist: '1.4km'");
|
||
|
||
expect(hall).toContain('getUserLocation');
|
||
expect(hall).toContain('p.distanceText');
|
||
expect(hall).not.toContain("'1.2km内'");
|
||
expect(hall).not.toContain("'1.1km'");
|
||
});
|
||
|
||
it('下单/组局在选点后提交经纬度', () => {
|
||
expect(orderCreate).toContain('pickVenue');
|
||
expect(orderCreate).toContain('uni.chooseLocation');
|
||
expect(orderCreate).toContain('latitude: isOffline.value ? meetCoords.value.latitude : null');
|
||
expect(activityCreate).toContain('form.value.latitude');
|
||
expect(apiCode).toContain('latitude: payload.latitude');
|
||
});
|
||
|
||
it('小程序的派单池调用支持携带定位与半径', () => {
|
||
expect(apiCode).toContain('export async function getOrdersPool(options = {})');
|
||
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');
|
||
});
|
||
});
|