diff --git a/backend/migrations/000001_init.sql b/backend/migrations/000001_init.sql index df951a4..df6009a 100644 --- a/backend/migrations/000001_init.sql +++ b/backend/migrations/000001_init.sql @@ -1,3 +1,15 @@ +-- ============================================ +-- 数据库初始化脚本 +-- 包含所有表结构定义 +-- ============================================ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ------------------------------------------- +-- 用户相关表 +-- ------------------------------------------- + CREATE TABLE users ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, phone VARCHAR(32) NOT NULL, @@ -29,6 +41,10 @@ CREATE TABLE user_realname ( KEY idx_user_realname_provider_order_no (provider_order_no) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- ------------------------------------------- +-- 游戏账号和商品表 +-- ------------------------------------------- + CREATE TABLE game_accounts ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, 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) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- ------------------------------------------- +-- 订单相关表 +-- ------------------------------------------- + CREATE TABLE rental_orders ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(64) NOT NULL, @@ -136,6 +156,10 @@ CREATE TABLE handoff_records ( KEY idx_handoff_records_order_id (order_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- ------------------------------------------- +-- 钱包相关表 +-- ------------------------------------------- + CREATE TABLE wallet_accounts ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, @@ -166,6 +190,10 @@ CREATE TABLE wallet_ledger ( KEY idx_wallet_ledger_biz (biz_type, biz_no) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- ------------------------------------------- +-- 纠纷和通知表 +-- ------------------------------------------- + CREATE TABLE disputes ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, order_id BIGINT UNSIGNED NOT NULL, @@ -213,6 +241,10 @@ CREATE TABLE audit_logs ( KEY idx_audit_logs_biz (biz_type, biz_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- ------------------------------------------- +-- 管理员和权限表 +-- ------------------------------------------- + CREATE TABLE admin_users ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, username VARCHAR(64) NOT NULL, @@ -262,6 +294,10 @@ CREATE TABLE role_permissions ( UNIQUE KEY uk_role_permissions_role_permission (role_id, permission_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- ------------------------------------------- +-- 系统配置表 +-- ------------------------------------------- + CREATE TABLE system_configs ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, `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, UNIQUE KEY uk_system_configs_key (`key`) ) 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; diff --git a/backend/migrations/000002_chat.sql b/backend/migrations/000002_chat.sql deleted file mode 100644 index 12e7f1a..0000000 --- a/backend/migrations/000002_chat.sql +++ /dev/null @@ -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); diff --git a/backend/migrations/000002_rbac_seed.sql b/backend/migrations/000002_seed.sql similarity index 68% rename from backend/migrations/000002_rbac_seed.sql rename to backend/migrations/000002_seed.sql index 22b4bbf..ecc9d0a 100644 --- a/backend/migrations/000002_rbac_seed.sql +++ b/backend/migrations/000002_seed.sql @@ -1,7 +1,14 @@ --- RBAC seed: 默认角色和权限 +-- ============================================ +-- 初始数据脚本 +-- 包含权限、角色、系统配置等基础数据 +-- ============================================ + SET NAMES utf8mb4; --- 插入权限 +-- ------------------------------------------- +-- 权限数据 +-- ------------------------------------------- + INSERT INTO permissions (code, name, resource, action) VALUES ('dashboard:view', '查看仪表盘', 'dashboard', 'view'), ('user:view', '查看用户', 'user', 'view'), @@ -26,7 +33,10 @@ INSERT INTO permissions (code, name, resource, action) VALUES ('audit_log:view', '查看审计日志', 'audit_log', 'view') ON DUPLICATE KEY UPDATE name = VALUES(name); --- 插入角色 +-- ------------------------------------------- +-- 角色数据 +-- ------------------------------------------- + INSERT INTO roles (code, name, description) VALUES ('super_admin', '超级管理员', '拥有所有权限,不可被删除'), ('cs', '客服', '处理用户咨询、群聊、纠纷仲裁'), @@ -34,6 +44,10 @@ INSERT INTO roles (code, name, description) VALUES ('finance', '财务', '查看资金流水、订单信息') ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description); +-- ------------------------------------------- +-- 角色权限关联 +-- ------------------------------------------- + -- super_admin 拥有所有权限 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'; @@ -53,6 +67,19 @@ INSERT IGNORE INTO role_permissions (role_id, permission_id) SELECT r.id, p.id FROM roles r, permissions p 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); diff --git a/backend/migrations/000007_chat_enhancements.sql b/backend/migrations/000007_chat_enhancements.sql deleted file mode 100644 index 466a571..0000000 --- a/backend/migrations/000007_chat_enhancements.sql +++ /dev/null @@ -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); diff --git a/scripts/dev.sh b/scripts/dev.sh index dcd879c..099dc35 100755 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -70,41 +70,14 @@ init_database() { )" if [[ "${table_count}" == "0" ]]; then - log "首次启动,初始化数据库结构..." + log "首次启动,初始化数据库..." local migration for migration in "${ROOT_DIR}"/backend/migrations/*.sql; do log "执行迁移:$(basename "${migration}")" docker exec -i hfb-mysql mysql -uhfb -psecret --default-character-set=utf8mb4 hfb_sys < "${migration}" done else - local chat_table_count - 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 "数据库迁移检查完成" + log "数据库已存在,跳过迁移(使用 DEV_RESET_DB=1 重建)" fi }