diff --git a/b/cntoai/get_user_balance.dspy b/b/cntoai/get_user_balance.dspy index 1a646d8..53c6ce8 100644 --- a/b/cntoai/get_user_balance.dspy +++ b/b/cntoai/get_user_balance.dspy @@ -35,8 +35,6 @@ async def get_user_balance(ns={}): } orgid = await sor.R('organization', {'id': user[0]['orgid']}) balance = await getCustomerBalance(sor, orgid[0]['id']) - ns['balance'] = balance - debug(ns) return { 'status': 'ok', 'balance': balance diff --git a/b/cntoai/model_management_customer_search copy.dspy b/b/cntoai/model_management_customer_search copy.dspy deleted file mode 100644 index 6d82e56..0000000 --- a/b/cntoai/model_management_customer_search copy.dspy +++ /dev/null @@ -1,94 +0,0 @@ -def _escape(value): - if value is None: - return None - return str(value).replace("'", "''") - -# 客户侧可见字段(不含 listing_status、is_active 等运营字段) -_CUSTOMER_MODEL_COLUMNS = """ - id, llmid, provider, model_name, display_name, model_logo, model_type, - context_length, input_token_price, output_token_price, - cache_hit_input_price, billing_method, billing_unit, - capabilities, limitations, highlights, description, sort_order,is_active, experience -""" - - -def _customer_listed_conditions(ns): - """已上架且启用的模型;支持按厂商、模型类别筛选""" - conditions = ["listing_status = 1", "is_active = 1"] - if ns.get('provider'): - conditions.append("provider = '%s'" % _escape(ns.get('provider'))) - if ns.get('model_type'): - conditions.append("model_type = '%s'" % _escape(ns.get('model_type'))) - return ' AND '.join(conditions) - -async def model_management_customer_search(ns={}): - """ - 客户查看模型列表:仅已上架且启用的模型。 - - 可选参数: - provider (str) 厂商,精确匹配筛选 - model_type (str) 模型类别,精确匹配筛选 - current_page (int) 页码,默认 1 - page_size (int) 每页条数,默认 10 - - 返回 data: - provider_list 当前可见模型中的厂商列表(去重) - model_type_list 当前可见模型中的模型类别列表(去重) - filter_total 当前筛选条件下的模型数量 - model_list 模型列表 - page_size, current_page - - 调用示例见 model_management_customer_search.dspy - """ - page_size = int(ns.get('page_size', 1000)) - current_page = int(ns.get('current_page', 1)) - offset = (current_page - 1) * page_size - where_clause = _customer_listed_conditions(ns) - listed_base = "listing_status = 1 AND is_active = 1" - - db = DBPools() - async with db.sqlorContext('kboss') as sor: - try: - provider_sql = """ - SELECT DISTINCT provider FROM model_management - WHERE %s AND provider IS NOT NULL AND provider != '' - ORDER BY provider; - """ % listed_base - model_type_sql = """ - SELECT DISTINCT model_type FROM model_management - WHERE %s AND model_type IS NOT NULL AND model_type != '' - ORDER BY model_type; - """ % listed_base - - count_sql = """ - SELECT COUNT(*) AS total_count FROM model_management WHERE %s; - """ % where_clause - find_sql = """ - SELECT %s FROM model_management - WHERE %s - ORDER BY sort_order ASC - LIMIT %s OFFSET %s; - """ % (_CUSTOMER_MODEL_COLUMNS, where_clause, page_size, offset) - - provider_rows = await sor.sqlExe(provider_sql, {}) - model_type_rows = await sor.sqlExe(model_type_sql, {}) - filter_total = (await sor.sqlExe(count_sql, {}))[0]['total_count'] - model_list = await sor.sqlExe(find_sql, {}) - - return { - 'status': True, - 'msg': 'customer model search success', - 'data': { - 'provider_list': [r['provider'] for r in provider_rows], - 'model_type_list': [r['model_type'] for r in model_type_rows], - 'filter_total': filter_total, - 'page_size': page_size, - 'current_page': current_page, - 'model_list': model_list, - }, - } - except Exception as e: - return {'status': False, 'msg': 'customer model search failed, %s' % str(e)} - -ret = await model_management_customer_search1(params_kw) -return ret \ No newline at end of file diff --git a/b/cntoai/model_management_customer_search.dspy b/b/cntoai/model_management_customer_search.dspy index 1381e0f..25c197c 100644 --- a/b/cntoai/model_management_customer_search.dspy +++ b/b/cntoai/model_management_customer_search.dspy @@ -3,38 +3,22 @@ def _escape(value): return None return str(value).replace("'", "''") -# 客户侧返回字段结构保持与原 model_management 版本一致 +# 客户侧可见字段(不含 listing_status、is_active 等运营字段) _CUSTOMER_MODEL_COLUMNS = """ - id, - id AS llmid, - provider_name AS provider, - model AS model_name, - name AS display_name, - provider_iconurl AS model_logo, - catelogname AS model_type, - NULL AS context_length, - 0 AS input_token_price, - 0 AS output_token_price, - 0 AS cache_hit_input_price, - pricing_display AS billing_method, - '' AS billing_unit, - description AS capabilities, - '' AS limitations, - '' AS highlights, - description, - 0 AS sort_order, - 1 AS is_active, - 0 AS experience + id, llmid, provider, model_name, display_name, model_logo, model_type, + context_length, input_token_price, output_token_price, + cache_hit_input_price, billing_method, billing_unit, + capabilities, limitations, highlights, description, sort_order,is_active, experience """ def _customer_listed_conditions(ns): """已上架且启用的模型;支持按厂商、模型类别筛选""" - conditions = ["status = 'published'"] + conditions = ["listing_status = 1", "is_active = 1"] if ns.get('provider'): - conditions.append("provider_name = '%s'" % _escape(ns.get('provider'))) + conditions.append("provider = '%s'" % _escape(ns.get('provider'))) if ns.get('model_type'): - conditions.append("catelogname = '%s'" % _escape(ns.get('model_type'))) + conditions.append("model_type = '%s'" % _escape(ns.get('model_type'))) return ' AND '.join(conditions) async def model_management_customer_search(ns={}): @@ -60,27 +44,27 @@ async def model_management_customer_search(ns={}): current_page = int(ns.get('current_page', 1)) offset = (current_page - 1) * page_size where_clause = _customer_listed_conditions(ns) - listed_base = "status = 'published'" + listed_base = "listing_status = 1 AND is_active = 1" db = DBPools() async with db.sqlorContext('kboss') as sor: try: provider_sql = """ - SELECT DISTINCT provider_name AS provider FROM llm - WHERE %s AND provider_name IS NOT NULL AND provider_name != '' + SELECT DISTINCT provider FROM model_management + WHERE %s AND provider IS NOT NULL AND provider != '' ORDER BY provider; """ % listed_base model_type_sql = """ - SELECT DISTINCT catelogname AS model_type FROM llm - WHERE %s AND catelogname IS NOT NULL AND catelogname != '' + SELECT DISTINCT model_type FROM model_management + WHERE %s AND model_type IS NOT NULL AND model_type != '' ORDER BY model_type; """ % listed_base count_sql = """ - SELECT COUNT(*) AS total_count FROM llm WHERE %s; + SELECT COUNT(*) AS total_count FROM model_management WHERE %s; """ % where_clause find_sql = """ - SELECT %s FROM llm + SELECT %s FROM model_management WHERE %s ORDER BY sort_order ASC LIMIT %s OFFSET %s; diff --git a/b/cntoai/sync_model_to_llm.dspy b/b/cntoai/sync_model_to_llm.dspy index 917f0cf..ac187af 100644 --- a/b/cntoai/sync_model_to_llm.dspy +++ b/b/cntoai/sync_model_to_llm.dspy @@ -1,182 +1,5 @@ async def sync_model_to_llm(ns={}): import aiohttp - - async def get_sync_orgid(sor): - if ns.get('orgid'): - return ns.get('orgid') - user_li = await sor.R('users', {'id': await get_user()}) - return user_li[0].get('orgid') if user_li else '' - - def build_llm_data(item): - return { - 'id': item.get('id') or uuid(), - 'name': item.get('name'), - 'model': item.get('model'), - 'description': item.get('description'), - 'iconid': item.get('iconid'), - 'upappid': item.get('upappid'), - 'providerid': item.get('providerid'), - 'ownerid': item.get('ownerid') or '0', - 'enabled_date': item.get('enabled_date'), - 'expired_date': item.get('expired_date'), - 'min_balance': item.get('min_balance'), - 'status': item.get('status') or 'published', - 'catelogname': item.get('catelogname'), - 'catelog_id': item.get('catelog_id') or item.get('catelogid'), - 'llmcatelogid': item.get('catelog_id') or item.get('catelogid'), - 'apiname': item.get('apiname'), - 'query_apiname': item.get('query_apiname'), - 'query_period': item.get('query_period'), - 'ppid': item.get('ppid'), - 'provider_name': item.get('provider_name'), - 'pricing_display': item.get('pricing_display'), - 'provider_iconurl': item.get('provider_iconurl') - } - - async def ensure_provider(sor, provider_orgcode, provider_name, sync_orgid, item): - exist_org_li = await sor.R('organization', {'orgcode': provider_orgcode, 'del_flg': '0'}) - if exist_org_li: - provider_orgid = exist_org_li[0].get('id') - await sor.U('organization', { - 'id': provider_orgid, - 'orgname': provider_name, - 'orgcode': provider_orgcode, - 'parentid': sync_orgid, - 'org_type': '4' - }) - else: - provider_orgid = uuid() - await sor.C('organization', { - 'id': provider_orgid, - 'orgname': provider_name, - 'contactor': '连战', - 'contactor_phone': '13800138000', - 'address': '北京市海淀区', - 'main_business': provider_name, - 'orgcode': provider_orgcode, - 'emailaddress': 'lianzhan@cntoai.com', - 'org_type': '4', - 'parentid': sync_orgid - }) - await openProviderAccounts(sor, sync_orgid, provider_orgid) - - provider_li = await sor.R('provider', {'orgid': provider_orgid, 'del_flg': '0'}) - provider_data = { - 'name': provider_name, - 'description': provider_name, - 'appid': item.get('upappid') or '', - 'providerkey': provider_orgcode, - 'state': '1', - 'start_date': '2026-07-01', - 'end_date': '9999-12-31', - 'settle_mode': '3', - 'settle_flowid': '0', - 'settle_datep': 'M00', - 'discount_mode': 1, - 'orgid': provider_orgid - } - if provider_li: - provider_id = provider_li[0].get('id') - provider_data['id'] = provider_id - await sor.U('provider', provider_data) - else: - provider_id = uuid() - provider_data['id'] = provider_id - await sor.C('provider', provider_data) - - protocol_li = await sor.R('saleprotocol', {'offer_orgid': provider_orgid, 'bid_orgid': sync_orgid, 'del_flg': '0'}) - if protocol_li: - protocolid = protocol_li[0].get('id') - await sor.U('saleprotocol', { - 'id': protocolid, - 'offer_orgid': provider_orgid, - 'bid_orgid': sync_orgid, - 'salemode': '0', - 'settle_mode': '3', - 'settle_dp': 'M00', - 'start_date': '2026-07-01', - 'end_date': '9999-12-31' - }) - else: - protocolid = uuid() - await sor.C('saleprotocol', { - 'id': protocolid, - 'offer_orgid': provider_orgid, - 'bid_orgid': sync_orgid, - 'salemode': '0', - 'settle_mode': '3', - 'settle_dp': 'M00', - 'start_date': '2026-07-01', - 'end_date': '9999-12-31' - }) - - return { - 'provider_orgid': provider_orgid, - 'provider_id': provider_id, - 'protocolid': protocolid - } - - async def sync_product(sor, item, category_list, provider_orgid, protocolid, sync_orgid): - product_data = { - 'providerid': provider_orgid, - 'providerpid': item.get('id'), - 'name': item.get('name'), - # 'description': item.get('description') or '', - 'ptype': '21', - 'state': '1', - 'salemode': '0', - 'product_code': item.get('model'), - 'reseller_orgid': sync_orgid, - 'classify': 'A', - 'label': item.get('catelogname') or category_list.get('catelogname'), - # 'productgroup': item.get('catelog_id') or item.get('catelogid') or category_list.get('catelogid'), - 'product_area': '北京', - 'effect_date': '2026-07-01', - 'expire_date': '9999-12-31' - } - product_li = await sor.R('product', {'providerid': provider_orgid, 'product_code': item.get('model'), 'del_flg': '0'}) - if product_li: - product_id = product_li[0].get('id') - product_data['id'] = product_id - await sor.U('product', product_data) - product_action = 'update' - else: - product_id = uuid() - product_data['id'] = product_id - await sor.C('product', product_data) - product_action = 'insert' - - salemode_data = { - 'protocolid': protocolid, - 'providerid': provider_orgid, - 'productid': product_id, - 'discount': 1, - 'unit': 'hour' - } - product_salemode_li = await sor.R('product_salemode', { - 'protocolid': protocolid, - 'providerid': provider_orgid, - 'productid': product_id, - 'del_flg': '0' - }) - if product_salemode_li: - salemode_data['id'] = product_salemode_li[0].get('id') - await sor.U('product_salemode', salemode_data) - else: - salemode_data['id'] = uuid() - await sor.C('product_salemode', salemode_data) - - return product_action - - async def upsert_llm(sor, item): - llm_data = build_llm_data(item) - exist_llm = await sor.R('llm', {'model': item.get('model')}) - if exist_llm: - llm_data['id'] = exist_llm[0].get('id') - await sor.U('llm', llm_data) - return 'update' - await sor.C('llm', llm_data) - return 'insert' # 从数据库读取domain和Bearer token db = DBPools() @@ -190,13 +13,6 @@ async def sync_model_to_llm(ns={}): } domain = domain_li[0]['pvalue'] bearer_token = user_key[0]['pvalue'] - # sync_orgid = await get_sync_orgid(sor) - sync_orgid = "mIWUHBeeDM8mwAFPIQ8pS" # 固定写 - if not sync_orgid: - return { - 'status': False, - 'msg': '未找到当前用户所属机构' - } url = f"{domain}/llmage/list_llms" header = { @@ -216,93 +32,38 @@ async def sync_model_to_llm(ns={}): # 插入数据库 db = DBPools() async with db.sqlorContext('kboss') as sor: - provider_groups = {} - current_model_set = set() + new_llms_count = 0 + new_llms_list = [] for category_list in result: for item in category_list.get('llms', []): - provider_orgcode = item.get('providerid') - model = item.get('model') - if not provider_orgcode or not model: + # 查找数据库中是否已经存在,不存在就插入 + exist_llm = await sor.R('llm', {'model': item.get('model')}) + if exist_llm: continue - item['catelogname'] = item.get('catelogname') or category_list.get('catelogname') - item['catelog_id'] = item.get('catelog_id') or item.get('catelogid') or category_list.get('catelogid') - current_model_set.add(model) - if provider_orgcode not in provider_groups: - provider_groups[provider_orgcode] = { - 'provider_name': item.get('provider_name') or provider_orgcode or '模型供应商', - 'items': [] - } - elif item.get('provider_name'): - provider_groups[provider_orgcode]['provider_name'] = item.get('provider_name') - provider_groups[provider_orgcode]['items'].append({ - 'item': item, - 'category': category_list - }) - - provider_count = 0 - product_insert_count = 0 - product_update_count = 0 - llm_insert_count = 0 - llm_update_count = 0 - synced_llms_list = [] - - for provider_orgcode, provider_group in provider_groups.items(): - provider_name = provider_group.get('provider_name') or provider_orgcode or '模型供应商' - provider_data = await ensure_provider( - sor, - provider_orgcode, - provider_name, - sync_orgid, - provider_group['items'][0]['item'] - ) - provider_count += 1 - - for model_info in provider_group['items']: - item = model_info['item'] - category_list = model_info['category'] - product_action = await sync_product( - sor, - item, - category_list, - provider_data['provider_orgid'], - provider_data['protocolid'], - sync_orgid - ) - if product_action == 'insert': - product_insert_count += 1 - else: - product_update_count += 1 - - llm_action = await upsert_llm(sor, item) - if llm_action == 'insert': - llm_insert_count += 1 - else: - llm_update_count += 1 - synced_llms_list.append(item.get('model')) - - llm_unpublished_count = 0 - exist_llm_li = await sor.R('llm', {}) - for exist_llm in exist_llm_li: - exist_model = exist_llm.get('model') - if exist_model and exist_model not in current_model_set and exist_llm.get('status') != 'unpublished': - await sor.U('llm', { - 'id': exist_llm.get('id'), - 'status': 'unpublished' - }) - llm_unpublished_count += 1 + new_llms = { + 'id': item.get('id'), + 'name': item.get('name'), + 'model': item.get('model'), + 'description': item.get('description'), + 'llmcatelogid': item.get('catelog_id') or item.get('catelogid'), + 'iconid': item.get('iconid'), + 'upappid': item.get('upappid'), + 'apiname': item.get('apiname'), + 'providerid': item.get('providerid'), + 'ownerid': item.get('ownerid') or '0', + 'enabled_date': item.get('enabled_date'), + 'expired_date': item.get('expired_date'), + 'query_apiname': item.get('query_apiname') or '', + 'query_period': item.get('query_period'), + 'ppid': item.get('ppid'), + } + new_llms_count += 1 + new_llms_list.append(new_llms.get('model')) + await sor.C('llm', new_llms) return { 'status': True, - 'msg': 'sync_llm_list同步模型成功', - 'data': { - 'provider_count': provider_count, - 'product_insert_count': product_insert_count, - 'product_update_count': product_update_count, - 'llm_insert_count': llm_insert_count, - 'llm_update_count': llm_update_count, - 'llm_unpublished_count': llm_unpublished_count, - 'model_list': synced_llms_list - } + 'msg': f"sync_llm_list同步模型成功,共插入{new_llms_count}个模型,模型列表: {new_llms_list}" } except Exception as e: diff --git a/b/llm.sql b/b/llm.sql deleted file mode 100644 index 7bd517c..0000000 --- a/b/llm.sql +++ /dev/null @@ -1,145 +0,0 @@ -# 创建表格命令 -CREATE TABLE llm ( - id VARCHAR(64) NOT NULL COMMENT '唯一标识', - name VARCHAR(50) NOT NULL COMMENT '模型名称', - model VARCHAR(50) NOT NULL COMMENT '模型代号', - description TEXT COMMENT '模型描述', - iconid VARCHAR(50) COMMENT '图标标识', - upappid VARCHAR(50) COMMENT '上层应用ID', - providerid VARCHAR(64) COMMENT '供应商ID', - ownerid VARCHAR(20) DEFAULT '0' COMMENT '所有者ID', - enabled_date DATE COMMENT '启用日期', - expired_date DATE COMMENT '过期日期', - min_balance INT DEFAULT 0 COMMENT '最低余额要求(元)', - status VARCHAR(20) COMMENT '状态(如published)', - catelogname VARCHAR(50) COMMENT '目录名称(如文生视频)', - catelog_id VARCHAR(20) COMMENT '目录ID', - apiname VARCHAR(50) COMMENT 'API名称', - query_apiname VARCHAR(50) COMMENT '查询API名称', - query_period INT COMMENT '查询周期(秒)', - ppid VARCHAR(64) COMMENT '定价计划ID', - provider_name VARCHAR(100) COMMENT '供应商名称', - pricing_display TEXT COMMENT '定价显示文本', - provider_iconurl VARCHAR(255) COMMENT '供应商图标URL', - PRIMARY KEY (id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='LLM模型信息表'; - - -# 厂商返回的部分数据示例 -[ - { - "catelogid": "2i2v", - "catelogname": "首尾帧生视频", - "llms": [ - { - "id": "r0ill7L0s6PtBS8mkmg-7", - "name": "viduq3-pro", - "model": "viduq3-pro", - "description": "vidu文生视频,viduq3-pro模型", - "iconid": "vidu", - "upappid": "vidu", - "providerid": "Bu3Z6OXANehbkD6OK5NJb", - "ownerid": "0", - "enabled_date": "2026-01-01", - "expired_date": "9999-12-31", - "min_balance": 10, - "status": "published", - "catelogname": "首尾帧生视频", - "catelog_id": "2i2v", - "apiname": "2i2v", - "query_apiname": "taskStatus", - "query_period": 30, - "ppid": "sF2gcl7UeANKtnZv8hfvL", - "provider_name": "北京生数科技有限公司", - "pricing_display": " - duration: 0.56 元/秒 ", - "provider_iconurl": "https://token.opencomputing.cn/appbase/show_icon.dspy?id=vidu" - } - ] - }, - { - "catelogid": "asr", - "catelogname": "语音识别", - "llms": [ - { - "id": "9glv3S-JSzxholxAblU14", - "name": "qwen3-asr-flash", - "model": "qwen3-asr-flash", - "description": "通义千问系列的录音文件识", - "iconid": "qwen", - "upappid": "tongyi-wan", - "providerid": "6fadgewjraOyvxC_EkHou", - "ownerid": "0", - "enabled_date": "2025-12-01", - "expired_date": "9999-12-31", - "min_balance": 10, - "status": "published", - "catelogname": "语音识别", - "catelog_id": "asr", - "apiname": "short_asr", - "query_apiname": null, - "query_period": null, - "ppid": "16pwEsQeHiOrxC0O6A2j6", - "provider_name": "阿里云", - "provider_iconurl": "https://token.opencomputing.cn/appbase/show_icon.dspy?id=qwen" - } - ] - }, - { - "catelogid": "digital_human", - "catelogname": "数字人", - "llms": [ - { - "id": "KOsAo6YjTdU0KG7_sKUJF", - "name": "wan2.2-s2v", - "model": "wan2.2-s2v", - "description": "模型:wan2.2-s2v,输入音频和照片,用照片中的人生成数字人", - "iconid": "qwen", - "upappid": "tongyi-wan", - "providerid": "6fadgewjraOyvxC_EkHou", - "ownerid": "0", - "enabled_date": "2025-12-19", - "expired_date": "9999-12-31", - "min_balance": 10, - "status": "published", - "catelogname": "数字人", - "catelog_id": "digital_human", - "apiname": "avator", - "query_apiname": "avatorstatus", - "query_period": 10, - "ppid": "0B6aldoAej1PpZ4ydtrEZ", - "provider_name": "阿里云", - "pricing_display": " - duration: 0.5 元/秒 [分辨率=480P]\n - duration: 0.9 元/秒 [分辨率=720P]", - "provider_iconurl": "https://token.opencomputing.cn/appbase/show_icon.dspy?id=qwen" - } - ] - }, - { - "catelogid": "i2v", - "catelogname": "图生视频", - "llms": [ - { - "id": "7y7kfYM0Xasizyi37WvAZ", - "name": "happyhorse-1.0-i2v", - "model": "happyhorse-1.0-i2v", - "description": "HappyHorse图生视频模型,以首帧图片为基础,支持通过文本描述进行引导,生成物理真实、运动流畅的视频。", - "iconid": "qwen", - "upappid": "tongyi-wan", - "providerid": "6fadgewjraOyvxC_EkHou", - "ownerid": "0", - "enabled_date": "2026-04-28", - "expired_date": "9999-12-31", - "min_balance": 10, - "status": "published", - "catelogname": "图生视频", - "catelog_id": "i2v", - "apiname": "i2v-happyhorse", - "query_apiname": "t2vstatus", - "query_period": 10, - "ppid": "knEwDP35DEz5oMAXyvwN3", - "provider_name": "阿里云", - "pricing_display": " - duration: 0.9 元/秒 [SR=720]\n - duration: 1.6 元/秒 [SR=1080]", - "provider_iconurl": "https://token.opencomputing.cn/appbase/show_icon.dspy?id=qwen" - }, - ] - } -] \ No newline at end of file diff --git a/b/provider/providerAdd.dspy b/b/provider/providerAdd.dspy index ae3d96e..b522eaa 100644 --- a/b/provider/providerAdd.dspy +++ b/b/provider/providerAdd.dspy @@ -82,6 +82,14 @@ async def providerAdd(ns={}): 'status': False, 'msg': 'provider add failed, orgcode is empty' } + # filter by orgcode + res = await sor.R('organization', {}) + orgcodes = [orgc.get('orgcode') for orgc in res] + if org_code in orgcodes: + return { + 'status': False, + 'msg': 'provider add failed, orgcode has already exist' + } if not ns.get('orgid'): orgid_li = await sor.R('users', {'id': await get_user()}) orgid = orgid_li[0].get('orgid') if orgid_li else '' @@ -93,33 +101,8 @@ async def providerAdd(ns={}): else: orgid = ns.get('orgid') - # filter by orgcode; existing provider returns ids for idempotent callers - exist_org_li = await sor.R('organization', {'orgcode': org_code, 'del_flg': '0'}) - if len(exist_org_li) >= 1: - exist_org = exist_org_li[0] - exist_provider_li = await sor.R('provider', {'orgid': exist_org.get('id'), 'del_flg': '0'}) - if not exist_provider_li: - return { - 'status': False, - 'msg': 'provider add failed, orgcode has already exist but provider not found' - } - exist_protocol_li = await sor.R('saleprotocol', {'offer_orgid': exist_org.get('id'), 'bid_orgid': orgid, 'del_flg': '0'}) - if not exist_protocol_li: - exist_protocol_li = await sor.R('saleprotocol', {'offer_orgid': exist_org.get('id'), 'del_flg': '0'}) - return { - 'status': True, - 'msg': 'provider already exist', - 'data': { - 'orgid': exist_org.get('id'), - 'provider_orgid': exist_org.get('id'), - 'provider_id': exist_provider_li[0].get('id'), - 'protocolid': exist_protocol_li[0].get('id') if exist_protocol_li else None - } - } - # 供应商parentid 和 运营机构id相同 ns_org['parentid'] = orgid - ns_sale_mode['bid_orgid'] = orgid if not ns_provider.get('start_date'): ns_provider['start_date'] = time.strftime('%Y-%m-%d %H:%M:%S') @@ -132,13 +115,7 @@ async def providerAdd(ns={}): await openProviderAccounts(sor, orgid, ns_org['id']) return { "status": True, - "msg": "provider add success", - "data": { - "orgid": ns_org['id'], - "provider_orgid": ns_org['id'], - "provider_id": ns_provider['id'], - "protocolid": ns_sale_mode['id'] - } + "msg": "provider add success" } except Exception as e: raise e diff --git a/b/reseller/reseller_add_user.dspy b/b/reseller/reseller_add_user.dspy index 2d77f31..53736dc 100644 --- a/b/reseller/reseller_add_user.dspy +++ b/b/reseller/reseller_add_user.dspy @@ -27,16 +27,15 @@ async def reseller_add_user(ns): try: ns['id'] = uuid() ns['password'] = password_encode(ns['password']) - # tenant_orgid = await get_reseller_user_tenant_orgid(sor, ns.get('orgid')) - tenant_orgid = ns.get('orgid') + tenant_orgid = await get_reseller_user_tenant_orgid(sor, ns.get('orgid')) if not tenant_orgid: return {'status': False, 'msg': '未找到用户所属租户'} user_sql = """select id from users where username = '%s' and tenant_orgid = '%s' and del_flg = '0' limit 1;""" % (ns['username'], tenant_orgid) user = await sor.sqlExe(user_sql, {}) if len(user) >= 1: return {'status': False, 'msg': '用户名重复'} - rolereacs = await sor.R('role', {'role': '管理员', 'del_flg': '0', 'org_type': ns.get('org_type')}) - ns['user_reseller'] = ns.get('org_type') + rolereacs = await sor.R('role', {'role': '管理员', 'del_flg': '0', 'org_type': '1'}) + ns['user_reseller'] = '1' ns['tenant_orgid'] = tenant_orgid await sor.C('users', ns) await sor.C('userrole', {'userid': ns['id'], 'roleid': rolereacs[0]['id'], 'id': uuid()}) diff --git a/b/user/add_user_role.dspy b/b/user/add_user_role.dspy deleted file mode 100644 index 06988e3..0000000 --- a/b/user/add_user_role.dspy +++ /dev/null @@ -1,55 +0,0 @@ -import json - - -def _parse_roleids(roleid): - if roleid is None: - return [] - if isinstance(roleid, list): - return [i for i in roleid if i] - if isinstance(roleid, str): - roleid = roleid.strip() - if not roleid: - return [] - try: - roleids = json.loads(roleid) - except Exception: - roleids = [roleid] - if isinstance(roleids, list): - return [i for i in roleids if i] - return [roleids] if roleids else [] - return [roleid] - - -async def add_user_role(ns): - """ - 用户分配角色 - :param userid: 用户id - :param roleid: 角色id列表 - :return: - """ - if not ns or not ns.get('userid') or 'roleid' not in ns: - return {'status': False, 'msg': '参数不正确'} - - userid = ns.get('userid') - roleids = _parse_roleids(ns.get('roleid')) - db = DBPools() - async with db.sqlorContext('kboss') as sor: - userroles = await sor.R('userrole', {'userid': userid}) - for userrole in userroles: - if userrole.get('roleid') not in roleids: - await sor.U('userrole', {'del_flg': '1', 'id': userrole['id']}) - - for roleid in roleids: - roles = {'userid': userid, 'roleid': roleid} - reacs = await sor.R('userrole', roles) - if len(reacs) >= 1: - await sor.U('userrole', {'id': reacs[0]['id'], 'del_flg': '0'}) - continue - await sor.C('userrole', {'id': uuid(), 'userid': userid, 'roleid': roleid}) - return {'status': True, 'msg': '添加成功'} - - return {'status': False, 'msg': '添加失败'} - - -ret = await add_user_role(params_kw) -return ret diff --git a/b/user/get_user_and_role.dspy b/b/user/get_user_and_role.dspy deleted file mode 100644 index f209a11..0000000 --- a/b/user/get_user_and_role.dspy +++ /dev/null @@ -1,90 +0,0 @@ -def _parse_page(ns, default_page=1, default_size=20, max_size=200): - try: - current_page = int(ns.get('current_page') or ns.get('page') or default_page) - except (TypeError, ValueError): - current_page = default_page - try: - page_size = int(ns.get('page_size') or default_size) - except (TypeError, ValueError): - page_size = default_size - current_page = max(1, current_page) - page_size = max(1, min(page_size, max_size)) - return current_page, page_size, (current_page - 1) * page_size - - -async def get_user_and_role(ns={}): - """获取机构下所有用户及用户对应的所有角色""" - orgid = ns.get('orgid') - if not orgid: - return {'status': False, 'msg': '缺少 orgid'} - - current_page, page_size, offset = _parse_page(ns) - db = DBPools() - async with db.sqlorContext('kboss') as sor: - try: - where_sql = """ - u.del_flg='0' - AND ( - u.orgid=${orgid}$ - OR o.parentid=${orgid}$ - ) - """ - if ns.get('username'): - where_sql += " AND u.username LIKE '%%%%%s%%%%'" % ns.get('username') - if ns.get('mobile'): - where_sql += " AND u.mobile LIKE '%%%%%s%%%%'" % ns.get('mobile') - count_rows = await sor.sqlExe( - """ - SELECT COUNT(*) AS total_count - FROM users u - LEFT JOIN organization o ON u.orgid = o.id AND o.del_flg='0' - WHERE %s - """ % where_sql, - {'orgid': orgid}, - ) - total_count = count_rows[0]['total_count'] if count_rows else 0 - sql = """ - SELECT u.* - FROM users u - LEFT JOIN organization o ON u.orgid = o.id AND o.del_flg='0' - LEFT JOIN ( - SELECT userid, MAX(create_at) AS userrole_create_at - FROM userrole - WHERE del_flg='0' - GROUP BY userid - ) ur_sort ON u.id = ur_sort.userid - WHERE %s - ORDER BY ur_sort.userrole_create_at DESC, u.create_at DESC - LIMIT %d OFFSET %d - """ % (where_sql, page_size, offset) - users = await sor.sqlExe(sql, {'orgid': orgid}) - for user in users: - user['roles'] = [] - userroles = await sor.R('userrole', {'userid': user['id']}) - userroles = sorted(userroles, key=lambda item: item.get('create_at') or '', reverse=True) - for userrole in userroles: - if userrole.get('del_flg') == '1' or not userrole.get('roleid'): - continue - roles = await sor.R('role', {'id': userrole['roleid']}) - if len(roles) >= 1 and roles[0].get('del_flg') != '1': - user['roles'].append({ - 'id': roles[0].get('id'), - 'name': roles[0].get('role'), - }) - - return { - 'status': True, - 'msg': 'ok', - 'data': { - 'total_count': total_count, - 'current_page': current_page, - 'page_size': page_size, - 'rows': users, - }, - } - except Exception as e: - return {'status': False, 'msg': '获取用户角色失败, %s' % str(e)} - - -ret = await get_user_and_role(params_kw) -return ret diff --git a/f/web-kboss/src/App.vue b/f/web-kboss/src/App.vue index d1ac44a..6e799fe 100644 --- a/f/web-kboss/src/App.vue +++ b/f/web-kboss/src/App.vue @@ -4,10 +4,6 @@ -
@@ -42,7 +38,6 @@ - -