SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; -- 七类岗位及权限矩阵来自产品确认的《身份权限预览》:固定岗位使用精确模板,不能再通过旧 ops-admin 迁移不断追加跨模块权限。 -- 性能边界:本迁移只扫描 7 个 role code 和数百条 permission code;role.code、permission.code 均为唯一索引, -- admin_role_permissions 以 (role_id, permission_id) 为主键,DELETE JOIN 和 INSERT SELECT 不扫描业务流水表。 SET @now_ms = CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED); INSERT INTO admin_permissions (name, code, kind, description, created_at_ms, updated_at_ms) VALUES ('支付账单导出', 'payment-bill:export', 'button', '允许导出充值账单,不随列表查看权限自动授予', @now_ms, @now_ms), ('支付账单刷新', 'payment-bill:refresh', 'button', '允许刷新 Google 实付明细,不随列表查看权限自动授予', @now_ms, @now_ms), ('三方支付方式更新', 'payment-third-party:update-method', 'button', '允许调整三方支付方式状态', @now_ms, @now_ms), ('三方支付方式同步', 'payment-third-party:sync-methods', 'button', '允许同步三方支付方式', @now_ms, @now_ms), ('三方支付汇率编辑', 'payment-third-party:update-rate', 'button', '允许编辑三方支付汇率', @now_ms, @now_ms), ('三方支付汇率同步', 'payment-third-party:sync-rates', 'button', '允许全局同步三方支付汇率', @now_ms, @now_ms), ('游戏列表查看', 'game-catalog:view', 'menu', '允许查看游戏列表和游戏平台', @now_ms, @now_ms), ('游戏平台配置', 'game-catalog:platform', 'button', '允许新增、编辑和同步游戏平台', @now_ms, @now_ms), ('游戏列表创建', 'game-catalog:create', 'button', '允许新增游戏', @now_ms, @now_ms), ('游戏列表更新', 'game-catalog:update', 'button', '允许编辑游戏和游戏白名单', @now_ms, @now_ms), ('游戏列表状态', 'game-catalog:status', 'button', '允许启用或停用游戏', @now_ms, @now_ms), ('游戏列表删除', 'game-catalog:delete', 'button', '允许删除游戏', @now_ms, @now_ms), ('自研游戏查看', 'self-game:view', 'menu', '允许查看自研游戏配置', @now_ms, @now_ms), ('自研游戏配置', 'self-game:update', 'button', '允许修改骰子、新手策略和档位奖池', @now_ms, @now_ms), ('全站机器人查看', 'game-robot:view', 'menu', '允许查看全站机器人', @now_ms, @now_ms), ('全站机器人创建', 'game-robot:create', 'button', '允许批量创建全站机器人', @now_ms, @now_ms), ('全站机器人更新', 'game-robot:update', 'button', '允许修改全站机器人状态', @now_ms, @now_ms), ('全站机器人删除', 'game-robot:delete', 'button', '允许删除全站机器人', @now_ms, @now_ms), ('房内猜拳配置查看', 'room-rps-config:view', 'menu', '允许查看房内猜拳配置', @now_ms, @now_ms), ('房内猜拳配置更新', 'room-rps-config:update', 'button', '允许修改房内猜拳配置', @now_ms, @now_ms), ('房内猜拳订单查看', 'room-rps-order:view', 'menu', '允许查看房内猜拳订单', @now_ms, @now_ms), ('房内猜拳订单更新', 'room-rps-order:update', 'button', '允许重试结算或手动过期房内猜拳订单', @now_ms, @now_ms) ON DUPLICATE KEY UPDATE name = VALUES(name), kind = VALUES(kind), description = VALUES(description), updated_at_ms = @now_ms; -- 历史粗粒度权限保留给用户自建角色兼容,但固定岗位不再绑定这些 code。 UPDATE admin_permissions SET description = CASE code WHEN 'payment-third-party:update' THEN '兼容旧角色的三方支付写权限' WHEN 'game:view' THEN '兼容旧角色的游戏管理查看权限' WHEN 'game:create' THEN '兼容旧角色的游戏管理创建权限' WHEN 'game:update' THEN '兼容旧角色的游戏管理更新权限' WHEN 'game:status' THEN '兼容旧角色的游戏管理状态权限' WHEN 'game:delete' THEN '兼容旧角色的游戏管理删除权限' ELSE description END, updated_at_ms = @now_ms WHERE code IN ('payment-third-party:update', 'game:view', 'game:create', 'game:update', 'game:status', 'game:delete'); UPDATE admin_menus SET permission_code = CASE code WHEN 'game-list' THEN 'game-catalog:view' WHEN 'self-games' THEN 'self-game:view' WHEN 'game-robots' THEN 'game-robot:view' WHEN 'room-rps-config' THEN 'room-rps-config:view' WHEN 'room-rps-challenges' THEN 'room-rps-order:view' ELSE permission_code END, updated_at_ms = @now_ms WHERE code IN ('game-list', 'self-games', 'game-robots', 'room-rps-config', 'room-rps-challenges'); INSERT INTO admin_roles (name, code, description, created_at_ms, updated_at_ms) VALUES ('超级管理员', 'platform-admin', '拥有管理后台全部权限', @now_ms, @now_ms), ('运营负责人', 'ops-admin', '负责运营、团队、活动和日常配置管理', @now_ms, @now_ms), ('运营专员', 'operations-specialist', '负责日常运营执行,不含后台设置和高风险财务配置', @now_ms, @now_ms), ('产品负责人', 'product-lead', '负责产品配置、资源、活动和游戏管理', @now_ms, @now_ms), ('产品专员', 'product-specialist', '负责资源配置,并只读查看关联业务模块', @now_ms, @now_ms), ('财务负责人', 'finance-lead', '负责财务看板、充值对账和提现审核', @now_ms, @now_ms), ('财务专员', 'finance-specialist', '负责财务看板、充值对账和提现审核', @now_ms, @now_ms) ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description), updated_at_ms = @now_ms; -- 只清理产品管理的七类固定岗位;审计员、只读用户和用户自建角色保留原绑定,避免破坏历史兼容。 DELETE role_permission FROM admin_role_permissions role_permission JOIN admin_roles role ON role.id = role_permission.role_id WHERE role.code IN ( 'platform-admin', 'ops-admin', 'operations-specialist', 'product-lead', 'product-specialist', 'finance-lead', 'finance-specialist' ); INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) SELECT role.id, permission.id FROM admin_roles role JOIN admin_permissions permission WHERE role.code = 'platform-admin'; INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) SELECT role.id, permission.id FROM admin_roles role JOIN admin_permissions permission WHERE role.code = 'ops-admin' AND permission.code IN ( 'overview:view', 'finance-order:coin-seller-recharge:view', 'finance-order:coin-seller-recharge:create', 'finance-order:coin-seller-recharge:verify', 'finance-order:coin-seller-recharge:grant', 'finance-withdrawal:view', 'finance-withdrawal:audit', 'app-user:view', 'app-user:export', 'app-user:update', 'app-user:level', 'app-user:status', 'app-user:password', 'level-config:view', 'level-config:update', 'pretty-id:view', 'pretty-id:update', 'pretty-id:grant', 'risk-config:view', 'risk-config:update', 'region-block:view', 'region-block:update', 'bd:view', 'bd:create', 'bd:update', 'agency:view', 'agency:create', 'agency:status', 'agency:delete', 'host:view', 'host-agency-policy:view', 'host-agency-policy:create', 'host-agency-policy:update', 'host-agency-policy:delete', 'host-agency-policy:publish', 'team-salary-policy:view', 'team-salary-policy:create', 'team-salary-policy:update', 'team-salary-policy:delete', 'host-salary-settlement:view', 'host-salary-settlement:settle', 'coin-seller:view', 'coin-seller:create', 'coin-seller:update', 'coin-seller:stock-credit', 'coin-seller:exchange-rate', 'coin-seller-sub-application:view', 'coin-seller-sub-application:audit', 'host-withdrawal:view', 'point-withdrawal-config:view', 'point-withdrawal-config:update', 'room:view', 'room:update', 'room:delete', 'room-pin:view', 'room-pin:create', 'room-pin:cancel', 'room-config:view', 'room-config:update', 'room-whitelist:view', 'room-whitelist:update', 'room-robot:view', 'room-robot:create', 'room-robot:update', 'app-config:view', 'app-config:update', 'full-server-notice:send', 'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create', 'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete', 'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create', 'coin-ledger:view', 'coin-seller-ledger:view', 'coin-adjustment:view', 'coin-adjustment:create', 'report:view', 'gift-diamond:view', 'gift-diamond:update', 'policy-template:view', 'policy-template:create', 'policy-instance:create', 'policy-instance:update', 'policy-instance:publish', 'payment-bill:view', 'payment-bill:export', 'payment-bill:refresh', 'payment-third-party:view', 'payment-third-party:update-method', 'payment-third-party:sync-methods', 'payment-temporary-link:view', 'payment-product:view', 'payment-product:create', 'payment-product:update', 'payment-product:delete', 'daily-task:view', 'daily-task:create', 'daily-task:update', 'daily-task:status', 'first-recharge-reward:view', 'first-recharge-reward:update', 'cumulative-recharge-reward:view', 'cumulative-recharge-reward:update', 'invite-activity-reward:view', 'invite-activity-reward:update', 'seven-day-checkin:view', 'seven-day-checkin:update', 'room-rocket:view', 'room-rocket:update', 'room-turnover-reward:view', 'room-turnover-reward:update', 'room-turnover-reward:retry', 'wheel:view', 'wheel:update', 'weekly-star:view', 'weekly-star:create', 'weekly-star:update', 'weekly-star:settle', 'agency-opening:view', 'agency-opening:create', 'agency-opening:update', 'user-leaderboard:view', 'red-packet:view', 'red-packet:update', 'cp-config:view', 'cp-config:update', 'cp-weekly-rank:view', 'cp-weekly-rank:update', 'vip-config:view', 'vip-config:update', 'achievement:view', 'achievement:create', 'achievement:update', 'game-catalog:view', 'game-catalog:platform', 'game-catalog:create', 'game-catalog:update', 'game-catalog:status', 'game-catalog:delete', 'self-game:view', 'self-game:update', 'game-robot:view', 'game-robot:create', 'game-robot:update', 'game-robot:delete', 'room-rps-config:view', 'room-rps-config:update', 'room-rps-order:view', 'room-rps-order:update', 'country:view', 'country:create', 'country:update', 'country:status', 'region:view', 'region:create', 'region:update', 'region:status' ); INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) SELECT role.id, permission.id FROM admin_roles role JOIN admin_permissions permission WHERE role.code = 'operations-specialist' AND permission.code IN ( 'overview:view', 'finance-order:coin-seller-recharge:view', 'finance-order:coin-seller-recharge:create', 'finance-order:coin-seller-recharge:verify', 'finance-order:coin-seller-recharge:grant', 'finance-withdrawal:view', 'finance-withdrawal:audit', 'app-user:view', 'app-user:export', 'app-user:update', 'app-user:level', 'app-user:status', 'app-user:password', 'level-config:view', 'level-config:update', 'pretty-id:view', 'pretty-id:update', 'pretty-id:grant', 'risk-config:view', 'risk-config:update', 'region-block:view', 'region-block:update', 'bd:view', 'bd:create', 'bd:update', 'agency:view', 'agency:create', 'agency:status', 'agency:delete', 'host:view', 'host-agency-policy:view', 'team-salary-policy:view', 'host-salary-settlement:view', 'coin-seller:view', 'coin-seller-sub-application:view', 'host-withdrawal:view', 'point-withdrawal-config:view', 'room:view', 'room:update', 'room:delete', 'room-pin:view', 'room-pin:create', 'room-pin:cancel', 'room-config:view', 'room-config:update', 'room-whitelist:view', 'room-whitelist:update', 'room-robot:view', 'room-robot:create', 'room-robot:update', 'app-config:view', 'app-config:update', 'full-server-notice:send', 'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create', 'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete', 'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create', 'coin-ledger:view', 'coin-seller-ledger:view', 'report:view', 'payment-bill:view', 'payment-bill:export', 'payment-bill:refresh', 'payment-third-party:view', 'payment-temporary-link:view', 'payment-product:view', 'daily-task:view', 'first-recharge-reward:view', 'cumulative-recharge-reward:view', 'invite-activity-reward:view', 'seven-day-checkin:view', 'room-rocket:view', 'room-turnover-reward:view', 'wheel:view', 'weekly-star:view', 'agency-opening:view', 'user-leaderboard:view', 'red-packet:view', 'cp-config:view', 'cp-weekly-rank:view', 'vip-config:view', 'achievement:view', 'game-catalog:view', 'self-game:view', 'game-robot:view', 'game-robot:create', 'game-robot:update', 'game-robot:delete', 'room-rps-config:view', 'room-rps-config:update', 'room-rps-order:view', 'country:view', 'region:view' ); INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) SELECT role.id, permission.id FROM admin_roles role JOIN admin_permissions permission WHERE role.code = 'product-lead' AND permission.code IN ( 'overview:view', 'app-user:view', 'app-user:export', 'level-config:view', 'level-config:update', 'pretty-id:view', 'pretty-id:update', 'pretty-id:grant', 'risk-config:view', 'risk-config:update', 'region-block:view', 'region-block:update', 'bd:view', 'agency:view', 'host:view', 'host-agency-policy:view', 'team-salary-policy:view', 'host-salary-settlement:view', 'coin-seller:view', 'coin-seller-sub-application:view', 'host-withdrawal:view', 'point-withdrawal-config:view', 'room:view', 'room:update', 'room:delete', 'room-pin:view', 'room-pin:create', 'room-pin:cancel', 'room-config:view', 'room-config:update', 'room-whitelist:view', 'room-whitelist:update', 'room-robot:view', 'room-robot:create', 'room-robot:update', 'app-config:view', 'app-config:update', 'app-version:view', 'app-version:create', 'app-version:update', 'app-version:delete', 'full-server-notice:view', 'full-server-notice:send', 'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create', 'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete', 'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create', 'coin-ledger:view', 'coin-seller-ledger:view', 'report:view', 'gift-diamond:view', 'gift-diamond:update', 'payment-bill:view', 'payment-third-party:view', 'payment-temporary-link:view', 'payment-product:view', 'daily-task:view', 'daily-task:create', 'daily-task:update', 'daily-task:status', 'first-recharge-reward:view', 'first-recharge-reward:update', 'cumulative-recharge-reward:view', 'cumulative-recharge-reward:update', 'invite-activity-reward:view', 'invite-activity-reward:update', 'seven-day-checkin:view', 'seven-day-checkin:update', 'room-rocket:view', 'room-rocket:update', 'room-turnover-reward:view', 'room-turnover-reward:update', 'room-turnover-reward:retry', 'wheel:view', 'wheel:update', 'weekly-star:view', 'weekly-star:create', 'weekly-star:update', 'weekly-star:settle', 'agency-opening:view', 'agency-opening:create', 'agency-opening:update', 'user-leaderboard:view', 'red-packet:view', 'red-packet:update', 'cp-config:view', 'cp-config:update', 'cp-weekly-rank:view', 'cp-weekly-rank:update', 'vip-config:view', 'vip-config:update', 'achievement:view', 'achievement:create', 'achievement:update', 'game-catalog:view', 'game-catalog:platform', 'game-catalog:create', 'game-catalog:update', 'game-catalog:status', 'game-catalog:delete', 'self-game:view', 'self-game:update', 'game-robot:view', 'game-robot:create', 'game-robot:update', 'game-robot:delete', 'room-rps-config:view', 'room-rps-config:update', 'room-rps-order:view', 'room-rps-order:update', 'country:view', 'region:view' ); INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) SELECT role.id, permission.id FROM admin_roles role JOIN admin_permissions permission WHERE role.code = 'product-specialist' AND permission.code IN ( 'overview:view', 'app-user:view', 'app-user:export', 'level-config:view', 'pretty-id:view', 'risk-config:view', 'region-block:view', 'room:view', 'room-pin:view', 'room-config:view', 'room-whitelist:view', 'room-robot:view', 'room-robot:create', 'room-robot:update', 'app-config:view', 'app-version:view', 'full-server-notice:view', 'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create', 'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete', 'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create', 'coin-ledger:view', 'coin-seller-ledger:view', 'report:view', 'payment-bill:view', 'payment-third-party:view', 'payment-temporary-link:view', 'payment-product:view', 'daily-task:view', 'first-recharge-reward:view', 'cumulative-recharge-reward:view', 'invite-activity-reward:view', 'seven-day-checkin:view', 'room-rocket:view', 'room-turnover-reward:view', 'wheel:view', 'weekly-star:view', 'agency-opening:view', 'user-leaderboard:view', 'red-packet:view', 'cp-config:view', 'cp-weekly-rank:view', 'vip-config:view', 'achievement:view', 'game-catalog:view', 'self-game:view', 'game-robot:view', 'room-rps-config:view', 'room-rps-order:view', 'country:view', 'region:view' ); INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) SELECT role.id, permission.id FROM admin_roles role JOIN admin_permissions permission WHERE role.code IN ('finance-lead', 'finance-specialist') AND permission.code IN ( 'overview:view', 'finance:view', 'payment-bill:view', 'payment-bill:export', 'finance-withdrawal:view', 'finance-withdrawal:audit', 'room-rps-order:view' );