fix(load_path): review修复——单事件循环直连注册(去掉600+次subprocess),get_accdetail恢复page/sort

This commit is contained in:
yumoqing 2026-08-27 18:17:45 +08:00
parent 89592b9585
commit 411d1017cf
2 changed files with 84 additions and 88 deletions

View File

@ -48,7 +48,9 @@ where b.subjectid = c.id
"""
ns = {
'accountid': accountid,
'orgid': userorgid
'orgid': userorgid,
'page': page,
'sort': 'acc_date desc'
}
ret = await sor.sqlExe(sql, ns)
return ret

View File

@ -22,11 +22,10 @@ accounting 模块 RBAC 权限管理脚本角色分层版2026-08-27 重构
orgtypeid+name role 表解析出真实 role.id 后注册同名多条全部注册
使用方法:
cd <app root> py3/ set_role_perm.py 的目录 /d/pipeline/pipeline-app
cd <app root> py3/ 的目录 /d/pipeline/pipeline-app
./py3/bin/python pkgs/accounting/scripts/load_path.py [--add-only]
"""
import subprocess
import os
import sys
import asyncio
@ -51,9 +50,6 @@ if not APP_ROOT:
print("ERROR: Cannot find app root directory")
sys.exit(1)
PYTHON = os.path.join(APP_ROOT, "py3", "bin", "python")
SET_PERM_SCRIPT = os.path.join(APP_ROOT, "set_role_perm.py")
MOD = "accounting"
# ============================================================
@ -252,102 +248,100 @@ async def _find_rbac_db(db):
return None
async def resolve_role_ids(labels):
async def resolve_role_ids(sor, labels):
"""标签 'orgtypeid.name' → 真实 role.id 列表(同名多条全返回)。"""
db = _get_db()
dbname = await _find_rbac_db(db)
mapping = {}
if not dbname:
print('WARN: role 表不可达,按字面量注册(可能无效)')
return {lb: [lb] for lb in labels}
async with db.sqlorContext(dbname) as sor:
for label in labels:
if label in ('any', 'logined', 'anonymous'):
mapping[label] = [label]
continue
orgtypeid, _, name = label.partition('.')
recs = await sor.sqlExe(
'select id from role where orgtypeid=${o}$ and name=${n}$',
{'o': orgtypeid, 'n': name})
ids = [_row_get(r, 'id') for r in recs]
ids = [i for i in ids if i]
if not ids:
print(f'WARN: 角色不存在 {label},跳过')
mapping[label] = ids
await sor.sqlExe('COMMIT', {})
for label in labels:
if label in ('any', 'logined', 'anonymous'):
mapping[label] = [label]
continue
orgtypeid, _, name = label.partition('.')
recs = await sor.sqlExe(
'select id from role where orgtypeid=${o}$ and name=${n}$',
{'o': orgtypeid, 'n': name})
ids = [_row_get(r, 'id') for r in recs]
ids = [i for i in ids if i]
if not ids:
print(f'WARN: 角色不存在 {label},跳过')
mapping[label] = ids
return mapping
async def clean_accounting_roleperms():
"""删除 /accounting/ 下全部旧授权(保留 permission 行本身)。"""
db = _get_db()
dbname = await _find_rbac_db(db)
if not dbname:
print('ERROR: 无法定位 RBAC 库,清理中止')
return -1
total = 0
async with db.sqlorContext(dbname) as sor:
perms = await sor.sqlExe(
'select id from permission where path like ${p}$ or path=${p2}$',
{'p': f'/{MOD}/%', 'p2': f'/{MOD}'})
for p in perms:
pid = _row_get(p, 'id')
r = await sor.sqlExe('delete from rolepermission where permid=${pid}$', {'pid': pid})
total += 1
await sor.sqlExe('COMMIT', {})
print(f'清理完成:/accounting/ 下 {len(perms)} 个 permission 的旧授权已删除')
return total
# ============================================================
# 注册
# ============================================================
def run_set_perm(role_id, path):
cmd = [PYTHON, SET_PERM_SCRIPT, role_id, path]
result = subprocess.run(cmd, capture_output=True, text=True, cwd=APP_ROOT)
if result.returncode != 0:
print(f" FAIL {role_id} {path}: {(result.stderr or result.stdout).strip()[:200]}")
async def set_role_perm(sor, role_id, path):
"""注册单条权限幂等permission 缺则建rolepermission 缺则建。"""
from appPublic.uniqueID import getID
recs = await sor.R('permission', {'path': path})
if not recs:
permid = getID()
await sor.C('permission', {'id': permid, 'path': path})
else:
permid = _row_get(recs[0], 'id')
rp = await sor.R('rolepermission', {'roleid': role_id, 'permid': permid})
if rp:
return False
await sor.C('rolepermission', {'id': getID(), 'roleid': role_id, 'permid': permid})
return True
def register_role_paths(role_label, role_ids, paths):
if not role_ids:
return 0
count = 0
for rid in role_ids:
for p in paths:
if run_set_perm(rid, p):
count += 1
print(f" {role_label} ({','.join(role_ids)}): {count}/{len(paths) * len(role_ids)} entries registered")
return count
async def run_all(add_only):
db = _get_db()
dbname = await _find_rbac_db(db)
if not dbname:
print('ERROR: 无法定位 RBAC 库role 表不可达),中止')
return 1
print(f'RBAC 库: {dbname}')
total = 0
async with db.sqlorContext(dbname) as sor:
if not add_only:
print('=== 清理旧授权 ===')
perms = await sor.sqlExe(
'select id from permission where path like ${p}$ or path=${p2}$',
{'p': f'/{MOD}/%', 'p2': f'/{MOD}'})
for p in perms:
await sor.sqlExe('delete from rolepermission where permid=${pid}$',
{'pid': _row_get(p, 'id')})
await sor.sqlExe('COMMIT', {})
print(f'清理完成:/accounting/ 下 {len(perms)} 个 permission 的旧授权已删除')
print('=== 解析角色 ===')
all_labels = sorted(set(FIN_ROLES + PROXY_ROLES))
role_map = await resolve_role_ids(sor, all_labels)
for lb in all_labels:
print(f' {lb} -> {role_map.get(lb) or "(不存在)"}')
print('=== 注册新矩阵 ===')
async def register_group(group_label, role_ids, paths):
nonlocal total
if not role_ids:
return
added = 0
for rid in role_ids:
for p in paths:
if await set_role_perm(sor, rid, p):
added += 1
await sor.sqlExe('COMMIT', {})
total += added
print(f' {group_label} ({",".join(role_ids)}): +{added}'
f'(目标 {len(paths) * len(role_ids)} 条,其余为已存在)')
await register_group('any', ['any'], PATHS_ANY)
await register_group('logined', ['logined'], PATHS_LOGINED)
for label in FIN_ROLES:
await register_group(label, role_map.get(label, []), PATHS_FIN)
for label in PROXY_ROLES:
await register_group(label, role_map.get(label, []), PATHS_PROXY)
print(f'\nDone. 本次新增 {total} 条授权。')
print('NOTE: 重启应用(或调用 /rbac/refresh_userperm.dspy后权限生效。')
return 0
def main():
add_only = '--add-only' in sys.argv
print(f"App root: {APP_ROOT}")
if not add_only:
print('=== 清理旧授权 ===')
asyncio.run(clean_accounting_roleperms())
print('=== 解析角色 ===')
all_labels = sorted(set(FIN_ROLES + PROXY_ROLES))
role_map = asyncio.run(resolve_role_ids(all_labels))
for lb in all_labels:
print(f' {lb} -> {role_map.get(lb) or "(不存在)"}')
print('=== 注册新矩阵 ===')
total = 0
total += register_role_paths('any', ['any'], PATHS_ANY)
total += register_role_paths('logined', ['logined'], PATHS_LOGINED)
for label in FIN_ROLES:
total += register_role_paths(label, role_map.get(label, []), PATHS_FIN)
for label in PROXY_ROLES:
total += register_role_paths(label, role_map.get(label, []), PATHS_PROXY)
print(f"\nDone. Total {total} permission entries registered.")
print("NOTE: 重启应用(或调用 /rbac/refresh_userperm.dspy后权限生效。")
sys.exit(asyncio.run(run_all(add_only)))
if __name__ == "__main__":