feat(order): 平台派单闭环(发需求单进入待接单池)

- 下单页新增「指定大神 / 平台派单」模式:平台派单填品类、预算、地点/选点,expertId=0

- 服务端:平台派单单据支付后进入待接单池(余额支付即时入池,微信支付确认后入池),预算由买家出价但受 1~2000 元/小时约束

- 抢单由认领大神写入 expert_id 并转履约中;30 分钟无人接单沿用自动全额退款

- 修复订单 INSERT 占位符少一个导致下单报 Column count doesn't match 的问题,并新增列数/占位符一致性护栏

- 111 套件/737 用例全绿;线上 1 元实测:下单→待接单→池内 640m,测试数据已回滚
这个提交包含在:
xcbyy
2026-10-21 15:16:03 +08:00
父节点 5538d8ce7e
当前提交 77aa4cb50b
共有 6 个文件被更改,包括 257 次插入 和 32 次删除

查看文件

@@ -2222,8 +2222,20 @@ app.post('/api/orders/:id/pay', async (req: Request, res: Response) => {
if (!paid) {
return res.status(400).json({ code: 40000, message: '微信支付尚未完成,无法确认订单支付' });
}
const order = await repo.updateOrderStatus(orderId, '履约中');
const isMarketplace = !Number(own.expertId);
const paidStatus = isMarketplace ? '待接单' : '履约中';
const order = await repo.updateOrderStatus(orderId, paidStatus);
const buyer = Number(own.buyerId || 0);
if (isMarketplace) {
pushUserNotification(
buyer,
'ORDER_STATUS',
'支付成功,等待大神接单',
`订单 ${order?.order_no || orderId} 已支付,正在为您匹配附近大神;30 分钟内无人接单将自动全额退款。`,
'/pages/order/list'
);
return res.json({ code: 20000, data: order, message: '支付成功,已进入派单池,等待附近大神接单' });
}
pushUserNotification(buyer, 'ORDER_STATUS', '订单已开始服务', `订单 ${order?.order_no || orderId} 已进入履约中${order?.verify_code ? `,核销码 ${order.verify_code}` : ''},请按时到场。`, '/pages/order/list');
void notifyBySubscribe('orderStatus', {
userId: buyer,
@@ -2244,7 +2256,7 @@ app.post('/api/orders/:id/pay', async (req: Request, res: Response) => {
}
// 沙箱仅允许推进到「已支付待履约」的合法状态,严禁客户端任意指定终态或退款态
const requested = String(req.body?.targetStatus || '履约中');
const requested = String(req.body?.targetStatus || (Number(own.expertId) ? '履约中' : '待接单'));
const allowedSandboxStatuses = ['履约中', '待接单'];
if (!allowedSandboxStatuses.includes(requested)) {
return res.status(400).json({ code: 40000, message: `非法的目标订单状态: ${requested}` });