reinit_rbac_data_fixed.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. #!/usr/bin/env python3
  2. """
  3. 重新初始化RBAC数据 - 修复菜单层级关系混乱问题
  4. 清晰的三级结构:父目录菜单 > 功能菜单 > 按钮权限
  5. """
  6. import pymysql
  7. from dotenv import load_dotenv
  8. import os
  9. import uuid
  10. from datetime import datetime
  11. load_dotenv()
  12. def get_db_connection():
  13. """获取数据库连接"""
  14. try:
  15. config = {
  16. 'host': os.getenv('DB_HOST', 'localhost'),
  17. 'port': int(os.getenv('DB_PORT', 3306)),
  18. 'user': os.getenv('DB_USER', 'root'),
  19. 'password': os.getenv('DB_PASSWORD', 'admin'),
  20. 'database': os.getenv('DB_NAME', 'lq_db'),
  21. 'charset': 'utf8mb4',
  22. 'autocommit': True
  23. }
  24. return pymysql.connect(**config)
  25. except Exception as e:
  26. print(f"数据库连接失败: {e}")
  27. return None
  28. def clear_rbac_data(cursor):
  29. """清理现有RBAC数据"""
  30. print("🧹 清理现有RBAC数据...")
  31. # 清理关联表
  32. cursor.execute("DELETE FROM role_permissions")
  33. cursor.execute("DELETE FROM role_menus")
  34. cursor.execute("DELETE FROM user_roles")
  35. # 清理主表
  36. cursor.execute("DELETE FROM permissions")
  37. cursor.execute("DELETE FROM menus")
  38. cursor.execute("DELETE FROM roles")
  39. print(" ✅ 清理完成")
  40. def insert_menus(cursor):
  41. """插入菜单数据 - 清晰的三级结构"""
  42. print("📋 插入菜单数据(修复层级关系)...")
  43. menus_data = [
  44. # ==================== 第一级:主菜单(父目录菜单) ====================
  45. {
  46. 'id': 'dashboard-main',
  47. 'parent_id': None,
  48. 'name': 'dashboard',
  49. 'title': '仪表盘',
  50. 'path': '/dashboard',
  51. 'component': 'dashboard/Index',
  52. 'icon': 'House',
  53. 'sort_order': 1,
  54. 'menu_type': 'menu',
  55. 'is_hidden': False,
  56. 'description': '系统概览和统计信息'
  57. },
  58. {
  59. 'id': 'profile-main',
  60. 'parent_id': None,
  61. 'name': 'profile',
  62. 'title': '个人资料',
  63. 'path': '/profile',
  64. 'component': 'user/Profile',
  65. 'icon': 'User',
  66. 'sort_order': 2,
  67. 'menu_type': 'menu',
  68. 'is_hidden': False,
  69. 'description': '个人信息管理'
  70. },
  71. {
  72. 'id': 'admin-main',
  73. 'parent_id': None,
  74. 'name': 'admin',
  75. 'title': '系统管理',
  76. 'path': '/admin',
  77. 'component': None,
  78. 'icon': 'Setting',
  79. 'sort_order': 3,
  80. 'menu_type': 'menu',
  81. 'is_hidden': False,
  82. 'description': '系统管理功能目录'
  83. },
  84. # ==================== 第二级:功能菜单 ====================
  85. # 系统管理下的功能菜单
  86. {
  87. 'id': 'admin-dashboard',
  88. 'parent_id': 'admin-main',
  89. 'name': 'admin-dashboard',
  90. 'title': '管理概览',
  91. 'path': '/admin/dashboard',
  92. 'component': 'admin/Dashboard',
  93. 'icon': 'Monitor',
  94. 'sort_order': 1,
  95. 'menu_type': 'menu',
  96. 'is_hidden': False,
  97. 'description': '管理员仪表盘'
  98. },
  99. {
  100. 'id': 'user-management',
  101. 'parent_id': 'admin-main',
  102. 'name': 'user-management',
  103. 'title': '用户管理',
  104. 'path': '/admin/users',
  105. 'component': 'admin/Users',
  106. 'icon': 'UserFilled',
  107. 'sort_order': 2,
  108. 'menu_type': 'menu',
  109. 'is_hidden': False,
  110. 'description': '用户信息管理'
  111. },
  112. {
  113. 'id': 'role-management',
  114. 'parent_id': 'admin-main',
  115. 'name': 'role-management',
  116. 'title': '角色管理',
  117. 'path': '/admin/roles',
  118. 'component': 'admin/Roles',
  119. 'icon': 'Avatar',
  120. 'sort_order': 3,
  121. 'menu_type': 'menu',
  122. 'is_hidden': False,
  123. 'description': '角色权限管理'
  124. },
  125. {
  126. 'id': 'menu-management',
  127. 'parent_id': 'admin-main',
  128. 'name': 'menu-management',
  129. 'title': '菜单管理',
  130. 'path': '/admin/menus',
  131. 'component': 'admin/Menus',
  132. 'icon': 'Menu',
  133. 'sort_order': 4,
  134. 'menu_type': 'menu',
  135. 'is_hidden': False,
  136. 'description': '菜单结构管理'
  137. },
  138. {
  139. 'id': 'permission-management',
  140. 'parent_id': 'admin-main',
  141. 'name': 'permission-management',
  142. 'title': '权限管理',
  143. 'path': '/admin/permissions',
  144. 'component': 'admin/Permissions',
  145. 'icon': 'Key',
  146. 'sort_order': 5,
  147. 'menu_type': 'menu',
  148. 'is_hidden': False,
  149. 'description': '权限配置管理'
  150. },
  151. {
  152. 'id': 'app-management',
  153. 'parent_id': 'admin-main',
  154. 'name': 'app-management',
  155. 'title': '应用管理',
  156. 'path': '/admin/apps',
  157. 'component': 'admin/Apps',
  158. 'icon': 'Grid',
  159. 'sort_order': 6,
  160. 'menu_type': 'menu',
  161. 'is_hidden': False,
  162. 'description': 'OAuth2应用管理'
  163. },
  164. {
  165. 'id': 'log-management',
  166. 'parent_id': 'admin-main',
  167. 'name': 'log-management',
  168. 'title': '系统日志',
  169. 'path': '/admin/logs',
  170. 'component': 'admin/Logs',
  171. 'icon': 'Document',
  172. 'sort_order': 7,
  173. 'menu_type': 'menu',
  174. 'is_hidden': False,
  175. 'description': '系统操作日志'
  176. },
  177. {
  178. 'id': 'system-settings',
  179. 'parent_id': 'admin-main',
  180. 'name': 'system-settings',
  181. 'title': '系统设置',
  182. 'path': '/admin/settings',
  183. 'component': 'admin/Settings',
  184. 'icon': 'Tools',
  185. 'sort_order': 8,
  186. 'menu_type': 'menu',
  187. 'is_hidden': False,
  188. 'description': '系统配置设置'
  189. },
  190. # ==================== 第三级:按钮权限 ====================
  191. # 用户管理的按钮权限
  192. {
  193. 'id': 'user-create-btn',
  194. 'parent_id': 'user-management',
  195. 'name': 'user-create',
  196. 'title': '创建用户',
  197. 'path': None,
  198. 'component': None,
  199. 'icon': 'Plus',
  200. 'sort_order': 1,
  201. 'menu_type': 'button',
  202. 'is_hidden': False,
  203. 'description': '创建新用户'
  204. },
  205. {
  206. 'id': 'user-edit-btn',
  207. 'parent_id': 'user-management',
  208. 'name': 'user-edit',
  209. 'title': '编辑用户',
  210. 'path': None,
  211. 'component': None,
  212. 'icon': 'Edit',
  213. 'sort_order': 2,
  214. 'menu_type': 'button',
  215. 'is_hidden': False,
  216. 'description': '编辑用户信息'
  217. },
  218. {
  219. 'id': 'user-delete-btn',
  220. 'parent_id': 'user-management',
  221. 'name': 'user-delete',
  222. 'title': '删除用户',
  223. 'path': None,
  224. 'component': None,
  225. 'icon': 'Delete',
  226. 'sort_order': 3,
  227. 'menu_type': 'button',
  228. 'is_hidden': False,
  229. 'description': '删除用户'
  230. },
  231. {
  232. 'id': 'user-batch-delete-btn',
  233. 'parent_id': 'user-management',
  234. 'name': 'user-batch-delete',
  235. 'title': '批量删除用户',
  236. 'path': None,
  237. 'component': None,
  238. 'icon': 'DeleteFilled',
  239. 'sort_order': 4,
  240. 'menu_type': 'button',
  241. 'is_hidden': False,
  242. 'description': '批量删除用户'
  243. },
  244. {
  245. 'id': 'user-assign-role-btn',
  246. 'parent_id': 'user-management',
  247. 'name': 'user-assign-role',
  248. 'title': '分配角色',
  249. 'path': None,
  250. 'component': None,
  251. 'icon': 'Avatar',
  252. 'sort_order': 5,
  253. 'menu_type': 'button',
  254. 'is_hidden': False,
  255. 'description': '为用户分配角色'
  256. },
  257. {
  258. 'id': 'user-reset-password-btn',
  259. 'parent_id': 'user-management',
  260. 'name': 'user-reset-password',
  261. 'title': '重置密码',
  262. 'path': None,
  263. 'component': None,
  264. 'icon': 'Key',
  265. 'sort_order': 6,
  266. 'menu_type': 'button',
  267. 'is_hidden': False,
  268. 'description': '重置用户密码'
  269. },
  270. # 角色管理的按钮权限
  271. {
  272. 'id': 'role-create-btn',
  273. 'parent_id': 'role-management',
  274. 'name': 'role-create',
  275. 'title': '创建角色',
  276. 'path': None,
  277. 'component': None,
  278. 'icon': 'Plus',
  279. 'sort_order': 1,
  280. 'menu_type': 'button',
  281. 'is_hidden': False,
  282. 'description': '创建新角色'
  283. },
  284. {
  285. 'id': 'role-edit-btn',
  286. 'parent_id': 'role-management',
  287. 'name': 'role-edit',
  288. 'title': '编辑角色',
  289. 'path': None,
  290. 'component': None,
  291. 'icon': 'Edit',
  292. 'sort_order': 2,
  293. 'menu_type': 'button',
  294. 'is_hidden': False,
  295. 'description': '编辑角色信息'
  296. },
  297. {
  298. 'id': 'role-delete-btn',
  299. 'parent_id': 'role-management',
  300. 'name': 'role-delete',
  301. 'title': '删除角色',
  302. 'path': None,
  303. 'component': None,
  304. 'icon': 'Delete',
  305. 'sort_order': 3,
  306. 'menu_type': 'button',
  307. 'is_hidden': False,
  308. 'description': '删除角色'
  309. },
  310. {
  311. 'id': 'role-assign-permission-btn',
  312. 'parent_id': 'role-management',
  313. 'name': 'role-assign-permission',
  314. 'title': '分配权限',
  315. 'path': None,
  316. 'component': None,
  317. 'icon': 'Key',
  318. 'sort_order': 4,
  319. 'menu_type': 'button',
  320. 'is_hidden': False,
  321. 'description': '为角色分配权限'
  322. },
  323. {
  324. 'id': 'role-assign-menu-btn',
  325. 'parent_id': 'role-management',
  326. 'name': 'role-assign-menu',
  327. 'title': '分配菜单',
  328. 'path': None,
  329. 'component': None,
  330. 'icon': 'Menu',
  331. 'sort_order': 5,
  332. 'menu_type': 'button',
  333. 'is_hidden': False,
  334. 'description': '为角色分配菜单'
  335. },
  336. # 菜单管理的按钮权限
  337. {
  338. 'id': 'menu-create-btn',
  339. 'parent_id': 'menu-management',
  340. 'name': 'menu-create',
  341. 'title': '创建菜单',
  342. 'path': None,
  343. 'component': None,
  344. 'icon': 'Plus',
  345. 'sort_order': 1,
  346. 'menu_type': 'button',
  347. 'is_hidden': False,
  348. 'description': '创建新菜单'
  349. },
  350. {
  351. 'id': 'menu-edit-btn',
  352. 'parent_id': 'menu-management',
  353. 'name': 'menu-edit',
  354. 'title': '编辑菜单',
  355. 'path': None,
  356. 'component': None,
  357. 'icon': 'Edit',
  358. 'sort_order': 2,
  359. 'menu_type': 'button',
  360. 'is_hidden': False,
  361. 'description': '编辑菜单信息'
  362. },
  363. {
  364. 'id': 'menu-delete-btn',
  365. 'parent_id': 'menu-management',
  366. 'name': 'menu-delete',
  367. 'title': '删除菜单',
  368. 'path': None,
  369. 'component': None,
  370. 'icon': 'Delete',
  371. 'sort_order': 3,
  372. 'menu_type': 'button',
  373. 'is_hidden': False,
  374. 'description': '删除菜单'
  375. },
  376. {
  377. 'id': 'menu-sort-btn',
  378. 'parent_id': 'menu-management',
  379. 'name': 'menu-sort',
  380. 'title': '排序菜单',
  381. 'path': None,
  382. 'component': None,
  383. 'icon': 'Sort',
  384. 'sort_order': 4,
  385. 'menu_type': 'button',
  386. 'is_hidden': False,
  387. 'description': '调整菜单排序'
  388. },
  389. # 权限管理的按钮权限
  390. {
  391. 'id': 'permission-create-btn',
  392. 'parent_id': 'permission-management',
  393. 'name': 'permission-create',
  394. 'title': '创建权限',
  395. 'path': None,
  396. 'component': None,
  397. 'icon': 'Plus',
  398. 'sort_order': 1,
  399. 'menu_type': 'button',
  400. 'is_hidden': False,
  401. 'description': '创建新权限'
  402. },
  403. {
  404. 'id': 'permission-edit-btn',
  405. 'parent_id': 'permission-management',
  406. 'name': 'permission-edit',
  407. 'title': '编辑权限',
  408. 'path': None,
  409. 'component': None,
  410. 'icon': 'Edit',
  411. 'sort_order': 2,
  412. 'menu_type': 'button',
  413. 'is_hidden': False,
  414. 'description': '编辑权限信息'
  415. },
  416. {
  417. 'id': 'permission-delete-btn',
  418. 'parent_id': 'permission-management',
  419. 'name': 'permission-delete',
  420. 'title': '删除权限',
  421. 'path': None,
  422. 'component': None,
  423. 'icon': 'Delete',
  424. 'sort_order': 3,
  425. 'menu_type': 'button',
  426. 'is_hidden': False,
  427. 'description': '删除权限'
  428. },
  429. # 应用管理的按钮权限
  430. {
  431. 'id': 'app-create-btn',
  432. 'parent_id': 'app-management',
  433. 'name': 'app-create',
  434. 'title': '创建应用',
  435. 'path': None,
  436. 'component': None,
  437. 'icon': 'Plus',
  438. 'sort_order': 1,
  439. 'menu_type': 'button',
  440. 'is_hidden': False,
  441. 'description': '创建OAuth2应用'
  442. },
  443. {
  444. 'id': 'app-edit-btn',
  445. 'parent_id': 'app-management',
  446. 'name': 'app-edit',
  447. 'title': '编辑应用',
  448. 'path': None,
  449. 'component': None,
  450. 'icon': 'Edit',
  451. 'sort_order': 2,
  452. 'menu_type': 'button',
  453. 'is_hidden': False,
  454. 'description': '编辑应用信息'
  455. },
  456. {
  457. 'id': 'app-delete-btn',
  458. 'parent_id': 'app-management',
  459. 'name': 'app-delete',
  460. 'title': '删除应用',
  461. 'path': None,
  462. 'component': None,
  463. 'icon': 'Delete',
  464. 'sort_order': 3,
  465. 'menu_type': 'button',
  466. 'is_hidden': False,
  467. 'description': '删除应用'
  468. },
  469. {
  470. 'id': 'app-view-secret-btn',
  471. 'parent_id': 'app-management',
  472. 'name': 'app-view-secret',
  473. 'title': '查看密钥',
  474. 'path': None,
  475. 'component': None,
  476. 'icon': 'View',
  477. 'sort_order': 4,
  478. 'menu_type': 'button',
  479. 'is_hidden': False,
  480. 'description': '查看应用密钥'
  481. },
  482. {
  483. 'id': 'app-reset-secret-btn',
  484. 'parent_id': 'app-management',
  485. 'name': 'app-reset-secret',
  486. 'title': '重置密钥',
  487. 'path': None,
  488. 'component': None,
  489. 'icon': 'RefreshRight',
  490. 'sort_order': 5,
  491. 'menu_type': 'button',
  492. 'is_hidden': False,
  493. 'description': '重置应用密钥'
  494. },
  495. # 系统日志的按钮权限
  496. {
  497. 'id': 'log-view-btn',
  498. 'parent_id': 'log-management',
  499. 'name': 'log-view',
  500. 'title': '查看日志',
  501. 'path': None,
  502. 'component': None,
  503. 'icon': 'View',
  504. 'sort_order': 1,
  505. 'menu_type': 'button',
  506. 'is_hidden': False,
  507. 'description': '查看系统日志'
  508. },
  509. {
  510. 'id': 'log-export-btn',
  511. 'parent_id': 'log-management',
  512. 'name': 'log-export',
  513. 'title': '导出日志',
  514. 'path': None,
  515. 'component': None,
  516. 'icon': 'Download',
  517. 'sort_order': 2,
  518. 'menu_type': 'button',
  519. 'is_hidden': False,
  520. 'description': '导出系统日志'
  521. },
  522. {
  523. 'id': 'log-clear-btn',
  524. 'parent_id': 'log-management',
  525. 'name': 'log-clear',
  526. 'title': '清理日志',
  527. 'path': None,
  528. 'component': None,
  529. 'icon': 'Delete',
  530. 'sort_order': 3,
  531. 'menu_type': 'button',
  532. 'is_hidden': False,
  533. 'description': '清理历史日志'
  534. },
  535. # 系统设置的按钮权限
  536. {
  537. 'id': 'settings-view-btn',
  538. 'parent_id': 'system-settings',
  539. 'name': 'settings-view',
  540. 'title': '查看设置',
  541. 'path': None,
  542. 'component': None,
  543. 'icon': 'View',
  544. 'sort_order': 1,
  545. 'menu_type': 'button',
  546. 'is_hidden': False,
  547. 'description': '查看系统设置'
  548. },
  549. {
  550. 'id': 'settings-edit-btn',
  551. 'parent_id': 'system-settings',
  552. 'name': 'settings-edit',
  553. 'title': '修改设置',
  554. 'path': None,
  555. 'component': None,
  556. 'icon': 'Edit',
  557. 'sort_order': 2,
  558. 'menu_type': 'button',
  559. 'is_hidden': False,
  560. 'description': '修改系统设置'
  561. }
  562. ]
  563. for menu in menus_data:
  564. cursor.execute("""
  565. INSERT INTO menus (id, parent_id, name, title, path, component, icon, sort_order, menu_type, is_hidden, is_active, description, created_at, updated_at)
  566. VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
  567. """, (
  568. menu['id'], menu['parent_id'], menu['name'], menu['title'],
  569. menu['path'], menu['component'], menu['icon'], menu['sort_order'],
  570. menu['menu_type'], menu['is_hidden'], True, menu['description']
  571. ))
  572. print(f" ✅ 插入了 {len(menus_data)} 个菜单项")
  573. # 统计各级菜单数量
  574. main_menus = len([m for m in menus_data if not m['parent_id']])
  575. function_menus = len([m for m in menus_data if m['parent_id'] and m['menu_type'] == 'menu'])
  576. button_permissions = len([m for m in menus_data if m['menu_type'] == 'button'])
  577. print(f" 📊 菜单结构统计:")
  578. print(f" 📁 主菜单(父目录): {main_menus} 个")
  579. print(f" 📄 功能菜单: {function_menus} 个")
  580. print(f" 🔘 按钮权限: {button_permissions} 个")
  581. def insert_roles(cursor):
  582. """插入角色数据"""
  583. print("👥 插入角色数据...")
  584. roles_data = [
  585. {
  586. 'id': str(uuid.uuid4()),
  587. 'name': 'super_admin',
  588. 'display_name': '超级管理员',
  589. 'description': '拥有系统所有权限的超级管理员',
  590. 'is_system': True
  591. },
  592. {
  593. 'id': str(uuid.uuid4()),
  594. 'name': 'admin',
  595. 'display_name': '管理员',
  596. 'description': '系统管理员,拥有大部分管理权限',
  597. 'is_system': True
  598. },
  599. {
  600. 'id': str(uuid.uuid4()),
  601. 'name': 'user_manager',
  602. 'display_name': '用户管理员',
  603. 'description': '负责用户和角色管理的管理员',
  604. 'is_system': True
  605. },
  606. {
  607. 'id': str(uuid.uuid4()),
  608. 'name': 'app_manager',
  609. 'display_name': '应用管理员',
  610. 'description': '负责应用管理的管理员',
  611. 'is_system': True
  612. },
  613. {
  614. 'id': str(uuid.uuid4()),
  615. 'name': 'user',
  616. 'display_name': '普通用户',
  617. 'description': '系统普通用户',
  618. 'is_system': True
  619. }
  620. ]
  621. role_ids = {}
  622. for role in roles_data:
  623. cursor.execute("""
  624. INSERT INTO roles (id, name, display_name, description, is_active, is_system, created_at, updated_at)
  625. VALUES (%s, %s, %s, %s, %s, %s, NOW(), NOW())
  626. """, (role['id'], role['name'], role['display_name'], role['description'], True, role['is_system']))
  627. role_ids[role['name']] = role['id']
  628. print(f" ✅ 插入了 {len(roles_data)} 个角色")
  629. return role_ids
  630. def insert_permissions(cursor):
  631. """插入权限数据"""
  632. print("🔐 插入权限数据...")
  633. permissions_data = [
  634. # 用户管理权限
  635. {'name': 'user.view', 'display_name': '查看用户', 'resource': 'user', 'action': 'view', 'description': '查看用户列表和详情'},
  636. {'name': 'user.create', 'display_name': '创建用户', 'resource': 'user', 'action': 'create', 'description': '创建新用户'},
  637. {'name': 'user.edit', 'display_name': '编辑用户', 'resource': 'user', 'action': 'edit', 'description': '编辑用户信息'},
  638. {'name': 'user.delete', 'display_name': '删除用户', 'resource': 'user', 'action': 'delete', 'description': '删除用户'},
  639. {'name': 'user.batch_delete', 'display_name': '批量删除用户', 'resource': 'user', 'action': 'batch_delete', 'description': '批量删除用户'},
  640. {'name': 'user.assign_role', 'display_name': '分配用户角色', 'resource': 'user', 'action': 'assign_role', 'description': '为用户分配角色'},
  641. {'name': 'user.reset_password', 'display_name': '重置用户密码', 'resource': 'user', 'action': 'reset_password', 'description': '重置用户密码'},
  642. # 角色管理权限
  643. {'name': 'role.view', 'display_name': '查看角色', 'resource': 'role', 'action': 'view', 'description': '查看角色列表和详情'},
  644. {'name': 'role.create', 'display_name': '创建角色', 'resource': 'role', 'action': 'create', 'description': '创建新角色'},
  645. {'name': 'role.edit', 'display_name': '编辑角色', 'resource': 'role', 'action': 'edit', 'description': '编辑角色信息'},
  646. {'name': 'role.delete', 'display_name': '删除角色', 'resource': 'role', 'action': 'delete', 'description': '删除角色'},
  647. {'name': 'role.assign_permission', 'display_name': '分配角色权限', 'resource': 'role', 'action': 'assign_permission', 'description': '为角色分配权限'},
  648. {'name': 'role.assign_menu', 'display_name': '分配角色菜单', 'resource': 'role', 'action': 'assign_menu', 'description': '为角色分配菜单'},
  649. # 菜单管理权限
  650. {'name': 'menu.view', 'display_name': '查看菜单', 'resource': 'menu', 'action': 'view', 'description': '查看菜单列表和详情'},
  651. {'name': 'menu.create', 'display_name': '创建菜单', 'resource': 'menu', 'action': 'create', 'description': '创建新菜单'},
  652. {'name': 'menu.edit', 'display_name': '编辑菜单', 'resource': 'menu', 'action': 'edit', 'description': '编辑菜单信息'},
  653. {'name': 'menu.delete', 'display_name': '删除菜单', 'resource': 'menu', 'action': 'delete', 'description': '删除菜单'},
  654. {'name': 'menu.sort', 'display_name': '排序菜单', 'resource': 'menu', 'action': 'sort', 'description': '调整菜单排序'},
  655. # 权限管理权限
  656. {'name': 'permission.view', 'display_name': '查看权限', 'resource': 'permission', 'action': 'view', 'description': '查看权限列表和详情'},
  657. {'name': 'permission.create', 'display_name': '创建权限', 'resource': 'permission', 'action': 'create', 'description': '创建新权限'},
  658. {'name': 'permission.edit', 'display_name': '编辑权限', 'resource': 'permission', 'action': 'edit', 'description': '编辑权限信息'},
  659. {'name': 'permission.delete', 'display_name': '删除权限', 'resource': 'permission', 'action': 'delete', 'description': '删除权限'},
  660. # 应用管理权限
  661. {'name': 'app.view', 'display_name': '查看应用', 'resource': 'app', 'action': 'view', 'description': '查看应用列表和详情'},
  662. {'name': 'app.create', 'display_name': '创建应用', 'resource': 'app', 'action': 'create', 'description': '创建OAuth2应用'},
  663. {'name': 'app.edit', 'display_name': '编辑应用', 'resource': 'app', 'action': 'edit', 'description': '编辑应用信息'},
  664. {'name': 'app.delete', 'display_name': '删除应用', 'resource': 'app', 'action': 'delete', 'description': '删除应用'},
  665. {'name': 'app.view_secret', 'display_name': '查看应用密钥', 'resource': 'app', 'action': 'view_secret', 'description': '查看应用密钥'},
  666. {'name': 'app.reset_secret', 'display_name': '重置应用密钥', 'resource': 'app', 'action': 'reset_secret', 'description': '重置应用密钥'},
  667. # 系统管理权限
  668. {'name': 'system.dashboard', 'display_name': '管理概览', 'resource': 'system', 'action': 'dashboard', 'description': '查看管理概览'},
  669. {'name': 'system.log_view', 'display_name': '查看系统日志', 'resource': 'system', 'action': 'log_view', 'description': '查看系统操作日志'},
  670. {'name': 'system.log_export', 'display_name': '导出系统日志', 'resource': 'system', 'action': 'log_export', 'description': '导出系统日志'},
  671. {'name': 'system.log_clear', 'display_name': '清理系统日志', 'resource': 'system', 'action': 'log_clear', 'description': '清理历史日志'},
  672. {'name': 'system.settings_view', 'display_name': '查看系统设置', 'resource': 'system', 'action': 'settings_view', 'description': '查看系统配置'},
  673. {'name': 'system.settings_edit', 'display_name': '修改系统设置', 'resource': 'system', 'action': 'settings_edit', 'description': '修改系统配置'},
  674. ]
  675. permission_ids = {}
  676. for perm in permissions_data:
  677. perm_id = str(uuid.uuid4())
  678. cursor.execute("""
  679. INSERT INTO permissions (id, name, display_name, resource, action, description, is_active, created_at, updated_at)
  680. VALUES (%s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
  681. """, (perm_id, perm['name'], perm['display_name'], perm['resource'], perm['action'], perm['description'], True))
  682. permission_ids[perm['name']] = perm_id
  683. print(f" ✅ 插入了 {len(permissions_data)} 个权限")
  684. return permission_ids
  685. def assign_role_permissions(cursor, role_ids, permission_ids):
  686. """分配角色权限"""
  687. print("🔗 分配角色权限...")
  688. # 超级管理员拥有所有权限
  689. super_admin_id = role_ids['super_admin']
  690. for perm_name, perm_id in permission_ids.items():
  691. cursor.execute("""
  692. INSERT INTO role_permissions (role_id, permission_id, created_at)
  693. VALUES (%s, %s, NOW())
  694. """, (super_admin_id, perm_id))
  695. # 管理员拥有大部分权限(除了系统设置修改)
  696. admin_id = role_ids['admin']
  697. admin_permissions = [perm for perm in permission_ids.keys() if not perm.startswith('system.settings_edit')]
  698. for perm_name in admin_permissions:
  699. cursor.execute("""
  700. INSERT INTO role_permissions (role_id, permission_id, created_at)
  701. VALUES (%s, %s, NOW())
  702. """, (admin_id, permission_ids[perm_name]))
  703. # 用户管理员只有用户和角色相关权限
  704. user_manager_id = role_ids['user_manager']
  705. user_permissions = [perm for perm in permission_ids.keys() if perm.startswith(('user.', 'role.', 'system.dashboard'))]
  706. for perm_name in user_permissions:
  707. cursor.execute("""
  708. INSERT INTO role_permissions (role_id, permission_id, created_at)
  709. VALUES (%s, %s, NOW())
  710. """, (user_manager_id, permission_ids[perm_name]))
  711. # 应用管理员只有应用相关权限
  712. app_manager_id = role_ids['app_manager']
  713. app_permissions = [perm for perm in permission_ids.keys() if perm.startswith(('app.', 'system.dashboard'))]
  714. for perm_name in app_permissions:
  715. cursor.execute("""
  716. INSERT INTO role_permissions (role_id, permission_id, created_at)
  717. VALUES (%s, %s, NOW())
  718. """, (app_manager_id, permission_ids[perm_name]))
  719. print(" ✅ 角色权限分配完成")
  720. def assign_role_menus(cursor, role_ids):
  721. """分配角色菜单"""
  722. print("🔗 分配角色菜单...")
  723. # 获取所有菜单ID
  724. cursor.execute("SELECT id, parent_id, menu_type FROM menus")
  725. all_menus = cursor.fetchall()
  726. menu_ids = [menu[0] for menu in all_menus]
  727. # 超级管理员和管理员拥有所有菜单
  728. for role_name in ['super_admin', 'admin']:
  729. role_id = role_ids[role_name]
  730. for menu_id in menu_ids:
  731. cursor.execute("""
  732. INSERT INTO role_menus (role_id, menu_id, created_at)
  733. VALUES (%s, %s, NOW())
  734. """, (role_id, menu_id))
  735. # 用户管理员只有基础菜单和用户管理相关菜单
  736. user_manager_id = role_ids['user_manager']
  737. user_manager_menus = [
  738. 'dashboard-main', 'profile-main', 'admin-main', 'admin-dashboard',
  739. 'user-management', 'role-management'
  740. ]
  741. # 添加用户管理和角色管理相关的按钮权限
  742. cursor.execute("SELECT id FROM menus WHERE parent_id IN ('user-management', 'role-management')")
  743. user_buttons = cursor.fetchall()
  744. user_manager_menus.extend([btn[0] for btn in user_buttons])
  745. for menu_id in user_manager_menus:
  746. cursor.execute("""
  747. INSERT INTO role_menus (role_id, menu_id, created_at)
  748. VALUES (%s, %s, NOW())
  749. """, (user_manager_id, menu_id))
  750. # 应用管理员只有基础菜单和应用管理相关菜单
  751. app_manager_id = role_ids['app_manager']
  752. app_manager_menus = [
  753. 'dashboard-main', 'profile-main', 'admin-main', 'admin-dashboard',
  754. 'app-management'
  755. ]
  756. # 添加应用管理相关的按钮权限
  757. cursor.execute("SELECT id FROM menus WHERE parent_id = 'app-management'")
  758. app_buttons = cursor.fetchall()
  759. app_manager_menus.extend([btn[0] for btn in app_buttons])
  760. for menu_id in app_manager_menus:
  761. cursor.execute("""
  762. INSERT INTO role_menus (role_id, menu_id, created_at)
  763. VALUES (%s, %s, NOW())
  764. """, (app_manager_id, menu_id))
  765. # 普通用户只有基础菜单
  766. user_id = role_ids['user']
  767. user_menus = ['dashboard-main', 'profile-main']
  768. for menu_id in user_menus:
  769. cursor.execute("""
  770. INSERT INTO role_menus (role_id, menu_id, created_at)
  771. VALUES (%s, %s, NOW())
  772. """, (user_id, menu_id))
  773. print(" ✅ 角色菜单分配完成")
  774. def assign_user_roles(cursor, role_ids):
  775. """为现有用户分配角色"""
  776. print("👤 为用户分配角色...")
  777. # 获取admin用户
  778. cursor.execute("SELECT id FROM users WHERE username = 'admin'")
  779. admin_user = cursor.fetchone()
  780. if admin_user:
  781. admin_user_id = admin_user[0]
  782. # 为admin用户分配超级管理员角色
  783. cursor.execute("""
  784. INSERT INTO user_roles (user_id, role_id, is_active, created_at)
  785. VALUES (%s, %s, %s, NOW())
  786. """, (admin_user_id, role_ids['super_admin'], True))
  787. print(f" ✅ 为admin用户分配了超级管理员角色")
  788. # 获取其他用户并分配普通用户角色
  789. cursor.execute("SELECT id, username FROM users WHERE username != 'admin'")
  790. other_users = cursor.fetchall()
  791. for user in other_users:
  792. user_id, username = user
  793. cursor.execute("""
  794. INSERT INTO user_roles (user_id, role_id, is_active, created_at)
  795. VALUES (%s, %s, %s, NOW())
  796. """, (user_id, role_ids['user'], True))
  797. print(f" ✅ 为用户 {username} 分配了普通用户角色")
  798. def print_menu_structure(cursor):
  799. """打印菜单结构验证"""
  800. print("\n🌳 菜单结构验证:")
  801. print("=" * 60)
  802. # 获取所有菜单
  803. cursor.execute("""
  804. SELECT id, parent_id, title, menu_type, sort_order
  805. FROM menus
  806. ORDER BY
  807. CASE WHEN parent_id IS NULL THEN 0 ELSE 1 END,
  808. sort_order,
  809. CASE WHEN menu_type = 'menu' THEN 0 ELSE 1 END
  810. """)
  811. all_menus = cursor.fetchall()
  812. # 构建菜单树
  813. menu_dict = {}
  814. for menu in all_menus:
  815. menu_id, parent_id, title, menu_type, sort_order = menu
  816. menu_dict[menu_id] = {
  817. 'id': menu_id,
  818. 'parent_id': parent_id,
  819. 'title': title,
  820. 'menu_type': menu_type,
  821. 'sort_order': sort_order,
  822. 'children': []
  823. }
  824. # 建立父子关系
  825. root_menus = []
  826. for menu_id, menu_data in menu_dict.items():
  827. if menu_data['parent_id']:
  828. if menu_data['parent_id'] in menu_dict:
  829. menu_dict[menu_data['parent_id']]['children'].append(menu_data)
  830. else:
  831. root_menus.append(menu_data)
  832. # 打印树形结构
  833. def print_menu_tree(menus, level=0):
  834. for menu in sorted(menus, key=lambda x: x['sort_order']):
  835. indent = " " * level
  836. if menu['menu_type'] == 'menu' and level == 0:
  837. icon = "📁"
  838. elif menu['menu_type'] == 'menu':
  839. icon = "📄"
  840. else:
  841. icon = "🔘"
  842. print(f"{indent}{icon} {menu['title']} ({menu['menu_type']})")
  843. if menu['children']:
  844. # 先显示菜单类型的子项,再显示按钮类型的子项
  845. menu_children = [c for c in menu['children'] if c['menu_type'] == 'menu']
  846. button_children = [c for c in menu['children'] if c['menu_type'] == 'button']
  847. print_menu_tree(menu_children, level + 1)
  848. print_menu_tree(button_children, level + 1)
  849. print_menu_tree(root_menus)
  850. def reinit_rbac_data():
  851. """重新初始化RBAC数据 - 修复层级关系"""
  852. print("🚀 开始重新初始化RBAC数据(修复层级关系)")
  853. print("=" * 60)
  854. conn = get_db_connection()
  855. if not conn:
  856. print("❌ 数据库连接失败")
  857. return False
  858. cursor = conn.cursor()
  859. try:
  860. # 1. 清理现有数据
  861. clear_rbac_data(cursor)
  862. # 2. 插入菜单数据(修复层级关系)
  863. insert_menus(cursor)
  864. # 3. 插入角色数据
  865. role_ids = insert_roles(cursor)
  866. # 4. 插入权限数据
  867. permission_ids = insert_permissions(cursor)
  868. # 5. 分配角色权限
  869. assign_role_permissions(cursor, role_ids, permission_ids)
  870. # 6. 分配角色菜单
  871. assign_role_menus(cursor, role_ids)
  872. # 7. 为用户分配角色
  873. assign_user_roles(cursor, role_ids)
  874. # 8. 打印菜单结构验证
  875. print_menu_structure(cursor)
  876. conn.commit()
  877. print("\n" + "=" * 60)
  878. print("🎉 RBAC数据重新初始化完成!(层级关系已修复)")
  879. print("=" * 60)
  880. print("📊 数据统计:")
  881. # 统计数据
  882. cursor.execute("SELECT COUNT(*) FROM menus")
  883. menu_count = cursor.fetchone()[0]
  884. cursor.execute("SELECT COUNT(*) FROM menus WHERE menu_type = 'menu' AND parent_id IS NULL")
  885. main_menu_count = cursor.fetchone()[0]
  886. cursor.execute("SELECT COUNT(*) FROM menus WHERE menu_type = 'menu' AND parent_id IS NOT NULL")
  887. function_menu_count = cursor.fetchone()[0]
  888. cursor.execute("SELECT COUNT(*) FROM menus WHERE menu_type = 'button'")
  889. button_count = cursor.fetchone()[0]
  890. cursor.execute("SELECT COUNT(*) FROM roles")
  891. role_count = cursor.fetchone()[0]
  892. cursor.execute("SELECT COUNT(*) FROM permissions")
  893. permission_count = cursor.fetchone()[0]
  894. print(f" 📁 主菜单(父目录): {main_menu_count} 个")
  895. print(f" 📄 功能菜单: {function_menu_count} 个")
  896. print(f" 🔘 按钮权限: {button_count} 个")
  897. print(f" 📋 菜单总数: {menu_count} 个")
  898. print(f" 👥 角色数量: {role_count} 个")
  899. print(f" 🔐 权限数量: {permission_count} 个")
  900. print("=" * 60)
  901. return True
  902. except Exception as e:
  903. print(f"❌ 初始化失败: {e}")
  904. conn.rollback()
  905. return False
  906. finally:
  907. cursor.close()
  908. conn.close()
  909. def main():
  910. """主函数"""
  911. success = reinit_rbac_data()
  912. if success:
  913. print("\n🎯 重新初始化成功!菜单层级关系已修复。")
  914. print("💡 建议重启前端服务以刷新菜单缓存。")
  915. print("\n🌐 访问地址:")
  916. print(" 前端: http://localhost:3000")
  917. print(" 菜单管理: http://localhost:3000/admin/menus")
  918. print("\n🔑 登录信息:")
  919. print(" 用户名: admin")
  920. print(" 密码: Admin123456")
  921. else:
  922. print("\n❌ 重新初始化失败!")
  923. if __name__ == "__main__":
  924. main()