feat(M08-A): 接入顾客端订单开门

This commit is contained in:
Codex
2026-06-24 22:39:15 +08:00
parent d2c73a2c28
commit eaa86547c2
7 changed files with 161 additions and 2 deletions
@@ -0,0 +1,39 @@
import type { RowDataPacket } from 'mysql2/promise';
import type { MySqlPool } from '../db/mysql.js';
export class CustomerDeviceAccessError extends Error {
constructor(public readonly code: string) { super(code); }
}
interface OrderDeviceRow extends RowDataPacket {
orderId: string;
storeId: string;
roomId: string;
status: string;
}
export class CustomerDeviceAccessRepository {
constructor(private readonly pool: MySqlPool) {}
async getDoorContext(input: { tenantId: string; userId: string; orderId: string }) {
const [rows] = await this.pool.execute<OrderDeviceRow[]>(
`SELECT o.id AS orderId, o.store_id AS storeId, o.room_id AS roomId, o.status
FROM qipai_orders o
INNER JOIN qipai_order_user_access a
ON a.tenant_id = o.tenant_id AND a.order_id = o.id
AND a.user_id = ? AND a.revoked_at IS NULL
WHERE o.tenant_id = ? AND o.id = ? AND o.deleted_at IS NULL
AND o.status IN ('PAID', 'RESERVED', 'IN_PROGRESS')
AND UTC_TIMESTAMP(3) BETWEEN DATE_SUB(o.start_at, INTERVAL 30 MINUTE) AND o.end_at
LIMIT 1`,
[input.userId, input.tenantId, input.orderId]
);
if (!rows[0]) throw new CustomerDeviceAccessError('ORDER_DOOR_ACCESS_FORBIDDEN');
return {
orderId: String(rows[0].orderId),
storeId: String(rows[0].storeId),
roomId: String(rows[0].roomId),
status: rows[0].status
};
}
}