20261027_qqflow_create_scrm_service_account.sql 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. -- =====================================================================
  2. -- 为 wl-scrm 后端创建 qqflow 专用服务账号
  3. --
  4. -- 执行库:qqflow 审批引擎库(qqflowengine)
  5. -- 用途:wl-scrm 后端内部调用 qqflow(发起/撤回审批、同步进度、
  6. -- 审批人配置页「同步选中」创建审批人账号/绑定企微)
  7. --
  8. -- 为什么需要 super_admin:
  9. -- · POST /system/user(创建审批人账号)要求 super_admin 或 dept_manager;
  10. -- · PUT /system/user/{id}/wecom(给已有账号补绑企微)仅允许 super_admin;
  11. -- · 只授 flow_manager 时,「同步选中」会报「权限不足,无法访问」。
  12. --
  13. -- 账号约定:
  14. -- username = scrm_service
  15. -- password = 自定义强密码(与 wl-scrm 外置配置 qqflow.service.password 一致)
  16. --
  17. -- qqflow 密码使用 BCrypt 存储,先生成哈希再替换下面的占位符:
  18. -- htpasswd -bnBC 10 "" '你的密码' | tr -d ':\n'
  19. --
  20. -- 注意:
  21. -- · 本脚本创建的是高权限服务账号,密码只放 wl-scrm 服务端外置配置,
  22. -- 不要提交仓库、不要发到群里;
  23. -- · 脚本幂等:重复执行会重置该账号密码并补齐 super_admin 角色;
  24. -- · 如果 username 已被无关账号占用,第 0 步会先查出来,切勿直接覆盖。
  25. -- =====================================================================
  26. -- 执行前确认当前库:必须是 qqflowengine。
  27. -- 如果在 wlscrmcenter 或测试库执行,生产 qqflow 里不会出现这个账号。
  28. SELECT DATABASE() AS current_database;
  29. SET @service_username = 'scrm_service';
  30. -- 替换为 htpasswd 生成的 BCrypt 哈希(60 位,$2a$/$2b$/$2y$ 开头)
  31. SET @service_password_hash = '<替换为 BCrypt 哈希>';
  32. SET @super_admin_role_code = 'super_admin';
  33. -- 0) 执行前检查:用户名是否已被占用
  34. -- 有结果时先确认是不是本次要重置的账号;如果是别人在用的账号,请换一个 username。
  35. SELECT id, username, real_name, employee_type, status
  36. FROM sys_user
  37. WHERE username COLLATE utf8mb4_general_ci = @service_username COLLATE utf8mb4_general_ci;
  38. -- 1) 校验 super_admin 角色存在且启用
  39. -- 生产当前应有 id=1 的 super_admin;若没有,请先确认 qqflow 角色模型,不要继续。
  40. SELECT id, role_code, role_name, role_scope, status
  41. FROM sys_role
  42. WHERE role_code COLLATE utf8mb4_general_ci = @super_admin_role_code COLLATE utf8mb4_general_ci;
  43. -- 2.1) 更新已有账号(仅限本脚本管理的账号)
  44. -- 只有 real_name 或 employee_type 对得上才更新,避免误改同名但无关的账号
  45. UPDATE sys_user
  46. SET password = @service_password_hash,
  47. real_name = 'SCRM 服务账号',
  48. employee_type = @super_admin_role_code,
  49. status = 0,
  50. wecom_user_id = NULL,
  51. wecom_remind_enabled = 0,
  52. update_time = NOW()
  53. WHERE username COLLATE utf8mb4_general_ci = @service_username COLLATE utf8mb4_general_ci
  54. AND (real_name = 'SCRM 服务账号' OR employee_type = @super_admin_role_code);
  55. -- 2.2) 不存在则创建
  56. -- 若 username 已被无关账号占用,这里不会插入;第 0 步/第 4 步会显示
  57. -- 该账号的原状态,此时不要继续,换一个 username 后重跑。
  58. INSERT INTO sys_user
  59. (username, password, real_name, dept_id, employee_type, status, wecom_remind_enabled)
  60. SELECT @service_username, @service_password_hash, 'SCRM 服务账号', NULL,
  61. @super_admin_role_code, 0, 0
  62. FROM DUAL
  63. WHERE NOT EXISTS (
  64. SELECT 1 FROM sys_user
  65. WHERE username COLLATE utf8mb4_general_ci = @service_username COLLATE utf8mb4_general_ci
  66. );
  67. -- 3) 绑定 super_admin 角色(接口鉴权使用)
  68. -- 只取「本脚本管理的账号」:如果 username 被无关账号占用,这里取不到 id,
  69. -- 不会给无关账号误绑 super_admin;校验结果会显示该账号仍是原 employee_type。
  70. SET @service_user_id = (
  71. SELECT id FROM sys_user
  72. WHERE username COLLATE utf8mb4_general_ci = @service_username COLLATE utf8mb4_general_ci
  73. AND (real_name = 'SCRM 服务账号' OR employee_type = @super_admin_role_code)
  74. LIMIT 1
  75. );
  76. SET @super_admin_role_id = (
  77. SELECT id FROM sys_role
  78. WHERE role_code COLLATE utf8mb4_general_ci = @super_admin_role_code COLLATE utf8mb4_general_ci
  79. LIMIT 1
  80. );
  81. INSERT INTO sys_user_role (user_id, role_id)
  82. SELECT @service_user_id, @super_admin_role_id
  83. WHERE @service_user_id IS NOT NULL
  84. AND @super_admin_role_id IS NOT NULL
  85. AND NOT EXISTS (
  86. SELECT 1 FROM sys_user_role
  87. WHERE user_id = @service_user_id
  88. AND role_id = @super_admin_role_id
  89. );
  90. -- 4) 校验:应返回 1 行:
  91. -- employee_type=super_admin、role_code=super_admin、
  92. -- pwd_len=60、pwd_prefix=$2a$/$2b$/$2y$(不是 60 位说明哈希没替换/复制错)
  93. SELECT u.id AS user_id,
  94. u.username,
  95. u.employee_type,
  96. u.status AS user_status,
  97. CHAR_LENGTH(u.password) AS pwd_len,
  98. LEFT(u.password, 4) AS pwd_prefix,
  99. r.id AS role_id,
  100. r.role_code,
  101. r.role_name,
  102. r.status AS role_status
  103. FROM sys_user u
  104. LEFT JOIN sys_user_role ur ON ur.user_id = u.id
  105. LEFT JOIN sys_role r ON r.id = ur.role_id
  106. WHERE u.username COLLATE utf8mb4_general_ci = @service_username COLLATE utf8mb4_general_ci;
  107. -- =====================================================================
  108. -- 执行后还需要在 wl-scrm 生产外置配置(config/application-prod.properties
  109. -- 或环境变量)中配置,并重启 wl-scrm:
  110. --
  111. -- qqflow.service.username=scrm_service
  112. -- qqflow.service.password=<与上面的明文密码一致>
  113. --
  114. -- 如果之前用过其它服务账号,清掉 wl-scrm Redis 中的旧 token(JWT 角色是
  115. -- 登录时写入的,缓存 23 小时;改密码/改角色后必须清):
  116. --
  117. -- redis-cli DEL "TOKEN:QQFLOW:SERVICE:default:scrm_service"
  118. -- redis-cli DEL "TOKEN:QQFLOW:SERVICE:default:<旧账号>"
  119. -- =====================================================================