async def sync_cn_ai_user(userid=None, orgid=None, username=None, name=None, email=None): import aiohttp debug(f"sync_cn_ai_user同步用户: {userid}, {orgid}, {username}, {name}, {email}") # 目标URL # domain 从数据库params表中获取到pname=cntoai_domain的pvalue值 domain = None db = DBPools() async with db.sqlorContext('kboss') as sor: domain = await sor.R('params', {'pname': 'cntoai_domain'}) if domain: domain = domain[0]['pvalue'] else: debug(f"sync_cn_ai_user未找到域名") return { 'status': False, 'msg': '未找到域名' } already_sync_user_key = await sor.R('params', {'pname': 'cntoai_already_sync_user_key'}) if already_sync_user_key: already_sync_user_key = already_sync_user_key[0]['pvalue'] else: debug(f"sync_cn_ai_user未找到已同步用户key") return { 'status': False, 'msg': '未找到已同步用户key' } already_sync_user_dappid = await sor.R('params', {'pname': 'cntoai_already_sync_user_dappid'}) if already_sync_user_dappid: already_sync_user_dappid = already_sync_user_dappid[0]['pvalue'] else: debug(f"sync_cn_ai_user未找到已同步用户dappid") return { 'status': False, 'msg': '未找到已同步用户dappid' } url = f"{domain}/rbac/usersync" # 请求头 headers = { "Content-Type": "application/json", "Authorization": "Bearer %s" % already_sync_user_key } # 请求体数据 payload = { "action": "single", "dappid": already_sync_user_dappid, "user": { "id": userid, "orgid": orgid, "username": username, "name": name, "email": email } } try: # 创建一个异步会话 result_sysnc = None async with aiohttp.ClientSession() as session: # 发送POST请求 async with session.post(url, headers=headers, data=json.dumps(payload)) as response: # 打印响应状态码 debug(f"sync_cn_ai_user状态码: {response.status}") result_sysnc = await response.json() if not result_sysnc.get('status') == 'success': debug(f"sync_cn_ai_user同步用户失败: {result_sysnc}") return { 'status': False } db = DBPools() async with db.sqlorContext('kboss') as sor: # user_api_keys表格 userid/opc_apikey # 首先判断apikey是否存在 apikey = result_sysnc['data'][0].get('apikey') appid = result_sysnc['data'][0].get('appid') secretkey = result_sysnc['data'][0].get('secretkey') records = await sor.R('user_api_keys', {'opc_apikey': apikey}) if records: debug(f"sync_cn_ai_user用户{payload['user']['id']}已存在") return { 'status': False, 'msg': '用户opc_apikey已存在' } await sor.C('user_api_keys', { 'userid': userid, 'opc_apikey': apikey, 'appid': appid, 'secretkey': secretkey, 'action': 'sync', 'expire_time': None, }) debug(f"sync_cn_ai_user用户{payload['user']['id']}同步成功") return { 'status': True, 'msg': '用户同步成功' } except Exception as e: debug(f"sync_cn_ai_user{userid}同步用户失败: {e}") return { 'status': False, 'msg': f"sync_cn_ai_user{userid}同步用户失败: {e}" } async def registerUser(ns): """ 用户注册 """ import re db = DBPools() async with db.sqlorContext('kboss') as sor: if ns: if ns.get('username'): userns = {'username': ns['username']} isuser = await sor.R('users', userns) if len(isuser) >= 1: return {'status': False, 'msg': '用户名已注册'} if ns.get('email'): useremai = {'email': ns['email']} isuser = await sor.R('users', useremai) if len(isuser) >= 1: return {'status': False, 'msg': '该邮箱已注册'} usermobile = {'mobile':ns['mobile']} isuser = await sor.R('users', usermobile) if len(isuser) >= 1: return {'status': False, 'msg': '该手机号已注册'} # 用户名没有 则用手机号作为用户名 if not ns.get('username'): ns['username'] = ns['mobile'] # if ns.get('password'): # # 至少8位,包含大小写字母、特殊字符、数字 # if len(ns.get('password')) < 8 or not re.search(r'[a-zA-Z]', ns.get('password')) or not re.search(r'[0-9]', ns.get('password')): # return {'status': False, 'msg': '密码至少8位,包含大小写字母、特殊字符、数字'} if not ns.get('codeid'): return {'status': False, 'msg': '验证码ID不能为空'} if ns.get('codeid'): code = await sor.R('validatecode', {'id': ns.get('codeid'), 'vcode': ns.get('vcode')}) # 验证码五分钟内才有效 create_at是字符串 格式是"2025-11-05 16:00:19" if code: create_at = code[0]['create_at'] now = datetime.datetime.now() create_at_dt = datetime.datetime.strptime(create_at, "%Y-%m-%d %H:%M:%S") if (now - create_at_dt).seconds > 500: return {'status': False, 'msg': '验证码过期'} else: return {'status': False, 'msg': '验证码不正确'} #通过邀请码注册 if ns.get('invitecode'): invitecodens = {} invitecodens['invitecode'] = ns['invitecode'] reacss = await sor.R('invitecode', invitecodens) if len(reacss) >= 1: date = await get_business_date(sor=None) if reacss[0]['expire_date'] < date: return {'status': False, 'msg': '邀请码过期'} try: ns['id'] = uuid() # ns['id'] = UUID() orgid = ns['id'] ns['contactor_phone'] = ns.get('mobile') usercode = await sor.R('users', {'id': reacss[0]['iusserid'], 'del_flg': '0'}) # 通过域名注册 if ns.get('domain_name'): reseller = await sor.R('reseller', {'domain_name': ns.get('domain_name')}) if len(reseller) >= 1: org = await sor.R('organization', {'id': reseller[0]['orgid'], 'del_flg': '0'}) ns['parentid'] = org[0]['id'] else: ns['parentid'] = usercode[0]['orgid'] else: ns['parentid'] = usercode[0]['orgid'] await sor.C('organization', ns) ns['id'] = uuid() # ns['id'] = UUID() userid = ns['id'] ns['orgid'] = orgid ns['password'] = password_encode(ns['password']) await sor.C('users', ns) listrole = ['管理员', '客户'] for i in listrole: role = await sor.R('role', {'role': i, 'org_type': ns['org_type']}) await sor.C('userrole', {'id': uuid(), 'userid': userid, 'roleid': role[0]['id']}) ns['invite_code'] = ns['invitecode'] ns['customerid'] = orgid ns['id'] = uuid() # ns['id'] = UUID() ns['salemanid'] = reacss[0]['iusserid'] await sor.C('customer', ns) promoted_cutomerns = {} promoted_cutomerns['id'] = uuid() # promoted_cutomerns['id'] = UUID() promoted_cutomerns['inviteid'] = reacss[0]['id'] promoted_cutomerns['customer'] = orgid promoted_cutomerns['join_date'] = datetime.datetime.now() await sor.C('promoted_cutomer', promoted_cutomerns) promote_discount = await sor.R('promote_discount', {'promotingid': reacss[0]['promotingid']}) iusseriduser = await sor.R('users', {'id': reacss[0]['iusserid']}) dictns = {} dictns['id'] = uuid() dictns['offer_orgid'] = iusseriduser[0]['orgid'] dictns['bid_orgid'] = orgid dictns['salemode'] = '0' dictns['start_date'] = datetime.datetime.now() dictns['end_date'] = '9999-12-31' await sor.C('saleprotocol', dictns) for i in promote_discount: products = await sor.R('product', {'id': i['productid']}) product_salemode = {} product_salemode['id'] = uuid() product_salemode['protocolid'] = dictns['id'] product_salemode['providerid'] = products[0]['providerid'] product_salemode['productid'] = i['productid'] product_salemode['discount'] = i['discount'] await sor.C('product_salemode', product_salemode) await openCustomerAccounts(sor, usercode[0]['orgid'], orgid) return {'status': True, 'msg': '邀请码注册成功'} except Exception as error: raise error else: return {'status': False, 'msg': '邀请码不正确'} else: try: # 用户orgid ns['id'] = uuid() org_id = ns['id'] ns['contactor_phone'] = ns.get('mobile') # 通过域名注册 if ns.get('domain_name'): # 通过域名查找分销商信息 reseller = await sor.R('reseller', {'domain_name': ns.get('domain_name')}) if len(reseller) >= 1: # 分销商机构ID 即orgid org = await sor.R('organization', {'id': reseller[0]['orgid'], 'del_flg': '0'}) else: # 分销商不存在 则查找业主机构ID org = await sor.R('organization', {'org_type': '0', 'del_flg': '0'}) else: # 没有通过域名 则默认是获取业主机构ID org = await sor.R('organization', {'org_type': '0', 'del_flg': '0'}) # 获取所在机构父级ID ns['parentid'] = org[0]['id'] # 新增用户机构信息 ns_org = { 'id': ns['id'], 'orgname': ns['username'], 'parentid': ns['parentid'], 'org_type': ns['org_type'], 'contactor_phone': ns.get('mobile'), } await sor.C('organization', ns_org) # 生成用户userid ns['id'] = uuid() userid = ns['id'] # 加密用户密码 if ns.get('password'): ns['password'] = password_encode(ns['password']) ns['orgid'] = org_id # 新增用户信息 await sor.C('users', ns) # 新增用户角色信息 listrole = ['管理员', '客户'] for i in listrole: role = await sor.R('role', {'role': i, 'org_type': ns['org_type']}) await sor.C('userrole', {'id': uuid(), 'userid': userid, 'roleid': role[0]['id']}) # 新增客户信息并使用openCustomerAccounts为客户开账 ns['id'] = uuid() ns['customerid'] = org_id await sor.C('customer', ns) await openCustomerAccounts(sor, org[0]['id'], org_id) # 同步用户 await sync_cn_ai_user(userid=userid, orgid=ns_org['id'], username=ns['username'], name=ns['username']) return {'status': True, 'msg': '注册成功'} except Exception as error: # raise error return {'status': False, 'msg': '注册失败, %s' % str(error)} ret = await registerUser(params_kw) return ret