feat(order): 禁止自己接自己发布的订单

- claimOrder 校验 buyer_id 与大神登录用户 id,相同直接 403「不能接自己发布的订单」

- 派单池支持 excludeBuyerId:已登录大神不会看到自己发布的待接单

- 115 套件/753 用例全绿;线上实测自接 403、他人可抢、自己的单不出现在自己的池子
这个提交包含在:
xcbyy
2026-10-22 10:35:56 +08:00
父节点 81368f870f
当前提交 082ec1c385
共有 4 个文件被更改,包括 26 次插入 和 6 次删除

查看文件

@@ -1940,7 +1940,8 @@ export class MysqlRepository {
}
}
async getOrdersPool(opts: { fromLat?: number | null; fromLng?: number | null; radiusKm?: number | null } = {}): Promise<any[]> {
async getOrdersPool(opts: { fromLat?: number | null; fromLng?: number | null; radiusKm?: number | null; excludeBuyerId?: number | null } = {}): Promise<any[]> {
const excludeBuyerId = Number(opts.excludeBuyerId) || 0;
const [rows]: any = await pool.query(`
SELECT
id, order_no as orderNo, client_name as clientName,
@@ -1951,9 +1952,10 @@ export class MysqlRepository {
FROM orders
WHERE status = '待接单'
AND (claimed_by IS NULL OR claimed_by = 0)
${excludeBuyerId ? 'AND buyer_id <> ?' : ''}
ORDER BY created_at DESC
LIMIT 50
`);
`, excludeBuyerId ? [excludeBuyerId] : []);
// 默认池保障
const maskClientName = (n: any): string => {
@@ -2043,7 +2045,7 @@ export class MysqlRepository {
// orders.expert_id 统一存「大神档案 id」;claimed_by 存登录用户 id
const companionIdForOrder = comp ? Number(comp.id) || expertId : expertId;
const [curRows]: any = await pool.query('SELECT id, status, claimed_by FROM orders WHERE id = ? OR order_no = ? LIMIT 1', [orderId, orderId]);
const [curRows]: any = await pool.query('SELECT id, buyer_id, status, claimed_by FROM orders WHERE id = ? OR order_no = ? LIMIT 1', [orderId, orderId]);
const cur = curRows && curRows[0];
if (!cur) {
const err: any = new Error('订单不存在');
@@ -2051,6 +2053,15 @@ export class MysqlRepository {
err.code = 40400;
throw err;
}
// 禁止自己接自己发布的订单(刷单/套券风险)
const buyerId = Number(cur.buyer_id) || 0;
const actorUserId = Number(comp && comp.user_id) || expertId;
if (buyerId > 0 && buyerId === actorUserId) {
const err: any = new Error('不能接自己发布的订单');
err.status = 403;
err.code = 40300;
throw err;
}
// 状态闸门:仅「待接单」可被抢单,严禁抢已在履约/已服务/已核销的订单
if (String(cur.status) !== '待接单') {
const err: any = new Error(`当前订单状态(${cur.status})不可接单(仅待接单可抢)`);