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 @@