# wechat_config.dspy - 微信通道配置(系统级单条:业主机构公众号,仅系统 admin) # action=get: 返回系统级公众号配置(appsecret 脱敏) # action=save: 保存配置(仅系统 admin) import json from appPublic.rc4 import password as _enc, unpassword as _dec uid = await get_user() if not uid: return json.dumps({"success": False, "error": "请先登录"}, ensure_ascii=False) action = (params_kw or {}).get('action', 'get') dbname = get_module_dbname('pipeline-sdlc') # 系统级公众号:全局一条,org_id 固定为 '0'(业主机构) SYS_ORG_ID = '0' # 查用户角色(pipeline 库),superuser/admin 可配置 is_admin = False try: async with DBPools().sqlorContext(dbname) as sor: rrecs = await sor.sqlExe( "SELECT r.name FROM userrole ur JOIN role r ON ur.roleid=r.id WHERE ur.userid=${u}$", {"u": uid}) roles = [getattr(r, 'name', '') for r in (rrecs or [])] is_admin = ('superuser' in roles) or ('admin' in roles) except Exception: pass if action == 'get': async with DBPools().sqlorContext(dbname) as sor: recs = await sor.sqlExe( "SELECT * FROM wechat_channel_config WHERE org_id=${o}$", {"o": SYS_ORG_ID}) if not recs: return json.dumps({"success": True, "config": None, "is_admin": is_admin}, ensure_ascii=False) r = recs[0] return json.dumps({"success": True, "is_admin": is_admin, "config": { "id": getattr(r, 'id', ''), "name": getattr(r, 'name', ''), "appid": getattr(r, 'appid', ''), "appsecret": "***", # 脱敏,不回传明文 "token": getattr(r, 'token', ''), "encoding_aes_key": getattr(r, 'encoding_aes_key', ''), "enabled": getattr(r, 'enabled', '1'), }}, ensure_ascii=False) elif action == 'save': if not is_admin: return json.dumps({"success": False, "error": "仅系统管理员可配置微信通道"}, ensure_ascii=False) name = (params_kw or {}).get('name', '') appid = (params_kw or {}).get('appid', '') appsecret = (params_kw or {}).get('appsecret', '') token = (params_kw or {}).get('token', '') aes_key = (params_kw or {}).get('encoding_aes_key', '') enabled = (params_kw or {}).get('enabled', '1') if not appid or not token: return json.dumps({"success": False, "error": "appid/token 必填"}, ensure_ascii=False) # appsecret 为空时表示不修改(保留原值) if not appsecret: async with DBPools().sqlorContext(dbname) as sor: recs = await sor.sqlExe( "SELECT appsecret FROM wechat_channel_config WHERE org_id=${o}$", {"o": SYS_ORG_ID}) if recs: appsecret = _dec(getattr(recs[0], 'appsecret', '') or '') if not appsecret: return json.dumps({"success": False, "error": "appsecret 必填"}, ensure_ascii=False) enc_secret = _enc(appsecret) async with DBPools().sqlorContext(dbname) as sor: recs = await sor.sqlExe( "SELECT id FROM wechat_channel_config WHERE org_id=${o}$", {"o": SYS_ORG_ID}) if recs: await sor.sqlExe( "UPDATE wechat_channel_config SET name=${n}$, appid=${a}$, appsecret=${s}$, " "token=${t}$, encoding_aes_key=${k}$, enabled=${e}$ WHERE org_id=${o}$", {"n": name, "a": appid, "s": enc_secret, "t": token, "k": aes_key, "e": enabled, "o": SYS_ORG_ID}) else: await sor.C('wechat_channel_config', { 'id': getID(), 'org_id': SYS_ORG_ID, 'name': name, 'appid': appid, 'appsecret': enc_secret, 'token': token, 'encoding_aes_key': aes_key, 'enabled': enabled, }) return json.dumps({"success": True}, ensure_ascii=False) else: return json.dumps({"error": "Unknown action: " + str(action)}, ensure_ascii=False)