# wechat_binding.dspy - 微信用户绑定(验证码方式:用户在 Web 生成验证码,发给公众号完成绑定) # action=gen_code: 生成绑定验证码(存 wechat_bind_code,10分钟有效),返回验证码 # action=get: 查当前用户绑定状态 # action=unbind: 解绑 import json import random import time 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(pipeline 库) org_id = '' try: async with DBPools().sqlorContext(dbname) as sor: urecs = await sor.sqlExe("SELECT orgid FROM users WHERE id=${u}$", {"u": uid}) if urecs: org_id = getattr(urecs[0], 'orgid', '') or '' except Exception: pass if action == 'gen_code': # 生成 6 位验证码,10 分钟有效 code = ''.join([str(random.randint(0, 9)) for _ in range(6)]) expires = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time() + 600)) async with DBPools().sqlorContext(dbname) as sor: # 清理该用户旧的未用验证码 await sor.sqlExe("DELETE FROM wechat_bind_code WHERE user_id=${u}$", {"u": uid}) await sor.C('wechat_bind_code', { 'id': getID(), 'code': code, 'user_id': uid, 'org_id': org_id, 'expires_at': expires, }) return json.dumps({"success": True, "code": code}, ensure_ascii=False) elif action == 'get': async with DBPools().sqlorContext(dbname) as sor: recs = await sor.sqlExe( "SELECT openid FROM wechat_user_binding WHERE user_id=${u}$", {"u": uid}) bound = getattr(recs[0], 'openid', '') if recs else '' return json.dumps({"success": True, "bound": bool(bound)}, ensure_ascii=False) elif action == 'unbind': async with DBPools().sqlorContext(dbname) as sor: await sor.sqlExe( "DELETE FROM wechat_user_binding WHERE user_id=${u}$", {"u": uid}) return json.dumps({"success": True}, ensure_ascii=False) else: return json.dumps({"error": "Unknown action: " + str(action)}, ensure_ascii=False)