revert(order): 移除订单站内聊天,沟通统一走官方客服

- 删除 pages/order/chat、聊天接口/仓储方法/order_messages 建表与客户端 API

- 买家「联系大神」、大神「联系老板」、大神详情「在线客服」、组局「私聊」统一改为 openSupportSheet(读取后台 customer_service 配置的客服微信/热线)

- 保留派单实时通知与雷达/大厅轮询

- 114 套件/742 用例全绿;聊天接口线上已 404
这个提交包含在:
xcbyy
2026-10-22 09:10:16 +08:00
父节点 aca35db200
当前提交 be1c7be5d3
共有 12 个文件被更改,包括 95 次插入 和 685 次删除

查看文件

@@ -159,21 +159,6 @@ export async function initDatabase(): Promise<void> {
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`);
// 订单维度站内聊天消息(仅交易双方可见,敏感词/联系方式在服务端拦截)
await conn.query(`
CREATE TABLE IF NOT EXISTS order_messages (
id VARCHAR(64) PRIMARY KEY,
order_id VARCHAR(64) NOT NULL,
sender_id INT NOT NULL,
receiver_id INT NOT NULL,
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
read_at DATETIME NULL,
INDEX idx_order_created (order_id, created_at),
INDEX idx_receiver_read (receiver_id, read_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`);
const extraOrderCols = [
"ALTER TABLE orders ADD COLUMN buyer_id INT DEFAULT 1001 AFTER id",
"ALTER TABLE orders ADD COLUMN expert_id INT DEFAULT 101 AFTER buyer_id",

查看文件

@@ -1686,66 +1686,6 @@ export class MysqlRepository {
};
}
/** 订单聊天上下文:仅买家与已认领大神可参与 */
async getOrderChatContext(orderId: string): Promise<any | null> {
const own = await this.getOrderOwnership(orderId);
if (!own) return null;
return {
orderId: own.id,
orderNo: own.orderNo,
buyerId: own.buyerId,
expertUserId: Number(own.claimedBy) || 0,
status: own.status,
amount: own.amount,
companionName: own.companionName,
};
}
async listOrderMessages(orderId: string, limit = 100): Promise<any[]> {
const safeLimit = Math.min(200, Math.max(1, Math.round(Number(limit) || 100)));
const [rows]: any = await pool.query(`
SELECT id, order_id as orderId, sender_id as senderId, receiver_id as receiverId,
content, created_at as createdAt, read_at as readAt
FROM order_messages
WHERE order_id = ?
ORDER BY created_at ASC
LIMIT ?
`, [orderId, safeLimit]);
return rows || [];
}
async createOrderMessage(orderId: string, senderId: number, receiverId: number, content: string): Promise<any> {
const id = `msg_${Date.now()}_${Math.floor(100 + Math.random() * 900)}`;
await pool.query(
'INSERT INTO order_messages (id, order_id, sender_id, receiver_id, content) VALUES (?, ?, ?, ?, ?)',
[id, orderId, senderId, receiverId, content]
);
return {
id,
orderId,
senderId: Number(senderId),
receiverId: Number(receiverId),
content,
createdAt: new Date().toISOString(),
readAt: null,
};
}
async markOrderMessagesRead(orderId: string, readerId: number): Promise<void> {
await pool.query(
'UPDATE order_messages SET read_at = NOW() WHERE order_id = ? AND receiver_id = ? AND read_at IS NULL',
[orderId, readerId]
);
}
async countUnreadOrderMessages(orderId: string, receiverId: number): Promise<number> {
const [rows]: any = await pool.query(
'SELECT COUNT(*) as c FROM order_messages WHERE order_id = ? AND receiver_id = ? AND read_at IS NULL',
[orderId, receiverId]
);
return Number(rows?.[0]?.c || 0);
}
// 大神点击申请完成服务 (服务中 -> 待确认,进入 48 小时买家确认窗口)
async applyCompleteOrder(orderId: string): Promise<any> {
const [cur]: any = await pool.query('SELECT status FROM orders WHERE id = ? OR order_no = ? LIMIT 1', [orderId, orderId]);