| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- # -*- coding: utf-8 -*-
- """幂等插入「业务事实字典」菜单到 dev 库。
- 首次启动时 SysMenuSeedData 不会自动补新菜单(IgnoreUpdateSeed),
- AidopMenuLinkSync 仅补租户/角色链接而不会建菜单本身。
- 故 dev 环境需一次性手工插。重跑无副作用。
- """
- from __future__ import annotations
- import sys
- from datetime import datetime
- import pymysql
- sys.stdout.reconfigure(encoding='utf-8')
- CONN = dict(
- host='123.60.180.165', port=3306,
- user='aidopremote', password='1234567890aiDOP#',
- database='aidopdev', charset='utf8mb4', autocommit=False,
- )
- MENU_ID = 1320990000313
- PARENT_ID = 1320990000300 # Ai-DOP 智慧运营目录(从 kpi-master 菜单推得,同父级)
- ROUTE_PATH = '/aidop/smart-ops/business-fact'
- ROUTE_NAME = 'aidopSmartOpsBusinessFact'
- COMPONENT = '/aidop/kanban/businessFact'
- TITLE = '业务事实字典'
- def main() -> None:
- conn = pymysql.connect(**CONN)
- cur = conn.cursor(pymysql.cursors.DictCursor)
- try:
- # 先找出 kpi-master 菜单的 Pid 作为父级
- cur.execute("SELECT Pid, OrderNo FROM SysMenu WHERE Id=%s", (1320990000312,))
- parent_row = cur.fetchone()
- if not parent_row:
- raise RuntimeError("未找到 kpi-master 菜单(1320990000312),无法推断父级目录")
- pid = parent_row['Pid']
- order_no = int(parent_row['OrderNo']) + 1
- print(f"父级目录 Pid={pid}, 排序={order_no}")
- # 探测 SysMenu 列集
- cur.execute("SHOW COLUMNS FROM SysMenu")
- cols = {r['Field'] for r in cur.fetchall()}
- print(f"SysMenu 列: {sorted(cols)[:12]}... (共 {len(cols)})")
- # 1) 菜单:从 kpi-master 克隆后覆盖关键字段
- cur.execute("SELECT COUNT(*) AS c FROM SysMenu WHERE Id=%s", (MENU_ID,))
- if cur.fetchone()['c'] > 0:
- print(f"[SKIP] SysMenu.Id={MENU_ID} 已存在")
- else:
- cur.execute("SELECT * FROM SysMenu WHERE Id=%s", (1320990000312,))
- tmpl = cur.fetchone()
- if not tmpl:
- raise RuntimeError("模板菜单 1320990000312 不存在")
- tmpl['Id'] = MENU_ID
- tmpl['Title'] = TITLE
- tmpl['Path'] = ROUTE_PATH
- tmpl['Name'] = ROUTE_NAME
- tmpl['Component'] = COMPONENT
- tmpl['Icon'] = 'ele-Collection'
- tmpl['OrderNo'] = order_no
- tmpl['Remark'] = TITLE
- tmpl['CreateTime'] = datetime.now()
- if 'UpdateTime' in tmpl:
- tmpl['UpdateTime'] = None
- ks = ','.join(f'`{k}`' for k in tmpl)
- ph = ','.join(['%s'] * len(tmpl))
- cur.execute(f"INSERT INTO SysMenu ({ks}) VALUES ({ph})", tuple(tmpl.values()))
- print(f"[OK] 新增 SysMenu.Id={MENU_ID}(按 kpi-master 菜单克隆)")
- # 2) 租户菜单 - 给所有租户都挂上
- cur.execute("SELECT Id FROM SysTenant")
- tenants = [r['Id'] for r in cur.fetchall()]
- cur.execute("SHOW COLUMNS FROM SysTenantMenu")
- tm_cols = {r['Field'] for r in cur.fetchall()}
- tm_added = 0
- for tid in tenants:
- cur.execute(
- "SELECT COUNT(*) AS c FROM SysTenantMenu WHERE TenantId=%s AND MenuId=%s",
- (tid, MENU_ID),
- )
- if cur.fetchone()['c'] > 0:
- continue
- cur.execute("SELECT IFNULL(MAX(Id),0)+1 AS nx FROM SysTenantMenu")
- link_id = cur.fetchone()['nx']
- tm_row = {'Id': link_id, 'TenantId': tid, 'MenuId': MENU_ID}
- tm_row = {k: v for k, v in tm_row.items() if k in tm_cols}
- ks = ','.join(f'`{k}`' for k in tm_row)
- ph = ','.join(['%s'] * len(tm_row))
- cur.execute(f"INSERT INTO SysTenantMenu ({ks}) VALUES ({ph})", tuple(tm_row.values()))
- tm_added += 1
- print(f"[OK] 补 SysTenantMenu x {tm_added} 条(共 {len(tenants)} 租户)")
- # 3) 角色菜单 - 给系统管理员 + 已授权 kpi-master 的角色
- cur.execute("SELECT DISTINCT RoleId FROM SysRoleMenu WHERE MenuId=%s", (1320990000312,))
- roles = {r['RoleId'] for r in cur.fetchall()}
- roles.add(1300000000101) # SysAdmin
- cur.execute("SHOW COLUMNS FROM SysRoleMenu")
- rm_cols = {r['Field'] for r in cur.fetchall()}
- inserted = 0
- for rid in roles:
- cur.execute(
- "SELECT COUNT(*) AS c FROM SysRoleMenu WHERE RoleId=%s AND MenuId=%s",
- (rid, MENU_ID),
- )
- if cur.fetchone()['c'] > 0:
- continue
- # 避免 Id 撞号:用 MAX+1 策略
- cur.execute("SELECT IFNULL(MAX(Id),0)+1 AS nx FROM SysRoleMenu")
- nx = cur.fetchone()['nx']
- rm_row = {'Id': nx, 'RoleId': rid, 'MenuId': MENU_ID}
- rm_row = {k: v for k, v in rm_row.items() if k in rm_cols}
- ks = ','.join(f'`{k}`' for k in rm_row)
- ph = ','.join(['%s'] * len(rm_row))
- cur.execute(f"INSERT INTO SysRoleMenu ({ks}) VALUES ({ph})", tuple(rm_row.values()))
- inserted += 1
- print(f"[OK] 补 SysRoleMenu x {inserted} 角色(共候选 {len(roles)})")
- conn.commit()
- print("\n[DONE] 菜单入库完成。请在前端 ctrl-shift-R 刷新或重新登录以加载。")
- except Exception as ex:
- conn.rollback()
- print(f"回滚:{ex}")
- raise
- finally:
- cur.close()
- conn.close()
- if __name__ == "__main__":
- main()
|