Compare commits
5 Commits
7f483fa246
...
f2b432df51
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2b432df51 | ||
|
|
4af3ff5000 | ||
|
|
35d7fa08ea | ||
|
|
d7e2875375 | ||
|
|
144b3afbc8 |
@ -35,6 +35,8 @@ 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
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
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 ''
|
||||
|
||||
# 从数据库读取domain和Bearer token
|
||||
db = DBPools()
|
||||
@ -13,6 +19,13 @@ 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 = {
|
||||
@ -33,29 +46,103 @@ async def sync_model_to_llm(ns={}):
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
new_llms_count = 0
|
||||
sync_products_count = 0
|
||||
new_llms_list = []
|
||||
for category_list in result:
|
||||
for item in category_list.get('llms', []):
|
||||
provider_orgcode = item.get('providerid')
|
||||
provider_name = item.get('provider_name') or item.get('providerid') or '模型供应商'
|
||||
if not provider_orgcode:
|
||||
continue
|
||||
|
||||
provider_ns = {
|
||||
'orgid': sync_orgid,
|
||||
'orgcode': provider_orgcode,
|
||||
'orgname': provider_name,
|
||||
'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_flowid': '0',
|
||||
'salemode': '0',
|
||||
'settle_mode': '3',
|
||||
'settle_datep': 'M00',
|
||||
'contactor': '连战',
|
||||
'contactor_phone': '13800138000',
|
||||
'emailaddress': 'lianzhan@cntoai.com',
|
||||
'address': '北京市海淀区',
|
||||
'org_type': '4'
|
||||
}
|
||||
provider_res = await path_call('../provider/providerAdd.dspy', provider_ns)
|
||||
if not provider_res.get('status'):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': '供应商同步失败, %s, %s' % (provider_name, provider_res.get('msg'))
|
||||
}
|
||||
provider_data = provider_res.get('data') or {}
|
||||
provider_orgid = provider_data.get('provider_orgid') or provider_data.get('orgid')
|
||||
protocolid = provider_data.get('protocolid')
|
||||
if not provider_orgid or not protocolid:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': '供应商同步失败, 未返回provider_orgid或protocolid, %s' % provider_name
|
||||
}
|
||||
|
||||
product_ns = {
|
||||
'providerid': provider_orgid,
|
||||
'providerpid': item.get('id'),
|
||||
'protocolid': protocolid,
|
||||
'name': item.get('name'),
|
||||
'product_code': item.get('model'),
|
||||
'reseller_orgid': sync_orgid,
|
||||
'label': item.get('catelogname') or category_list.get('catelogname'),
|
||||
'classify': 'A',
|
||||
'ptype': '21',
|
||||
'unit': 'hour',
|
||||
'discount': '1',
|
||||
'product_area': '北京'
|
||||
}
|
||||
product_res = await path_call('../product/productAdd.dspy', product_ns)
|
||||
if not product_res.get('status'):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': '产品同步失败, %s, %s' % (item.get('name'), product_res.get('msg'))
|
||||
}
|
||||
sync_products_count += 1
|
||||
|
||||
# 查找数据库中是否已经存在,不存在就插入
|
||||
exist_llm = await sor.R('llm', {'model': item.get('model')})
|
||||
if exist_llm:
|
||||
# 更新
|
||||
exits_id = exist_llm[0].get('id')
|
||||
await sor.U('llm', {'id': exits_id}, item)
|
||||
continue
|
||||
|
||||
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',
|
||||
'ownerid': item.get('ownerid'),
|
||||
'enabled_date': item.get('enabled_date'),
|
||||
'expired_date': item.get('expired_date'),
|
||||
'query_apiname': item.get('query_apiname') or '',
|
||||
'min_balance': item.get('min_balance'),
|
||||
'status': item.get('status'),
|
||||
'catelogname': item.get('catelogname'),
|
||||
'catelog_id': item.get('catelog_id'),
|
||||
'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')
|
||||
}
|
||||
new_llms_count += 1
|
||||
new_llms_list.append(new_llms.get('model'))
|
||||
@ -63,7 +150,7 @@ async def sync_model_to_llm(ns={}):
|
||||
|
||||
return {
|
||||
'status': True,
|
||||
'msg': f"sync_llm_list同步模型成功,共插入{new_llms_count}个模型,模型列表: {new_llms_list}"
|
||||
'msg': f"sync_llm_list同步模型成功,共同步{sync_products_count}个产品,共插入{new_llms_count}个模型,模型列表: {new_llms_list}"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
|
||||
145
b/llm.sql
Normal file
145
b/llm.sql
Normal file
@ -0,0 +1,145 @@
|
||||
# 创建表格命令
|
||||
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"
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -82,14 +82,6 @@ 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 ''
|
||||
@ -101,8 +93,33 @@ 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')
|
||||
@ -115,7 +132,13 @@ async def providerAdd(ns={}):
|
||||
await openProviderAccounts(sor, orgid, ns_org['id'])
|
||||
return {
|
||||
"status": True,
|
||||
"msg": "provider add success"
|
||||
"msg": "provider add success",
|
||||
"data": {
|
||||
"orgid": ns_org['id'],
|
||||
"provider_orgid": ns_org['id'],
|
||||
"provider_id": ns_provider['id'],
|
||||
"protocolid": ns_sale_mode['id']
|
||||
}
|
||||
}
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user