seed.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. """幂等种子数据:角色、菜单、管理员、热线/二维码配置"""
  2. import uuid
  3. from typing import Dict, List
  4. import bcrypt
  5. from sqlalchemy.orm import Session
  6. from app.core.config import get_settings
  7. from app.models.business import HotlineConfig, QrcodeConfig
  8. from app.models.system import SysMenu, SysRole, SysRoleMenu, SysUser
  9. def _uuid() -> str:
  10. return str(uuid.uuid4())
  11. def _hash_password(plain: str) -> str:
  12. return bcrypt.hashpw(plain.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")
  13. # 菜单定义:(menu_code, menu_name, path, menu_type, sort, parent_code|None)
  14. MENU_DEFS = [
  15. ("dashboard", "工作台", "/dashboard", "C", 10, None),
  16. ("feedback", "在线反馈", "/feedback", "C", 20, None),
  17. ("suggestion", "建言献策", "/suggestion", "C", 30, None),
  18. ("hotline", "监督热线", "/hotline", "C", 40, None),
  19. ("qrcode", "二维码配置", "/qrcode", "C", 50, None),
  20. ("user", "用户管理", "/user", "C", 60, None),
  21. ("role", "角色授权", "/role", "C", 70, None),
  22. ("audit", "操作审计", "/audit", "C", 80, None),
  23. ("feedback:handle", "反馈办理", "", "F", 21, "feedback"),
  24. ("suggestion:handle", "建言办理", "", "F", 31, "suggestion"),
  25. ("hotline:write", "热线编辑", "", "F", 41, "hotline"),
  26. ("qrcode:write", "二维码编辑", "", "F", 51, "qrcode"),
  27. ("user:manage", "用户管理操作", "", "F", 61, "user"),
  28. ("role:grant", "角色授权操作", "", "F", 71, "role"),
  29. ]
  30. ROLE_DEFS = [
  31. ("admin", "系统管理员", "全部菜单与按钮权限"),
  32. ("handler", "办理员", "工作台、反馈、建言及办理权限"),
  33. ("viewer", "查阅员", "工作台、反馈、建言查阅(无办理)"),
  34. ]
  35. # role_code -> menu_code 列表;admin 用特殊标记表示全部
  36. ROLE_MENU_CODES: Dict[str, List[str] | str] = {
  37. "admin": "*",
  38. "handler": [
  39. "dashboard",
  40. "feedback",
  41. "suggestion",
  42. "feedback:handle",
  43. "suggestion:handle",
  44. ],
  45. "viewer": ["dashboard", "feedback", "suggestion"],
  46. }
  47. def seed_if_empty(db: Session) -> None:
  48. """若库中尚无角色则写入种子;已有则直接返回(幂等)。"""
  49. if db.query(SysRole).count() > 0:
  50. return
  51. settings = get_settings()
  52. now_by = "system"
  53. # --- roles ---
  54. role_by_code: Dict[str, SysRole] = {}
  55. for code, name, remark in ROLE_DEFS:
  56. role = SysRole(
  57. id=_uuid(),
  58. role_code=code,
  59. role_name=name,
  60. remark=remark,
  61. del_flag="0",
  62. create_by=now_by,
  63. update_by=now_by,
  64. )
  65. db.add(role)
  66. role_by_code[code] = role
  67. db.flush()
  68. # --- menus ---
  69. menu_by_code: Dict[str, SysMenu] = {}
  70. for code, name, path, mtype, sort, parent_code in MENU_DEFS:
  71. parent_id = "0"
  72. if parent_code:
  73. parent_id = menu_by_code[parent_code].id
  74. menu = SysMenu(
  75. id=_uuid(),
  76. parent_id=parent_id,
  77. menu_code=code,
  78. menu_name=name,
  79. path=path,
  80. menu_type=mtype,
  81. sort=sort,
  82. visible="1",
  83. del_flag="0",
  84. create_by=now_by,
  85. update_by=now_by,
  86. )
  87. db.add(menu)
  88. menu_by_code[code] = menu
  89. db.flush()
  90. # --- role_menu ---
  91. for role_code, codes in ROLE_MENU_CODES.items():
  92. role = role_by_code[role_code]
  93. if codes == "*":
  94. target_codes = list(menu_by_code.keys())
  95. else:
  96. target_codes = codes # type: ignore[assignment]
  97. for menu_code in target_codes:
  98. db.add(
  99. SysRoleMenu(
  100. id=_uuid(),
  101. role_id=role.id,
  102. menu_id=menu_by_code[menu_code].id,
  103. )
  104. )
  105. # --- admin user ---
  106. admin_role = role_by_code["admin"]
  107. db.add(
  108. SysUser(
  109. id=_uuid(),
  110. username=settings.INIT_ADMIN_USERNAME,
  111. password_hash=_hash_password(settings.INIT_ADMIN_PASSWORD),
  112. display_name="管理员",
  113. role_id=admin_role.id,
  114. status="0",
  115. del_flag="0",
  116. create_by=now_by,
  117. update_by=now_by,
  118. )
  119. )
  120. # --- hotline / qrcode defaults ---
  121. if db.query(HotlineConfig).count() == 0:
  122. db.add(
  123. HotlineConfig(
  124. id=_uuid(),
  125. phone="0551-00000000",
  126. email="jj@example.com",
  127. address="安徽建工集团医院纪检室",
  128. work_time="工作日 9:00-17:00",
  129. del_flag="0",
  130. create_by=now_by,
  131. update_by=now_by,
  132. )
  133. )
  134. if db.query(QrcodeConfig).count() == 0:
  135. db.add(
  136. QrcodeConfig(
  137. id=_uuid(),
  138. land_url="https://example.com/h5/",
  139. title="安建医院纪检扫码反馈",
  140. image_url="",
  141. del_flag="0",
  142. create_by=now_by,
  143. update_by=now_by,
  144. )
  145. )
  146. db.commit()