整理数据库迁移文件和开发脚本

- 合并迁移文件为 000001_init.sql(表结构)和 000002_seed.sql(初始数据)
- 删除旧的迁移文件(000002_chat.sql、000002_rbac_seed.sql、000007_chat_enhancements.sql)
- 简化 dev.sh 迁移逻辑,移除对已删除文件的引用
- 添加聊天相关表(chat_quick_replies)到初始化脚本

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
yml2213
2026-05-27 06:49:58 +08:00
co-authored by Claude Opus 4.7
parent 138f0514a9
commit 0d9fec01f3
5 changed files with 133 additions and 101 deletions
+98
View File
@@ -1,3 +1,15 @@
-- ============================================
-- 数据库初始化脚本
-- 包含所有表结构定义
-- ============================================
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- -------------------------------------------
-- 用户相关表
-- -------------------------------------------
CREATE TABLE users ( CREATE TABLE users (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
phone VARCHAR(32) NOT NULL, phone VARCHAR(32) NOT NULL,
@@ -29,6 +41,10 @@ CREATE TABLE user_realname (
KEY idx_user_realname_provider_order_no (provider_order_no) KEY idx_user_realname_provider_order_no (provider_order_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------
-- 游戏账号和商品表
-- -------------------------------------------
CREATE TABLE game_accounts ( CREATE TABLE game_accounts (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
owner_id BIGINT UNSIGNED NOT NULL, owner_id BIGINT UNSIGNED NOT NULL,
@@ -67,6 +83,10 @@ CREATE TABLE rental_listings (
KEY idx_rental_listings_filter (status, review_status, in_transaction, price) KEY idx_rental_listings_filter (status, review_status, in_transaction, price)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------
-- 订单相关表
-- -------------------------------------------
CREATE TABLE rental_orders ( CREATE TABLE rental_orders (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(64) NOT NULL, order_no VARCHAR(64) NOT NULL,
@@ -136,6 +156,10 @@ CREATE TABLE handoff_records (
KEY idx_handoff_records_order_id (order_id) KEY idx_handoff_records_order_id (order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------
-- 钱包相关表
-- -------------------------------------------
CREATE TABLE wallet_accounts ( CREATE TABLE wallet_accounts (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT UNSIGNED NOT NULL, user_id BIGINT UNSIGNED NOT NULL,
@@ -166,6 +190,10 @@ CREATE TABLE wallet_ledger (
KEY idx_wallet_ledger_biz (biz_type, biz_no) KEY idx_wallet_ledger_biz (biz_type, biz_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------
-- 纠纷和通知表
-- -------------------------------------------
CREATE TABLE disputes ( CREATE TABLE disputes (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
order_id BIGINT UNSIGNED NOT NULL, order_id BIGINT UNSIGNED NOT NULL,
@@ -213,6 +241,10 @@ CREATE TABLE audit_logs (
KEY idx_audit_logs_biz (biz_type, biz_id) KEY idx_audit_logs_biz (biz_type, biz_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------
-- 管理员和权限表
-- -------------------------------------------
CREATE TABLE admin_users ( CREATE TABLE admin_users (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(64) NOT NULL, username VARCHAR(64) NOT NULL,
@@ -262,6 +294,10 @@ CREATE TABLE role_permissions (
UNIQUE KEY uk_role_permissions_role_permission (role_id, permission_id) UNIQUE KEY uk_role_permissions_role_permission (role_id, permission_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------
-- 系统配置表
-- -------------------------------------------
CREATE TABLE system_configs ( CREATE TABLE system_configs (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`key` VARCHAR(128) NOT NULL, `key` VARCHAR(128) NOT NULL,
@@ -272,3 +308,65 @@ CREATE TABLE system_configs (
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_system_configs_key (`key`) UNIQUE KEY uk_system_configs_key (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------
-- 客服聊天表
-- -------------------------------------------
CREATE TABLE chat_conversations (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
order_id BIGINT UNSIGNED NOT NULL,
type VARCHAR(32) NOT NULL DEFAULT 'order_group',
title VARCHAR(128) NOT NULL,
status VARCHAR(32) NOT NULL DEFAULT 'active',
last_message_id BIGINT UNSIGNED NULL,
last_message_preview VARCHAR(255) NOT NULL DEFAULT '',
last_message_at DATETIME NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_chat_conversations_order_id (order_id),
KEY idx_chat_conversations_last_message_at (last_message_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE chat_participants (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
conversation_id BIGINT UNSIGNED NOT NULL,
participant_type VARCHAR(16) NOT NULL,
participant_id BIGINT UNSIGNED NOT NULL,
role VARCHAR(32) NOT NULL,
remark VARCHAR(128) NOT NULL DEFAULT '',
last_read_at DATETIME NULL,
joined_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_chat_participants_member (conversation_id, participant_type, participant_id),
KEY idx_chat_participants_participant (participant_type, participant_id),
KEY idx_chat_participants_conversation (conversation_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE chat_messages (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
conversation_id BIGINT UNSIGNED NOT NULL,
sender_type VARCHAR(16) NOT NULL,
sender_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
sender_role VARCHAR(32) NOT NULL DEFAULT '',
content_type VARCHAR(32) NOT NULL DEFAULT 'text',
content TEXT NULL,
attachment_urls JSON NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
KEY idx_chat_messages_conversation_id (conversation_id, id),
KEY idx_chat_messages_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE chat_quick_replies (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
admin_user_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0=全局, >0=个人',
title VARCHAR(64) NOT NULL COMMENT '快捷回复标题',
content TEXT NOT NULL COMMENT '回复内容',
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_admin_user_id (admin_user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='快捷回复模板';
SET FOREIGN_KEY_CHECKS = 1;
-47
View File
@@ -1,47 +0,0 @@
CREATE TABLE IF NOT EXISTS chat_conversations (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
order_id BIGINT UNSIGNED NOT NULL,
type VARCHAR(32) NOT NULL DEFAULT 'order_group',
title VARCHAR(128) NOT NULL,
status VARCHAR(32) NOT NULL DEFAULT 'active',
last_message_id BIGINT UNSIGNED NULL,
last_message_preview VARCHAR(255) NOT NULL DEFAULT '',
last_message_at DATETIME NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_chat_conversations_order_id (order_id),
KEY idx_chat_conversations_last_message_at (last_message_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS chat_participants (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
conversation_id BIGINT UNSIGNED NOT NULL,
participant_type VARCHAR(16) NOT NULL,
participant_id BIGINT UNSIGNED NOT NULL,
role VARCHAR(32) NOT NULL,
last_read_at DATETIME NULL,
joined_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_chat_participants_member (conversation_id, participant_type, participant_id),
KEY idx_chat_participants_participant (participant_type, participant_id),
KEY idx_chat_participants_conversation (conversation_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS chat_messages (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
conversation_id BIGINT UNSIGNED NOT NULL,
sender_type VARCHAR(16) NOT NULL,
sender_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
sender_role VARCHAR(32) NOT NULL DEFAULT '',
content_type VARCHAR(32) NOT NULL DEFAULT 'text',
content TEXT NULL,
attachment_urls JSON NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
KEY idx_chat_messages_conversation_id (conversation_id, id),
KEY idx_chat_messages_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO system_configs (`key`, `value`, description)
VALUES ('chat.default_support_admin_id', '1', '订单群聊默认接入的客服管理员 ID')
ON DUPLICATE KEY UPDATE description = VALUES(description);
@@ -1,7 +1,14 @@
-- RBAC seed: 默认角色和权限 -- ============================================
-- 初始数据脚本
-- 包含权限、角色、系统配置等基础数据
-- ============================================
SET NAMES utf8mb4; SET NAMES utf8mb4;
-- 插入权限 -- -------------------------------------------
-- 权限数据
-- -------------------------------------------
INSERT INTO permissions (code, name, resource, action) VALUES INSERT INTO permissions (code, name, resource, action) VALUES
('dashboard:view', '查看仪表盘', 'dashboard', 'view'), ('dashboard:view', '查看仪表盘', 'dashboard', 'view'),
('user:view', '查看用户', 'user', 'view'), ('user:view', '查看用户', 'user', 'view'),
@@ -26,7 +33,10 @@ INSERT INTO permissions (code, name, resource, action) VALUES
('audit_log:view', '查看审计日志', 'audit_log', 'view') ('audit_log:view', '查看审计日志', 'audit_log', 'view')
ON DUPLICATE KEY UPDATE name = VALUES(name); ON DUPLICATE KEY UPDATE name = VALUES(name);
-- 插入角色 -- -------------------------------------------
-- 角色数据
-- -------------------------------------------
INSERT INTO roles (code, name, description) VALUES INSERT INTO roles (code, name, description) VALUES
('super_admin', '超级管理员', '拥有所有权限,不可被删除'), ('super_admin', '超级管理员', '拥有所有权限,不可被删除'),
('cs', '客服', '处理用户咨询、群聊、纠纷仲裁'), ('cs', '客服', '处理用户咨询、群聊、纠纷仲裁'),
@@ -34,6 +44,10 @@ INSERT INTO roles (code, name, description) VALUES
('finance', '财务', '查看资金流水、订单信息') ('finance', '财务', '查看资金流水、订单信息')
ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description); ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description);
-- -------------------------------------------
-- 角色权限关联
-- -------------------------------------------
-- super_admin 拥有所有权限 -- super_admin 拥有所有权限
INSERT IGNORE INTO role_permissions (role_id, permission_id) INSERT IGNORE INTO role_permissions (role_id, permission_id)
SELECT r.id, p.id FROM roles r CROSS JOIN permissions p WHERE r.code = 'super_admin'; SELECT r.id, p.id FROM roles r CROSS JOIN permissions p WHERE r.code = 'super_admin';
@@ -53,6 +67,19 @@ INSERT IGNORE INTO role_permissions (role_id, permission_id)
SELECT r.id, p.id FROM roles r, permissions p SELECT r.id, p.id FROM roles r, permissions p
WHERE r.code = 'finance' AND p.code IN ('dashboard:view', 'wallet:view', 'order:view'); WHERE r.code = 'finance' AND p.code IN ('dashboard:view', 'wallet:view', 'order:view');
-- 默认 admin 用户自动绑定 super_admin 角色 -- -------------------------------------------
INSERT IGNORE INTO admin_user_roles (admin_user_id, role_id) -- 系统配置
SELECT au.id, r.id FROM admin_users au, roles r WHERE au.username = 'admin' AND r.code = 'super_admin'; -- -------------------------------------------
INSERT INTO system_configs (`key`, `value`, description) VALUES
('order.handoff_timeout_minutes', '60', '交接超时时间(分钟)'),
('order.return_timeout_minutes', '1440', '归还超时时间(分钟)'),
('sms.rate_limit_per_minute', '1', '短信限流:每分钟最多发送次数'),
('sms.rate_limit_per_hour', '5', '短信限流:每小时最多发送次数'),
('wallet.min_deposit', '50', '最低押金金额'),
('platform.fee_ratio', '0.1', '平台抽成比例'),
('listing.review_required', 'true', '商品是否需要审核'),
('order.pending_payment_timeout_minutes', '15', '待支付超时时间(分钟)'),
('chat.default_support_admin_id', '1', '订单群聊默认接入的客服管理员 ID'),
('chat.auto_welcome_message', '欢迎加入订单群聊!如有任何问题,请随时沟通。', '建群后自动发送的欢迎话术')
ON DUPLICATE KEY UPDATE description = VALUES(description);
@@ -1,19 +0,0 @@
-- 会话备注字段(个人级别)
ALTER TABLE chat_participants ADD COLUMN remark VARCHAR(128) DEFAULT '' AFTER last_read_at;
-- 快捷回复表
CREATE TABLE IF NOT EXISTS chat_quick_replies (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
admin_user_id BIGINT NOT NULL DEFAULT 0 COMMENT '0=全局, >0=个人',
title VARCHAR(64) NOT NULL COMMENT '快捷回复标题',
content TEXT NOT NULL COMMENT '回复内容',
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_admin_user_id (admin_user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快捷回复模板';
-- 建群自动话术配置
INSERT INTO system_configs (`key`, `value`, description) VALUES
('chat.auto_welcome_message', '欢迎加入订单群聊!如有任何问题,请随时沟通。', '建群后自动发送的欢迎话术')
ON DUPLICATE KEY UPDATE description = VALUES(description);
+2 -29
View File
@@ -70,41 +70,14 @@ init_database() {
)" )"
if [[ "${table_count}" == "0" ]]; then if [[ "${table_count}" == "0" ]]; then
log "首次启动,初始化数据库结构..." log "首次启动,初始化数据库..."
local migration local migration
for migration in "${ROOT_DIR}"/backend/migrations/*.sql; do for migration in "${ROOT_DIR}"/backend/migrations/*.sql; do
log "执行迁移:$(basename "${migration}")" log "执行迁移:$(basename "${migration}")"
docker exec -i hfb-mysql mysql -uhfb -psecret --default-character-set=utf8mb4 hfb_sys < "${migration}" docker exec -i hfb-mysql mysql -uhfb -psecret --default-character-set=utf8mb4 hfb_sys < "${migration}"
done done
else else
local chat_table_count log "数据库已存在,跳过迁移(使用 DEV_RESET_DB=1 重建)"
chat_table_count="$(
docker exec hfb-mysql mysql -uhfb -psecret -N -s -e \
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'hfb_sys' AND table_name = 'chat_conversations';" 2>/dev/null
)" || chat_table_count="0"
if [[ "${chat_table_count}" == "0" ]]; then
log "补充聊天表迁移:000002_chat.sql"
docker exec -i hfb-mysql mysql -uhfb -psecret --default-character-set=utf8mb4 hfb_sys < "${ROOT_DIR}/backend/migrations/000002_chat.sql"
fi
local role_count
role_count="$(
docker exec hfb-mysql mysql -uhfb -psecret -N -s -e \
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'hfb_sys' AND table_name = 'roles';" 2>/dev/null
)" || role_count="0"
if [[ "${role_count}" != "0" ]]; then
local seed_count
seed_count="$(
docker exec hfb-mysql mysql -uhfb -psecret -N -s -e \
"SELECT COUNT(*) FROM roles;" 2>/dev/null
)" || seed_count="0"
if [[ "${seed_count}" == "0" ]]; then
log "补充 RBAC 种子数据:000002_rbac_seed.sql"
docker exec -i hfb-mysql mysql -uhfb -psecret --default-character-set=utf8mb4 hfb_sys < "${ROOT_DIR}/backend/migrations/000002_rbac_seed.sql" || true
fi
fi
log "数据库迁移检查完成"
fi fi
} }