- claimOrder 校验 buyer_id 与大神登录用户 id,相同直接 403「不能接自己发布的订单」 - 派单池支持 excludeBuyerId:已登录大神不会看到自己发布的待接单 - 115 套件/753 用例全绿;线上实测自接 403、他人可抢、自己的单不出现在自己的池子
71 行
3.3 KiB
TypeScript
71 行
3.3 KiB
TypeScript
// 已读取AGENTS.md
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
/**
|
|
* 第九十五批:平台派单(发需求单)闭环闸门。
|
|
* 背景:抢单池只查 status='待接单',但下单流程全是「指定大神 → 支付 → 履约中」,
|
|
* 没有任何流程产出待接单订单,导致雷达/接单大厅永远是空池。
|
|
*/
|
|
describe('第九十五批平台派单闭环', () => {
|
|
const root = path.resolve(__dirname, '../../');
|
|
const read = (rel: string) => fs.readFileSync(path.join(root, rel), 'utf-8');
|
|
const repo = read('server/src/db/repository.ts');
|
|
const indexCode = read('server/src/index.ts');
|
|
const createPage = read('pwuniapp/pages/order/create.vue');
|
|
|
|
it('平台派单订单 expertId=0,余额支付后直接进入待接单池', () => {
|
|
expect(repo).toContain('const isMarketplace = !Number(data.expertId)');
|
|
expect(repo).toContain("const expertId = isMarketplace ? 0 : Number(data.expertId)");
|
|
expect(repo).toContain("isMarketplace ? '待接单' : '履约中'");
|
|
});
|
|
|
|
it('平台派单预算由买家出价但受服务端上下限约束', () => {
|
|
expect(repo).toContain('hourlyRate = Math.min(2000, Math.max(1, Number(data.hourlyRate) || 35))');
|
|
});
|
|
|
|
it('微信支付确认后:无大神订单转入待接单而不是履约中', () => {
|
|
expect(indexCode).toContain("const paidStatus = isMarketplace ? '待接单' : '履约中'");
|
|
expect(indexCode).toContain('已进入派单池,等待附近大神接单');
|
|
expect(indexCode).toContain('30 分钟内无人接单将自动全额退款');
|
|
});
|
|
|
|
it('抢单后由认领大神写入 expert_id 并进入履约中', () => {
|
|
expect(repo).toContain("SET status = '履约中', expert_id = ?, companion_name = ?");
|
|
expect(repo).toContain("AND status = '待接单'");
|
|
});
|
|
|
|
it('下单页提供「平台派单」模式并提交 expertId=0', () => {
|
|
expect(createPage).toContain("const orderMode = ref('EXPERT')");
|
|
expect(createPage).toContain('platformCategories');
|
|
expect(createPage).toContain('expertId: isPlatform ? 0 : expert.value.id');
|
|
expect(createPage).toContain('平台派单需求');
|
|
});
|
|
|
|
it('平台派单时不会沿用指定大神页的默认地点', () => {
|
|
expect(createPage).toContain('const switchMode = (mode) =>');
|
|
expect(createPage).toContain("meetVenue.value = '';");
|
|
});
|
|
|
|
it('订单 INSERT 的列数必须与占位符数量一致(含 paid_at/created_at 两个表达式值)', () => {
|
|
const start = repo.indexOf('INSERT INTO orders');
|
|
const end = repo.indexOf('`, [', start);
|
|
const seg = repo.slice(start, end);
|
|
const columns = seg
|
|
.slice(seg.indexOf('(') + 1, seg.indexOf(')'))
|
|
.split(',')
|
|
.filter((s) => s.trim()).length;
|
|
const values = seg.slice(seg.indexOf('VALUES'));
|
|
const placeholders = (values.replace(/\$\{[^}]*\}/g, '').match(/\?/g) || []).length;
|
|
expect(columns).toBe(24);
|
|
expect(placeholders + 2).toBe(columns);
|
|
});
|
|
|
|
it('禁止自己接自己发布的订单,派单池也不展示自己的单', () => {
|
|
expect(repo).toContain('不能接自己发布的订单');
|
|
expect(repo).toContain('const actorUserId = Number(comp && comp.user_id) || expertId;');
|
|
expect(repo).toContain('AND buyer_id <> ?');
|
|
expect(indexCode).toContain('excludeBuyerId');
|
|
});
|
|
});
|