-- ============================================================================ -- parking-cloud · P1 系统管理种子数据 -- -- 执行前提:先执行 01_system_schema.sql -- 幂等:全部 INSERT IGNORE + 显式主键,可重复执行(不会重复插、不会覆盖已改过的数据) -- -- ⚠️ 本脚本**只用于本地/开发环境初始化**。上线前必须处理两处: -- 1. admin 的初始密码(见 3. 的说明) -- 2. OAuth2 客户端的 secret(见 8. 的说明) -- 红线第 11 条:禁止把生产密钥提交进仓库。 -- -- 菜单 id 是**刻意固定**的(1 / 2 / 21~26),与 P0 占位实现 -- P0AuthController#buildP0Menus 下发的 id 完全一致,这样 P1 换成真实现后, -- 前端的动态路由与已打开的标签页不会因为 id 变化而失配。 -- ============================================================================ USE parking_cloud; -- --------------------------------------------------------------------------- -- 1. 组织 -- --------------------------------------------------------------------------- INSERT IGNORE INTO system_org (id, name, parent_id, sort, leader, mobile, email, status, remark, create_by, update_by) VALUES (1, '总公司', 0, 1, '管理员', '', '', 0, '顶级组织(种子数据)', 'seed', 'seed'); -- --------------------------------------------------------------------------- -- 2. 角色 -- ⚠️ 超级管理员的 **id 必须为 1** 且 **code 必须为 super_admin** —— 两处硬编码依赖它: -- · 后端 PermissionServiceImpl 用 id=1 判定超管,超管直接拥有全部权限点 -- · 前端 store/modules/user.ts 的 isSuperAdmin 判定 roles.includes('super_admin') -- 改动这一行会让「超管恒有权限」这条链路静默失效(表现为按钮消失但没有报错)。 -- --------------------------------------------------------------------------- INSERT IGNORE INTO system_role (id, name, code, sort, data_scope, status, type, remark, create_by, update_by) VALUES (1, '超级管理员', 'super_admin', 1, 1, 0, 1, '内置角色:拥有全部权限,不可删除', 'seed', 'seed'); -- --------------------------------------------------------------------------- -- 3. 用户 -- admin / admin123 -- password 是 BCrypt 密文,已用 Spring Security 5.7.12 的 -- BCryptPasswordEncoder#matches("admin123", <该串>) 实测为 true -- (密文以 $2y$ 开头,Spring 的 BCrypt 接受 $2a$/$2b$/$2y$ 三种版本前缀)。 -- ⚠️ admin123 是弱口令,仅供本地联调;上线前必须改密(走 /system/user/update-password)。 -- --------------------------------------------------------------------------- INSERT IGNORE INTO system_users (id, username, password, nickname, remark, org_id, email, mobile, sex, status, create_by, update_by) VALUES (1, 'admin', '$2y$10$SG.m/uKIJpcEgJLnvPgZteLpU2PJ1Dv5EBp9krhSmBVASm45XSZ4C', '管理员', '种子数据:初始超级管理员', 1, '', '', 0, 0, 'seed', 'seed'); -- --------------------------------------------------------------------------- -- 4. 用户 ↔ 角色 -- --------------------------------------------------------------------------- INSERT IGNORE INTO system_user_role (user_id, role_id, create_by) VALUES (1, 1, 'seed'); -- --------------------------------------------------------------------------- -- 5. 菜单树 -- type:1 目录,2 菜单,3 按钮(按钮只承载权限标识,不进前端菜单树) -- component:相对 src/views 的路径,必须是**真实存在**的 .vue —— -- 前端 store/modules/permission.ts 用 import.meta.glob('/src/views/**/*.vue') 解析, -- 填错不会报错,只会让该菜单点开后是空白页。 -- 目录节点的 component 必须为 ''(前端只给有 component 的节点建路由), -- 但目录**必须有 path**(/system)作为子菜单路由的前缀。 -- --------------------------------------------------------------------------- -- 5.1 顶级:首页 + 系统管理 INSERT IGNORE INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, create_by, update_by) VALUES (1, '首页', '', 2, 1, 0, '/dashboard', 'ep:home-filled', 'dashboard/index', 'Dashboard', 0, 1, 'seed', 'seed'), (2, '系统管理', '', 1, 2, 0, '/system', 'ep:setting', '', '', 0, 1, 'seed', 'seed'); -- 5.2 一级菜单(系统管理下的 6 个页面) INSERT IGNORE INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, create_by, update_by) VALUES (21, '用户管理', '', 2, 1, 2, '/system/user', 'ep:user', 'system/user/index', 'SystemUser', 0, 1, 'seed', 'seed'), (22, '角色管理', '', 2, 2, 2, '/system/role', 'ep:avatar', 'system/role/index', 'SystemRole', 0, 1, 'seed', 'seed'), (23, '菜单管理', '', 2, 3, 2, '/system/menu', 'ep:menu', 'system/menu/index', 'SystemMenu', 0, 1, 'seed', 'seed'), (24, '组织管理', '', 2, 4, 2, '/system/org', 'ep:office-building', 'system/org/index', 'SystemOrg', 0, 1, 'seed', 'seed'), (25, '字典管理', '', 2, 5, 2, '/system/dict', 'ep:collection', 'system/dict/index', 'SystemDict', 0, 1, 'seed', 'seed'), (26, '日志管理', '', 2, 6, 2, '/system/log', 'ep:document', 'system/log/index', 'SystemLog', 0, 1, 'seed', 'seed'); -- 5.3 按钮权限点 -- 命名规范 模块:资源:动作,与 Controller 上 -- @PreAuthorize("@ss.hasPermission('...')") 以及前端 v-hasPermi="'...'" 三处必须逐字一致。 -- 资源名与前端 API 文件的 BASE 路径对齐:标签用 dict,路径用 /system/dict-type。 INSERT IGNORE INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, create_by, update_by) VALUES -- 用户管理 (101, '用户查询', 'system:user:query', 3, 1, 21, '', '', '', '', 0, 1, 'seed', 'seed'), (102, '用户新增', 'system:user:create', 3, 2, 21, '', '', '', '', 0, 1, 'seed', 'seed'), (103, '用户修改', 'system:user:update', 3, 3, 21, '', '', '', '', 0, 1, 'seed', 'seed'), (104, '用户删除', 'system:user:delete', 3, 4, 21, '', '', '', '', 0, 1, 'seed', 'seed'), (105, '用户导出', 'system:user:export', 3, 5, 21, '', '', '', '', 0, 1, 'seed', 'seed'), (106, '重置密码', 'system:user:update-password', 3, 6, 21, '', '', '', '', 0, 1, 'seed', 'seed'), -- 角色管理 (111, '角色查询', 'system:role:query', 3, 1, 22, '', '', '', '', 0, 1, 'seed', 'seed'), (112, '角色新增', 'system:role:create', 3, 2, 22, '', '', '', '', 0, 1, 'seed', 'seed'), (113, '角色修改', 'system:role:update', 3, 3, 22, '', '', '', '', 0, 1, 'seed', 'seed'), (114, '角色删除', 'system:role:delete', 3, 4, 22, '', '', '', '', 0, 1, 'seed', 'seed'), (115, '角色导出', 'system:role:export', 3, 5, 22, '', '', '', '', 0, 1, 'seed', 'seed'), -- 菜单管理 (121, '菜单查询', 'system:menu:query', 3, 1, 23, '', '', '', '', 0, 1, 'seed', 'seed'), (122, '菜单新增', 'system:menu:create', 3, 2, 23, '', '', '', '', 0, 1, 'seed', 'seed'), (123, '菜单修改', 'system:menu:update', 3, 3, 23, '', '', '', '', 0, 1, 'seed', 'seed'), (124, '菜单删除', 'system:menu:delete', 3, 4, 23, '', '', '', '', 0, 1, 'seed', 'seed'), (125, '菜单导出', 'system:menu:export', 3, 5, 23, '', '', '', '', 0, 1, 'seed', 'seed'), -- 组织管理 (131, '组织查询', 'system:org:query', 3, 1, 24, '', '', '', '', 0, 1, 'seed', 'seed'), (132, '组织新增', 'system:org:create', 3, 2, 24, '', '', '', '', 0, 1, 'seed', 'seed'), (133, '组织修改', 'system:org:update', 3, 3, 24, '', '', '', '', 0, 1, 'seed', 'seed'), (134, '组织删除', 'system:org:delete', 3, 4, 24, '', '', '', '', 0, 1, 'seed', 'seed'), (135, '组织导出', 'system:org:export', 3, 5, 24, '', '', '', '', 0, 1, 'seed', 'seed'), -- 字典管理 (141, '字典查询', 'system:dict:query', 3, 1, 25, '', '', '', '', 0, 1, 'seed', 'seed'), (142, '字典新增', 'system:dict:create', 3, 2, 25, '', '', '', '', 0, 1, 'seed', 'seed'), (143, '字典修改', 'system:dict:update', 3, 3, 25, '', '', '', '', 0, 1, 'seed', 'seed'), (144, '字典删除', 'system:dict:delete', 3, 4, 25, '', '', '', '', 0, 1, 'seed', 'seed'), (145, '字典导出', 'system:dict:export', 3, 5, 25, '', '', '', '', 0, 1, 'seed', 'seed'), -- 日志管理(操作日志只读,无 create/update/delete) (151, '日志查询', 'system:operate-log:query', 3, 1, 26, '', '', '', '', 0, 1, 'seed', 'seed'), (152, '日志导出', 'system:operate-log:export', 3, 2, 26, '', '', '', '', 0, 1, 'seed', 'seed'); -- --------------------------------------------------------------------------- -- 6. 角色 ↔ 菜单:超管拿全部 -- 用 SELECT 而不是罗列 id,这样以后加菜单不必回来改本脚本。 -- 依赖 system_role_menu 的 uk_role_menu 唯一键做幂等去重。 -- --------------------------------------------------------------------------- INSERT IGNORE INTO system_role_menu (role_id, menu_id, create_by) SELECT 1, id, 'seed' FROM system_menu; -- --------------------------------------------------------------------------- -- 7. 字典 -- --------------------------------------------------------------------------- INSERT IGNORE INTO system_dict_type (id, name, type, status, remark, create_by, update_by) VALUES (1, '通用状态', 'system_common_status', 0, '0 开启 / 1 停用', 'seed', 'seed'), (2, '用户性别', 'system_user_sex', 0, '', 'seed', 'seed'), (3, '菜单类型', 'system_menu_type', 0, '1 目录 / 2 菜单 / 3 按钮', 'seed', 'seed'), (4, '数据范围', 'system_data_scope', 0, '角色可访问的数据范围', 'seed', 'seed'), (5, '操作类型', 'system_operate_type', 0, '操作日志的操作类型', 'seed', 'seed'); INSERT IGNORE INTO system_dict_data (id, sort, label, value, dict_type, status, color_type, css_class, remark, create_by, update_by) VALUES (1, 1, '开启', '0', 'system_common_status', 0, 'success', '', '', 'seed', 'seed'), (2, 2, '停用', '1', 'system_common_status', 0, 'danger', '', '', 'seed', 'seed'), (11, 1, '未知', '0', 'system_user_sex', 0, 'info', '', '', 'seed', 'seed'), (12, 2, '男', '1', 'system_user_sex', 0, 'info', '', '', 'seed', 'seed'), (13, 3, '女', '2', 'system_user_sex', 0, 'info', '', '', 'seed', 'seed'), (21, 1, '目录', '1', 'system_menu_type', 0, 'info', '', '', 'seed', 'seed'), (22, 2, '菜单', '2', 'system_menu_type', 0, 'info', '', '', 'seed', 'seed'), (23, 3, '按钮', '3', 'system_menu_type', 0, 'info', '', '', 'seed', 'seed'), (31, 1, '全部', '1', 'system_data_scope', 0, 'info', '', '', 'seed', 'seed'), (32, 2, '自定义', '2', 'system_data_scope', 0, 'info', '', '', 'seed', 'seed'), (33, 3, '本组织', '3', 'system_data_scope', 0, 'info', '', '', 'seed', 'seed'), (34, 4, '本组织及以下', '4', 'system_data_scope', 0, 'info', '', '', 'seed', 'seed'), (35, 5, '仅本人', '5', 'system_data_scope', 0, 'info', '', '', 'seed', 'seed'), -- 操作类型的 value 直接就是中文,与 system_operate_log.type 列存的**同一个字符串**: -- 前端日志页 v1 是直接打印 row.type(没有 DictTag),所以列里必须是可直接展示的值; -- 这里仍保留成字典,是为了将来换成 DictTag 渲染时不用改数据。 (41, 1, '查询', '查询', 'system_operate_type', 0, 'info', '', '', 'seed', 'seed'), (42, 2, '新增', '新增', 'system_operate_type', 0, 'success', '', '', 'seed', 'seed'), (43, 3, '修改', '修改', 'system_operate_type', 0, 'warning', '', '', 'seed', 'seed'), (44, 4, '删除', '删除', 'system_operate_type', 0, 'danger', '', '', 'seed', 'seed'); -- --------------------------------------------------------------------------- -- 8. OAuth2 客户端 -- client_id 与 P0 占位实现保持一致(parking-cloud-ui),改动会让已签发的 token 对不上。 -- -- ⚠️ secret 这里填的是**本地占位值**,不是密钥:管理后台是本方 SPA, -- 浏览器里放任何 "客户端密钥" 都不构成秘密,所以登录接口(/system/auth/login) -- 只收 username/password,**不校验 client secret**。该列留给以后接入第三方 -- 授权(authorization_code)时使用。生产环境请通过环境变量注入真实值。 -- --------------------------------------------------------------------------- INSERT IGNORE INTO system_oauth2_client (id, client_id, secret, name, logo, description, status, access_token_validity_seconds, refresh_token_validity_seconds, redirect_uris, authorized_grant_types, scopes, auto_approve_scopes, additional_information, create_by, update_by) VALUES (1, 'parking-cloud-ui', 'local-dev-placeholder-not-a-secret', '停车云管理后台', '', 'parking-cloud-ui 前端使用', 0, 1800, 2592000, '', 'password,refresh_token', 'server', '', '', 'seed', 'seed'); -- --------------------------------------------------------------------------- -- 校验 -- --------------------------------------------------------------------------- SELECT '组织' AS 表, COUNT(*) AS 行数 FROM system_org UNION ALL SELECT '角色', COUNT(*) FROM system_role UNION ALL SELECT '用户', COUNT(*) FROM system_users UNION ALL SELECT '用户角色', COUNT(*) FROM system_user_role UNION ALL SELECT '菜单', COUNT(*) FROM system_menu UNION ALL SELECT '菜单(按钮)', COUNT(*) FROM system_menu WHERE type = 3 UNION ALL SELECT '角色菜单', COUNT(*) FROM system_role_menu UNION ALL SELECT '字典类型', COUNT(*) FROM system_dict_type UNION ALL SELECT '字典数据', COUNT(*) FROM system_dict_data UNION ALL SELECT 'OAuth2客户端', COUNT(*) FROM system_oauth2_client;