-- +goose Up -- +goose StatementBegin CREATE TABLE IF NOT EXISTS chat_admin_conversation_states ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, conversation_id BIGINT UNSIGNED NOT NULL COMMENT '会话ID', admin_user_id BIGINT UNSIGNED NOT NULL COMMENT '管理员ID', remark VARCHAR(128) NOT NULL DEFAULT '' COMMENT '管理员个人备注', last_read_message_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '最后已读消息ID', last_read_at DATETIME NULL COMMENT '最后已读时间', created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_chat_admin_conversation_state (conversation_id, admin_user_id), KEY idx_chat_admin_state_admin (admin_user_id, conversation_id), KEY idx_chat_admin_state_read (admin_user_id, last_read_message_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='管理员会话个人状态'; INSERT INTO chat_admin_conversation_states ( conversation_id, admin_user_id, remark, last_read_message_id, last_read_at ) SELECT cp.conversation_id, cp.participant_id, cp.remark, COALESCE(( SELECT MAX(cm.id) FROM chat_messages cm WHERE cm.conversation_id = cp.conversation_id AND cp.last_read_at IS NOT NULL AND cm.created_at <= cp.last_read_at ), 0), cp.last_read_at FROM chat_participants cp WHERE cp.participant_type = 'admin' AND (cp.remark <> '' OR cp.last_read_at IS NOT NULL) ON DUPLICATE KEY UPDATE remark = VALUES(remark), last_read_message_id = GREATEST( chat_admin_conversation_states.last_read_message_id, VALUES(last_read_message_id) ), last_read_at = CASE WHEN chat_admin_conversation_states.last_read_at IS NULL THEN VALUES(last_read_at) WHEN VALUES(last_read_at) IS NULL THEN chat_admin_conversation_states.last_read_at ELSE GREATEST(chat_admin_conversation_states.last_read_at, VALUES(last_read_at)) END; ALTER TABLE chat_conversations ADD INDEX idx_chat_conversations_status_activity (status, last_message_at, id), ADD INDEX idx_chat_conversations_type_scene_activity (type, support_scene, last_message_at, id); -- 后台客服列表需要按商品快速定位最新订单,避免为每个会话执行全表排序。 ALTER TABLE rental_orders ADD INDEX idx_rental_orders_listing_id_id (listing_id, id); -- +goose StatementEnd -- +goose Down -- +goose StatementBegin ALTER TABLE rental_orders DROP INDEX idx_rental_orders_listing_id_id; ALTER TABLE chat_conversations DROP INDEX idx_chat_conversations_type_scene_activity, DROP INDEX idx_chat_conversations_status_activity; DROP TABLE IF EXISTS chat_admin_conversation_states; -- +goose StatementEnd