Compare commits

..

No commits in common. "main" and "fix/dark-mode-bg" have entirely different histories.

175 changed files with 902 additions and 12785 deletions

74
.gitignore vendored
View File

@ -1,38 +1,42 @@
# Generated i18n files — run merge_i18n.py to regenerate # Python
wwwroot/i18n/zh/
wwwroot/i18n/en/
wwwroot/i18n/jp/
wwwroot/i18n/ko/
py3/
app/__pycache__/
logs/
*.pyc
__pycache__/ __pycache__/
conf/config.json *.py[cod]
*.egg-info/
dist/
build/
# Virtual environment
py3/
# Logs
logs/
# PID files
*.pid
# Generated files
*.pem
*.key
merchant_*.pem
alipay_*.pem
pay_*.pem
# Database
models/mysql.ddl.sql
# pkgs (submodules should be in their own repos)
pkgs/
# wwwroot (linked from module repos)
wwwroot/
# Migration scripts (run once, not needed in repo)
migrate_*.py
reset_*.py
check_*.py
set_*.sh
setup_*.sh
# Sage runtime
sage.pid sage.pid
sage_backend.pid sage_backend.pid
start.sh
stop.sh
wwwroot/bricks
wwwroot/bugfix
wwwroot/pricing
wwwroot/supplychain
# Module wwwroot symlinks (managed by build.sh, not tracked in git)
wwwroot/accounting
wwwroot/appbase
wwwroot/charge
wwwroot/cpcc
wwwroot/dapi
wwwroot/dashboard_for_sage
wwwroot/discount
wwwroot/filemgr
wwwroot/llmage
wwwroot/msp
wwwroot/platformbiz
wwwroot/product_management
wwwroot/rag
wwwroot/rbac
wwwroot/uapi
wwwroot/unipay

View File

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCJHRwndZ5KgGu2
I5Q3/SkcDrdq59UOeWy5F0rz0GVujfz2/pWNqNcym+IDyrUoxFiYcYbqsu3IKeBU
PXIy4WIhjP++qnd+tKQvOUltxtC21Wpxh60HwFxqUnecC/szgSQEHGJOnHwAH0xX
tBf0MbtlOWxefeHYrVIb3nK9FYRzK0b7g/n35QZ8TYlKVLUhoBakqFQfTmQQFwoT
hu/1WiTwt+E8Gkixd83bMVl4Y6YXbyslIXcuG3WA43FnylgkutvbbkO8NpoZzwIr
Px8wD3wgxUqpuqbfOjXeHvPyInUzGKtuRxYNmW+b1+0ERKTSNsMm50T+Jehq6gK2
qGT1k5ydAgMBAAECggEABkxPrRb/qge+FYQK3IuEu4+IKKFKLbuxcnW5xqXtktIe
KtuaKQNMEedhJAVypChosrqRlO7vxyr37UapRoxdwpFvHztF+Tb497ECSMhCHAkv
i37M7uHiHNbO5wcR3IAeabtCtL5cCnFlmKhiv/UXg4MgvDJnZlmHv6n3IUJUxClz
3Cxnbt3C66Vbl1ES9vtu9obbMm3W3oFGH+7zJItVQyWa4uYBnAyOICTncT5tMR9k
gWuXITrt/cB9+PAJa7NZsPORPxHygV4bbo+7OH6sBLh1c+Rcm3oSNyejkzRaKFO2
tWUcsyFvIUd/h61BMG123mBWT4XgPo0pTCBkfPohDQKBgQC4fNRz6DSjT3OgF9+7
fLhU+58ED+UtMWKBbKx+PZZfaumxWf8ZbKeLanrnxkCWIr7aVyVl567gq5I5lvN3
jSIDM9A/hgJqFJ8wJ0sW8Q2Fv+loLxANgf8XboSpcy8uADPO7r83D/UhuseHy42L
vQ0ex8WoH0V39PeqBHqcjbZMAwKBgQC+Qz+PFLfcWfvoLQr2aGhe4AQmFSmM5szb
xntkEcD0Dj/34kHOdbKfTThOwo+X8gf3nPcA2WWz3ytQPhZQueNHsR6qcJwzI9WU
yULwnS9Ukdu6bHO74D+1ehM2jZVc2s2V58b2hr5yNz3Z/tlv9txttESBhyCi4bcO
zLzhxeUi3wKBgQCN0sDMHc0hYnnDr7a5/eYCxrB2wfVvKZDNaAquvY+06I6gXUwD
cojWX1P+i2SpRiqr1OSWE2ZXpu2xQf8Gf8OO7K0BuHZwsEu0C/DowQShNmgrREq1
56J/k+F+FmNFnLg3M0hh/u12MY0kMnIs43eLmw2y8d9ImVQvKmRLp5FlmwKBgEiD
tOvBh7nSCfKZiD4V2QGf+7TQCAANzzJMWabwJUxfSf4eG9qmfSe99KIAAV51/pdf
Gb0XHm4JtqZko3itAHTIitmHBeFv3O1SL9Mo9WsUFFzfDNUkSOPP3RbDq5OySPzD
U8+N13QMneRB/3lu6uBc/mcnq0apJG3dlneuRwCdAoGAYZsNbg84qE5o9Jy9dZG8
mTSoS7H/hFZR0XFx3ur6YIBVQ5Ajr//jJinItxMuqV/TEeMdMBJ9DrN+osgPahmq
KNzovtG8spGMbssXY6yMQtM0RPeI+/16TZiWcScnkYQ7QfkwWBRbvQgjUhE6E5Sn
v+Sp46nTaBhBn6iKNVJrhhE=
-----END PRIVATE KEY-----

View File

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmBNz4GpYlwpIy
7uhXTYpCy125vcGltsMjDr7xNehDSkwrQZYOfHoCALE8o1hTEeAXaZN/wls6AEUT
o4i2KB+g3EXDNtm298zydpaWyh8HDhLkzsPeVxT2t2BE6vsusa5/IeQWmnjfU4Un
erSee+EHkrimzAkCLezynOeR69hobkZzhFfPvDm3ur79wJcttRmwbeF0fM6Nvsx2
CY5f1g9ZQb5UY0tfsN7qNFR/Hm6f5Du4nIAt7CwVUheCrjvvh8dByNJBpmSJfqOI
BipzbBDWTQm0s8+d29noUU/rMRAwBfAToG73nCpJoiFLlvw+DCjR4y/FtE5wgHXm
a1wCl1MdAgMBAAECggEAHfpe1EYouqTJtXzCY5FS2ADU6cdEAmJgFiKBhBjR2eS+
oEj1iaQce+QYHPT56/YcWt3rjnRP+Mc3sfYjp5DTNT7RMhDje1B/p4CWbKAOvj1i
WAKmB6390RcHwSoVNTdMZRR/lT1LejggoSJdHwkLd0ydHzFUpxoX4S9H+Wd26lRE
UiMDZuytWdJaW+xDdHTLrgO7m2bgp7qA1QAekEodsMDSorPgw8sNx7o5v0ZruYZi
SXKx6V1zhjFtTcWjCQgV51+4h6NQdjkG5aEyrrdV1hl7uqJMFRHt5EkczD9y/m7g
jdmufhD0TLYbubSop3tBy68S9c6Hat6LTEFJsnwogQKBgQDoi6sGQPI/+tUbNFFH
n0XqbYhOZKD8J3sTW3Qtmo0rAZgtHVtzpgSs2+X836Qit5RghQA+GPX4lwbBoG3h
MjOjxET6YEk15pnzeiqQrPhxJgNSc05DigQTjQg7OgtP8AELvQc63kuJ97A3Ivol
KMEmqWI0VVybCrsDgXssaCAb8QKBgQC2w3owPrQT0ORWgmFDVwyquPrpkVdBk+1w
sE29hban9/3ykmVDgYS0Iyji0VvcBmD+SxUGavyVzKuRbxo4anOdjZMTH8yLaCZ4
RWiCMpIoM9QrB89my++X14V0n+wucvHromTYYdbewku5ReUV0Ivr/HDquCx+4vtD
3fAv3i3F7QKBgQCYPJdCCNKOwA8zOBTd5o9G4V4StB4P9WjFS2HLWRqBxRFyt31f
QJhe8bamzWIOuFASv/9gp8afb3+k0vocK1lTJPJjVxWWi9jNZHTpMdOTf2c9Wu8p
l/kDM5jn7R/qvRxyKtXI3C5nrBdYgTVxjjSkss7vo9J0TZoQuXuBnskmgQKBgFa0
J9yJcr7P4/OSiPf8bRr1BLwX4nBO8F78lPTrYXsQMF6KyxWadU1MPNJWBiE8uXkK
P6A60zdx0Jb/QU4wWkcNag+xj0U3lMCMFQdnXGVMKUR8wQ0AhNrhOQPZ9p8WkuR5
tyPcTqaBQJFVsleGB0teCGeiFiHgJtnMiWz8F3UFAoGAQCHHLm5UY0KR71eSiF/Z
RjcfuEy1KIi8IN2QGRWoonghWdtZiGhx/PeieaOVLs9XMR1uX+mLG1G9lKSVNdxs
S+y7engCTTS4JbkWN5Hv+LoXKv0y8As9e3ddk+OEO5iiW1ZyTyhrFCek2Xl8dSbq
aWHluS2LQFVNlDX5I1lTeuI=
-----END PRIVATE KEY-----

View File

@ -1,5 +1,6 @@
from ahserver.serverenv import ServerEnv from ahserver.serverenv import ServerEnv
from sqlor.dbpools import DBPools from sqlor.dbpools import DBPools
from alisms import AliSMS
def PopError(title='Error', message='Error happened'): def PopError(title='Error', message='Error happened'):
return { return {
@ -48,7 +49,9 @@ async def get_llminstances_by_modeltype(mtid):
def set_globalvariable(): def set_globalvariable():
sms_engine = sms = AliSMS('LTAI5t5w7xsZgueod6uZ3TCD', 'n1HttSbQvgEbjvf62Gzl1aagfKyIyS')
g = ServerEnv() g = ServerEnv()
g.sms_engine = sms_engine
g.PopError = PopError g.PopError = PopError
g.PopMessage = PopMessage g.PopMessage = PopMessage
g.get_llm_types = get_llm_types g.get_llm_types = get_llm_types

View File

@ -1,5 +1,6 @@
import os, sys import os, sys
import json import json
import asyncio
import argparse import argparse
from appPublic.log import MyLogger, info, debug, warning from appPublic.log import MyLogger, info, debug, warning
from appPublic.folderUtils import ProgramPath from appPublic.folderUtils import ProgramPath
@ -10,7 +11,7 @@ from bricks_for_python.init import load_pybricks
from ahserver.webapp import webapp from ahserver.webapp import webapp
from ahserver.serverenv import ServerEnv from ahserver.serverenv import ServerEnv
from ahserver.configuredServer import add_cleanupctx from ahserver.configuredServer import add_cleanupctx
from rbac.init import load_rbac from rbac.init import load_rbac, start_cache_sync
from pricing.init import load_pricing from pricing.init import load_pricing
from appbase.init import load_appbase from appbase.init import load_appbase
from llmage.init import load_llmage from llmage.init import load_llmage
@ -20,19 +21,17 @@ from dapi.init import load_dapi
from rag.init import load_rag from rag.init import load_rag
from msp.init import load_msp from msp.init import load_msp
from checklang.init import load_checklang from checklang.init import load_checklang
# from dashboard_for_sage.init import load_dashboard_for_sage
from reallife_asset.init import load_reallife_asset
from discount.init import load_discount from discount.init import load_discount
from harnessed_agent.init import load_harnessed_agent
from harnessed_reasoning.init import load_harnessed_reasoning
from hermes_web_cli.init import load_hermes_web_cli
from dashboard_for_sage.init import load_dashboard_for_sage
from global_func import set_globalvariable from global_func import set_globalvariable
from unipay.init import load_unipay from unipay.init import load_unipay
from platformbiz.init import load_platformbiz
from product_management.init import load_product_management from product_management.init import load_product_management
from supplychain.init import load_supplychain
from accounting.init import load_accounting from accounting.init import load_accounting
from bugfix.init import load_bugfix
from discount.init import load_discount
from tenant.init import load_tenant
from smssend import load_smssend from smssend import load_smssend
from sage_datamart import load_sage_datamart
from ext import * from ext import *
from rf import * from rf import *
__version__ = '0.0.1' __version__ = '0.0.1'
@ -43,10 +42,11 @@ def init():
load_pybricks() load_pybricks()
load_appbase() load_appbase()
load_rbac() load_rbac()
asyncio.create_task(start_cache_sync())
load_accounting() load_accounting()
load_unipay() load_unipay()
load_platformbiz()
load_product_management() load_product_management()
load_supplychain()
load_filemgr() load_filemgr()
load_llmage() load_llmage()
load_uapi() load_uapi()
@ -55,15 +55,13 @@ def init():
load_rag() load_rag()
load_pricing() load_pricing()
load_checklang() load_checklang()
# load_harnessed_agent() load_harnessed_agent()
# load_harnessed_reasoning() load_harnessed_reasoning()
load_discount() load_discount()
load_tenant() load_hermes_web_cli()
load_smssend() load_smssend()
# load_dashboard_for_sage() load_dashboard_for_sage()
load_reallife_asset()
load_bugfix()
load_sage_datamart()
if __name__ == '__main__': if __name__ == '__main__':
webapp(init) webapp(init)

View File

@ -1,27 +0,0 @@
#!/bin/bash
# Sage 冷备配置 — 修改 STANDBY_IP 后即可使用
# 生成时间: 2026-07-04
# ===== 主机(当前生产) =====
PRIMARY_IP="192.168.16.2"
PRIMARY_DB_PORT=3306
PRIMARY_SAGE_DIR="/d/ymq/repos/sage"
PRIMARY_FILES_DIR="${PRIMARY_SAGE_DIR}/files"
# ===== 备机(必填!) =====
STANDBY_IP="" # <-- 改成你的备机 IP
STANDBY_SSH_USER="root"
STANDBY_SSH_PORT=22
STANDBY_SAGE_DIR="/d/ymq/repos/sage"
STANDBY_FILES_DIR="${STANDBY_SAGE_DIR}/files"
# ===== 数据库复制账号 =====
REPL_USER="repl"
REPL_PASSWORD="Repl...n
# ===== lsyncd =====
LSYNCD_CONF="/etc/lsyncd/lsyncd.conf.lua"
LSYNCD_LOG="/var/log/lsyncd.log"
# ===== 健康检查 =====
HEALTH_CHECK_INTERVAL=10
MAX_FAIL_COUNT=3

View File

@ -1,13 +1,18 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
独立运行的产品后台计费程序 独立运行的LLM后台计费程序
产品记账已从 llmage 迁移到 product_management 模块 sage.py llmage 模块中提取避免多进程模式下重复运行
""" """
import os import os
import sys import sys
import asyncio import asyncio
import signal import signal
# 切换到 Sage 工作目录
os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'py3', 'lib', 'python3.10', 'site-packages'))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'pkgs'))
from appPublic.folderUtils import ProgramPath from appPublic.folderUtils import ProgramPath
from appPublic.jsonConfig import getConfig from appPublic.jsonConfig import getConfig
from sqlor.dbpools import DBPools from sqlor.dbpools import DBPools
@ -20,16 +25,20 @@ from llmage.init import load_llmage
from pricing.init import load_pricing from pricing.init import load_pricing
from discount.init import load_discount from discount.init import load_discount
from dapi.init import load_dapi from dapi.init import load_dapi
from product_management import get_manager
# 初始化配置
p = ProgramPath()
config = getConfig(NS={'workdir': os.getcwd(), 'ProgramPath': p})
DBPools(config.databases)
# 导入 llmage 的计费函数
from llmage.accounting import (
backend_accounting
)
def get_module_dbname(m): def get_module_dbname(m):
return 'sage' return 'sage'
def main(): def main():
# 初始化配置
p = ProgramPath()
config = getConfig(NS={'workdir': os.getcwd(), 'ProgramPath': p})
db = DBPools(config.databases)
logger = MyLogger('backend_accounting', levelname='info', logger = MyLogger('backend_accounting', levelname='info',
logfile=os.path.join(os.getcwd(), 'logs', 'backend_accounting.log')) logfile=os.path.join(os.getcwd(), 'logs', 'backend_accounting.log'))
info(f'Backend accounting process started (PID: {os.getpid()})') info(f'Backend accounting process started (PID: {os.getpid()})')
@ -48,20 +57,13 @@ def main():
initEnv() initEnv()
env = ServerEnv() env = ServerEnv()
env.get_module_dbname = get_module_dbname env.get_module_dbname = get_module_dbname
# Mock event_dispatcher for standalone mode
class _MockDispatcher:
def bind(self, *a, **kw): pass
env.event_dispatcher = _MockDispatcher()
load_appbase() load_appbase()
load_accounting() load_accounting()
load_pricing() load_pricing()
load_discount() load_discount()
load_dapi() load_dapi()
load_llmage()
manager = get_manager()
try: try:
loop.run_until_complete(manager.backend_accounting()) loop.run_until_complete(backend_accounting())
except asyncio.CancelledError: except asyncio.CancelledError:
pass pass
finally: finally:

View File

@ -1,304 +0,0 @@
#!/bin/bash
# ============================================================
# backup_api.sh
# 自动从 conf/config.json 读取数据库配置,扫描所有模块的
# models 目录提取表名,导出为 SQL 文件。
#
# 运行目录: sage.py 所在目录 (即 repos/sage/)
#
# 用法:
# cd /path/to/sage && bash bin/backup_api.sh [options]
#
# 选项:
# -p PASSWORD 直接指定密码 (覆盖config.json中的加密密码)
# -h HOST 覆盖数据库主机
# -o OUTPUT_DIR 输出目录 (默认: ./sql_dumps)
# --no-data 只导出表结构,不导出数据
# --help 显示帮助
# ============================================================
set -euo pipefail
# --- 定位工作目录 (sage.py 所在目录) ---
SAGE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
REPOS_DIR="$(cd "$SAGE_DIR/.." && pwd)"
CONFIG_FILE="$SAGE_DIR/conf/config.json"
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "错误: 找不到配置文件 $CONFIG_FILE"
echo "请在 sage.py 所在目录下运行此脚本"
exit 1
fi
# 默认参数
OUTPUT_DIR="./sql_dumps"
NO_DATA=""
PASSWORD_OVERRIDE=""
HOST_OVERRIDE=""
usage() {
sed -n '2,/^# ===/p' "$0" | grep '^#' | sed 's/^# \?//'
exit 0
}
# 解析参数
while [[ $# -gt 0 ]]; do
case "$1" in
-p) PASSWORD_OVERRIDE="$2"; shift 2 ;;
-h) HOST_OVERRIDE="$2"; shift 2 ;;
-o) OUTPUT_DIR="$2"; shift 2 ;;
--no-data) NO_DATA="--no-data"; shift ;;
--help) usage ;;
*) echo "未知参数: $1"; exit 1 ;;
esac
done
# --- 从 config.json 提取数据库配置并解密密码 ---
read_config() {
# Use the sage venv if available, otherwise system python
local PYTHON="python3"
if [[ -x "$SAGE_DIR/py3/bin/python3" ]]; then
PYTHON="$SAGE_DIR/py3/bin/python3"
fi
$PYTHON -c "
import re, json, sys, os
# 读取并修复 config.json (可能有非标准 JSON)
text = open('$CONFIG_FILE').read()
# 移除无 key 的裸对象 (如 hot_reload)
text = re.sub(r',\s*\{[^{}]*\"hot_reload\"[^{}]*\{[^{}]*\}[^{}]*\}', '', text)
config = json.loads(text)
# 获取数据库配置 (取第一个数据库)
db_name = list(config['databases'].keys())[0]
db_cfg = config['databases'][db_name]['kwargs']
password_key = config.get('password_key', 'QRIVSRHrthhwyjy176556332')
# 尝试 RC4 解密
try:
from appPublic.rc4 import unpassword
decrypted = unpassword(db_cfg['password'], key=password_key)
except ImportError:
# Fallback: inline RC4 implementation
import base64
from hashlib import sha1
class RC4:
def __init__(self):
self.bcoding = 'iso-8859-1'
self.dcoding = 'utf8'
self.salt = b'AFUqx9WZuI32lnHk'
def _crypt(self, data, key):
x = 0; box = list(range(256))
for i in range(256):
x = (x + box[i] + key[i % len(key)]) % 256
box[i], box[x] = box[x], box[i]
x = y = 0; out = []
for char in data:
x = (x + 1) % 256; y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
out.append(chr(char ^ box[(box[x] + box[y]) % 256]))
return ''.join(out).encode(self.bcoding)
def decode(self, data, key):
if isinstance(data, str): data = data.encode(self.dcoding)
key = key.encode(self.bcoding)
data = base64.b64decode(data)
a = sha1(key + self.salt); k = a.digest()
return self._crypt(data[16:], k).decode(self.dcoding)
rc4 = RC4()
decrypted = rc4.decode(db_cfg['password'], password_key)
except Exception as e:
decrypted = ''
# 如果解密失败或为空,使用原始值
if not decrypted:
decrypted = db_cfg['password']
host = '$HOST_OVERRIDE' if '$HOST_OVERRIDE' else db_cfg.get('host', 'localhost')
port = str(db_cfg.get('port', '3306'))
user = db_cfg.get('user', 'root')
database = db_cfg.get('db', 'sage')
# Shell-safe output
print(f'HOST={host}')
print(f'PORT={port}')
print(f'USER={user}')
print(f'DATABASE={database}')
# Password needs quoting for special chars
print(f\"PASSWORD='{decrypted}'\")
"
}
echo "正在读取配置..."
eval "$(read_config)"
# 命令行密码覆盖
if [[ -n "$PASSWORD_OVERRIDE" ]]; then
PASSWORD="$PASSWORD_OVERRIDE"
fi
if [[ -z "$PASSWORD" ]]; then
echo "错误: 密码为空。请使用 -p 参数指定密码,或检查 config.json 中的密码配置"
exit 1
fi
# 构建 mysqldump 基础命令 (密码通过环境变量传递,避免命令行暴露)
export MYSQL_PWD="$PASSWORD"
MYSQLDUMP_CMD="mysqldump -h${HOST} -P${PORT} -u${USER}"
# --- 各模块排除的表 (大数据量/日志表) ---
declare -A MODULE_EXCLUDES
MODULE_EXCLUDES["llmage"]="llmusage llmusage_accounting_failed llmusage_history"
MODULE_EXCLUDES["uapi"]="uapiset uptask"
MODULE_EXCLUDES["accounting"]="accountingdetail accountinghistory"
MODULE_EXCLUDES["harnessed_agent"]="harnessed_agent_log"
MODULE_EXCLUDES["harnessed_reasoning"]="harnessed_reasoning_log"
# --- 从 models/*.json 提取表名 ---
get_tables() {
local module_dir="$1"
shift
local excludes=("$@")
local tables=()
if [[ ! -d "$module_dir/models" ]]; then
return
fi
for f in "$module_dir/models"/*.json; do
[[ -f "$f" ]] || continue
local tbl
tbl=$(python3 -c "
import json, sys
try:
d = json.load(open('$f'))
s = d.get('summary', [])
if isinstance(s, list) and len(s) > 0:
print(s[0].get('name', ''))
elif isinstance(s, dict):
print(s.get('name', ''))
except:
pass
" 2>/dev/null)
if [[ -z "$tbl" ]]; then
continue
fi
# 检查排除
local excluded=false
for ex in "${excludes[@]+"${excludes[@]}"}"; do
if [[ "$tbl" == "$ex" ]]; then
excluded=true
break
fi
done
if [[ "$excluded" == "false" ]]; then
tables+=("$tbl")
fi
done
echo "${tables[@]}"
}
# --- 自动发现所有模块 ---
discover_modules() {
for dir in "$REPOS_DIR"/*/; do
[[ -d "$dir/models" ]] || continue
local name
name=$(basename "$dir")
# 跳过无模型文件的模块
if ls "$dir/models/"*.json &>/dev/null; then
echo "$name"
fi
done
}
# --- 创建输出目录 ---
mkdir -p "$OUTPUT_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
echo "============================================================"
echo " Sage 全模块表数据导出"
echo " 时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo " 数据库: ${DATABASE}@${HOST}:${PORT}"
echo " 用户: ${USER}"
echo " 模块目录: ${REPOS_DIR}"
echo " 输出目录: ${OUTPUT_DIR}"
echo "============================================================"
# 发现所有模块
MODULES=($(discover_modules))
echo ""
echo "发现 ${#MODULES[@]} 个模块: ${MODULES[*]}"
TOTAL_TABLES=0
TOTAL_FILES=0
FAILED_MODULES=()
for module in "${MODULES[@]}"; do
module_dir="$REPOS_DIR/$module"
echo ""
echo "--- 模块: $module ---"
# 获取排除列表
excludes_str="${MODULE_EXCLUDES[$module]:-}"
excludes_arr=()
if [[ -n "$excludes_str" ]]; then
read -ra excludes_arr <<< "$excludes_str"
fi
tables=$(get_tables "$module_dir" "${excludes_arr[@]+"${excludes_arr[@]}"}")
if [[ -z "$tables" ]]; then
echo " 跳过: 未找到表定义"
continue
fi
echo " 表: $tables"
# 生成 SQL 文件
outfile="${OUTPUT_DIR}/${module}_${TIMESTAMP}.sql"
table_count=0
for tbl in $tables; do
echo -n " 导出 $tbl ... "
if ${MYSQLDUMP_CMD} \
--single-transaction \
--routines \
--triggers \
--set-gtid-purged=OFF \
--column-names \
--complete-insert \
$NO_DATA \
"$DATABASE" "$tbl" >> "$outfile" 2>/dev/null; then
echo "OK"
((table_count++))
else
echo "跳过(表不存在或无权限)"
fi
done
if [[ $table_count -gt 0 ]]; then
echo " => $outfile ($table_count 个表)"
((TOTAL_TABLES += table_count))
((TOTAL_FILES++))
else
rm -f "$outfile"
echo " => 无有效表数据"
FAILED_MODULES+=("$module")
fi
done
# 清理密码环境变量
unset MYSQL_PWD
echo ""
echo "============================================================"
echo " 导出完成"
echo " 模块数: ${#MODULES[@]}"
echo " 文件数: $TOTAL_FILES"
echo " 表总数: $TOTAL_TABLES"
if [[ ${#FAILED_MODULES[@]} -gt 0 ]]; then
echo " 无数据模块: ${FAILED_MODULES[*]}"
fi
echo " 输出目录: $(cd "$OUTPUT_DIR" && pwd)"
echo "============================================================"

View File

@ -26,21 +26,18 @@ do
cd $m cd $m
$cdir/py3/bin/pip install . $cdir/py3/bin/pip install .
done done
for m in appbase rbac accounting llmage msp cpcc unipay filemgr dapi uapi rag charge pricing discount harnessed_agent harnessed_reasoning sage_datamart product_management supplychain reallife_asset bugfix for m in appbase rbac accounting llmage platformbiz msp cpcc unipay filemgr dapi uapi rag charge pricing discount harnessed_agent harnessed_reasoning dashboard_for_sage product_management
do do
echo "install $m module..." echo "install $m module..."
cd $cdir/pkgs cd $cdir/pkgs
if [ ! -d "$cdir/pkgs/$m" ];then git clone https://git.opencomputing.cn/yumoqing/$m
git clone https://git.opencomputing.cn/yumoqing/$m cd $m
cd $cdir/pkgs/$m
if [ -d $cdir/pkgs/$m/models ];then
cd $cdir/pkgs/$m/models
xls2ddl mysql . > mysql.ddl.sql
mysql -h db -utest -ptest123 sage < mysql.ddl.sql
fi
fi
cd $cdir/pkgs/$m
$cdir/py3/bin/pip install . $cdir/py3/bin/pip install .
if [ -d $cdir/pkgs/$m/models ];then
cd $cdir/pkgs/$m/models
xls2ddl mysql . > mysql.ddl.sql
mysql -h db -utest -ptest123 sage < mysql.ddl.sql
fi
if [ -d $cdir/pkgs/$m/json ];then if [ -d $cdir/pkgs/$m/json ];then
cd $cdir/pkgs/$m/json cd $cdir/pkgs/$m/json
./build.sh ./build.sh
@ -94,40 +91,3 @@ if ! echo "$cc"|grep -Fq "$new_cron"; then
else else
echo "任务已存在,未重复添加。" echo "任务已存在,未重复添加。"
fi fi
# 每日 8:00 抓取外汇牌价
forex_cron="0 8 * * * curl -s http://localhost:9180/accounting/api/fetch_forex_rates.dspy"
if ! echo "$cc"|grep -Fq "fetch_forex_rates"; then
(echo "$cc";echo "$forex_cron") | crontab -
else
echo "汇率任务已存在,未重复添加。"
fi
# sage_datamart ETL crontab
cc=$(crontab -l 2>/dev/null)
# 每5分钟增量同步 llmusage → dm_model_call_fact
dm_sync_cron="*/5 * * * * curl -s http://localhost:9180/sage_datamart/cron/etl_sync.dspy"
if ! echo "$cc"|grep -Fq "etl_sync"; then
(echo "$cc";echo "$dm_sync_cron") | crontab -
cc=$(crontab -l 2>/dev/null)
else
echo "datamart sync任务已存在未重复添加。"
fi
# 每小时聚合 dm_model_perf_daily
dm_agg_cron="15 * * * * curl -s http://localhost:9180/sage_datamart/cron/etl_aggregate.dspy"
if ! echo "$cc"|grep -Fq "etl_aggregate"; then
(echo "$cc";echo "$dm_agg_cron") | crontab -
cc=$(crontab -l 2>/dev/null)
else
echo "datamart aggregate任务已存在未重复添加。"
fi
# 每天 02:00 聚合供应商性价比
dm_prov_cron="0 2 * * * curl -s http://localhost:9180/sage_datamart/cron/etl_provider_cost.dspy"
if ! echo "$cc"|grep -Fq "etl_provider_cost"; then
(echo "$cc";echo "$dm_prov_cron") | crontab -
else
echo "datamart provider_cost任务已存在未重复添加。"
fi

View File

@ -1,19 +0,0 @@
import asyncio
from sqlor.dbpools import DBPools
from appPublic.jsonConfig import getConfig
async def main():
config = getConfig('.')
db = DBPools(config.databases)
async with db.sqlorContext('sage') as sor:
perms = await sor.sqlExe(
"select p.path from permission p inner join rolepermission rp on p.id=rp.permid where rp.roleid='any' and p.path like ${path}$",
{'path': '/bricks/%'}
)
print(f'Found {len(perms)} bricks paths with any role:')
for p in perms[:15]:
print(f' {p.path}')
if len(perms) > 15:
print(f' ... and {len(perms)-15} more')
asyncio.get_event_loop().run_until_complete(main())

119
conf/config.json Executable file
View File

@ -0,0 +1,119 @@
{
"password_key":"!@#$%^&*(*&^%$QWERTYUIqwertyui234567",
"logopath": "$[workdir]$/conf/logo.png",
"tpacs":{
"cnprod":{
"get_tpac_balance_url": "https://www.opencomputing.cn/cntoai/get_user_balance.dspy",
"tpac_accounting_url": "https://www.opencomputing.cn/cntoai/process_user_billing.dspy"
},
"ncmatchdemo":{
"get_tpac_balance_url": "https://www.ncmatch.cn/cntoai/get_user_balance.dspy",
"tpac_accounting_url": "https://www.ncmatch.cn/cntoai/process_user_billing.dspy"
},
"cndemo": {
"get_tpac_balance_url": "https://dev.opencomputing.cn/cntoai/get_user_balance.dspy",
"tpac_accounting_url": "https://dev.opencomputing.cn/cntoai/process_user_billing.dspy"
}
},
"woa_handler_id":"woa_subscribe_type",
"logger":{
"name":"sage",
"levelname":"clientinfo",
"logfile":"$[workdir]$/logs/sage.log"
},
"pay":{
"alipay":{
"public_key_file":"$[workdir]$/conf/alipay/public.txt",
"private_key_file":"$[workdir]$/conf/alipay/private.txt",
"appid":"2021005111636494",
"callback":"https://sage.opencomputing.cn/api/callback/alipay"
},
"paypal":{
"mode":"sandbox",
"client_id":"myid",
"client_secret":"mysecret",
"return_url":"ret_url",
"cancel_url":"cancel_url"
}
},
"skills_path": "$[workdir]$/skills",
"filesroot":"$[workdir]$/files",
"databases":{
"sage":{
"driver":"mysql",
"kwargs":{
"user":"test",
"db":"sage",
"password":"SS+C1MDMJrslBwGzYIv3nQ==",
"charset": "utf8mb4",
"host":"db"
}
}
},
"zmq_url": "tcp://127.0.0.1:5555",
"website":{
"paths":[
["$[workdir]$/wwwroot",""]
],
"client_max_size":1000000000,
"host":"0.0.0.0",
"port":9080,
"coding":"utf-8",
"ssl_gg":{
"crtfile":"$[workdir]$/conf/www.bsppo.com.pem",
"keyfile":"$[workdir]$/conf/www.bsppo.com.key"
},
"indexes":[
"index.html",
"index.tmpl",
"index.ui",
"index.dspy",
"index.md"
],
"startswiths":[
{
"leading":"/idfile",
"registerfunction":"idfile"
},{
"leading":"/i18n_getmsgs",
"registerfunction":"i18n"
}
],
"processors":[
[".ws","ws"],
[".wss","ws"],
[".xterm","xterm"],
[".proxy","proxy"],
[".llm", "llm"],
[".llms", "llms"],
[".llma", "llma"],
[".xlsxds","xlsxds"],
[".sqlds","sqlds"],
[".tmpl.js","tmpl"],
[".tmpl.css","tmpl"],
[".html.tmpl","tmpl"],
[".bcrud", "bricks_crud"],
[".tmpl","tmpl"],
[".app","app"],
[".bui","bui"],
[".ui","bui"],
[".dspy","dspy"],
[".md","md"]
],
"rsakey":{
"privatekey":"$[workdir]$/conf/rsa_private_key.pem",
"publickey":"$[workdir]$/conf/rsa_public_key.pem"
},
"session_max_time":3000,
"session_issue_time":2500,
"session_redis":{
"url":"redis://127.0.0.1:6379"
}
},
"langMapping":{
"zh-Hans-CN":"zh-cn",
"zh-CN":"zh-cn",
"en-us":"en",
"en-US":"en"
}
}

Binary file not shown.

View File

@ -1,135 +0,0 @@
# Sage 智能平台 — 市场宣传稿
## 一句话
**Sage让 AI 服务成为可运营、可计费、可编排的商业产品。**
---
## 我们解决了什么问题
AI 时代的企业面临三个核心难题:
1. **模型太多,管理太难** — 通义、DeepSeek、MiniMax、火山方舟……每个供应商 API 不同,接入成本高
2. **计费复杂,算不清账** — 按 token按秒按次不同模型不同定价客户账单一团乱
3. **产线分散,效率低下** — 多个 AI 服务各自为政,无法编排成完整的业务流程
**Sage 用一套平台解决全部问题。**
---
## 核心能力
### ① 统一模型网关 — 一个接口,接入所有 AI
```
OpenAI 兼容 API Sage llmage 网关 上游 AI 服务
───────────────── ───────────────── ─────────────
/v1/chat → → 通义千问
/v1/image → 模型路由 + → 通义万相
/v1/video → 计费 + 权限 → MiniMax
/v1/models → → 火山方舟
/pipeline/submit → → 自建 GPU 服务
```
- **146+ 模型**已接入,文本/图像/视频/语音全覆盖
- **OpenAI 兼容 API**,零代码迁移
- **一行配置**新增模型,无需改代码
### ② 智能计费引擎 — 每一分钱都算得清清楚楚
| 计费方式 | 示例 |
|---------|------|
| 按量计费 | ASR 语音识别0.01元/秒 |
| 按次计费 | 人脸检测0.10元/次 |
| 按时长 | 视频生成0.05元/秒 |
| 套餐/折扣 | 客户专属折扣、分销商差价 |
- 实时余额检查,欠费自动拦截
- 后台自动记账,零人工对账
- 支持多级分销折扣体系
### ③ KTV 产线 — 从一首歌到一部 MV全自动
```
上传音频 → 自动分离人声/伴奏 → AI 生成 28 个场景视频
→ 逐字卡拉OK字幕 → 片头+水印 → 输出 KTV + MTV
```
**全部通过 API 自动化完成**,无需人工介入。
- 内置模型选择流程:客户看到费用预估,自主选择视频模型
- 费用透明:每个子步骤独立计费,总费用一目了然
- 容错机制20% 容错预算,自动重试失败任务
### ④ 完整商业闭环
```
客户注册 → API Key 管理 → 余额充值 → 调用服务 → 自动记账 → 账单导出
```
- 多租户隔离,数据安全
- 分销商/供应商多级管理体系
- 优惠券、折扣、促销活动支持
---
## 谁在用 / 谁能用
| 用户类型 | 使用场景 |
|---------|---------|
| **AI 服务商** | 将自己的 GPU 服务包装为 API 产品,上架销售 |
| **内容创作者** | 一键制作 KTV/MVAI 写词、AI 演唱、AI 视频 |
| **企业 IT** | 统一管理公司所有 AI 服务接入,控制成本 |
| **代理商** | 代理销售 AI 服务,赚取差价佣金 |
| **开发者** | 通过 OpenAI 兼容 API 快速开发 AI 应用 |
---
## 技术亮点
- **异步任务引擎**:长耗时任务自动轮询,不阻塞用户
- **供应商抽象层**:更换底层模型只需改配置,不换代码
- **xls2ddl 建表**Excel 设计数据库,自动生成 DDL + CRUD
- **浏览器测试**CDP 协议自动化端到端测试
- **热更新**:配置修改即时生效,无需重启
---
## 与竞品的差异
| 对比维度 | Sage | 传统 API 网关 | 单一模型平台 |
|---------|------|-------------|------------|
| 模型接入 | 146+ 任意供应商 | 有限 | 自有模型 |
| 计费能力 | 按量/按次/套餐/折扣 | 简单限额 | 固定定价 |
| 产线编排 | 多步骤自动化 | ❌ | ❌ |
| 客户管理 | 多租户+分销 | ❌ | 简单 |
| 部署方式 | 私有化部署 | 云服务 | SaaS |
---
## 案例KTV 产线实测数据
**《女儿国的秋》制作全过程:**
| 步骤 | 服务 | 耗时 | 费用 |
|------|------|------|------|
| 音频分离 | Demucs (full) | 65秒 | 1.31元 |
| 场景生成 | HappyHorse T2V × 28 | ~10分钟 | ~14元 |
| 视频合成 | ffmpeg | 30秒 | — |
| **总计** | | | **~16元** |
产出213MB KTV 视频(双音轨+卡拉OK字幕+ 210MB MTV 视频
---
## 立即开始
```bash
# 一行命令体验 KTV 产线
curl -X POST https://your-sage.com/llmage/v1/pipeline/submit \
-H "Authorization: Bearer YOUR_KEY" \
-d '{"model":"ky-demucs-separate","audio_file":"song.mp3"}'
```
**联系元境团队,获取完整部署方案:元境出品 欢乐随行**

Binary file not shown.

View File

@ -1,208 +0,0 @@
# Sage 智能平台技术白皮书
## 一、平台概述
Sage 是一个面向 AI 时代的智能服务管理平台,集模型网关、计费引擎、产线编排、权限管理于一体,为企业提供从 API 接入到业务结算的全链路基础设施。
**核心理念**:一套平台,统一管理所有 AI 服务的接入、调度、计费和客户关系。
## 二、系统架构
```
┌──────────────────────────────────────────────────────────┐
│ 客户端层 │
│ Web 管理后台 │ API 调用 (OpenAI 兼容) │ CLI Agent │
└──────────────┬───────────────────────────────────────────┘
┌──────────────▼───────────────────────────────────────────┐
│ Sage 平台核心 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ 权限管理 │ │ 模型网关 │ │ 计费引擎 │ │ 产线编排 │ │
│ │ RBAC + │ │ llmage │ │ Pricing │ │ Pipeline │ │
│ │ Session │ │ UAPI │ │ Engine │ │ Orchestrator│ │
│ └──────────┘ └──────────┘ └──────────┘ └────────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ 文件管理 │ │ 知识库 │ │ 营销引擎 │ │ 多语言 │ │
│ │ FileMgr │ │ RAG/KDB │ │ Discount │ │ i18n │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────────┘ │
└──────────────┬───────────────────────────────────────────┘
┌──────────────▼───────────────────────────────────────────┐
│ 基础设施层 │
│ ahserver (异步HTTP) │ sqlor (数据库) │ Redis │ Nginx │
│ Hermes Agent │ 浏览器测试 (CDP) │ SSH 远程调度 │
└──────────────────────────────────────────────────────────┘
```
## 三、核心模块
### 3.1 模型网关 (llmage)
**功能**:统一的 AI 模型接入层,支持 OpenAI 兼容 API。
| 特性 | 说明 |
|------|------|
| 多供应商 | 同时接入通义、MiniMax、火山方舟、Vidu、自建 GPU 等 |
| 协议统一 | 标准 `/v1/chat/completions``/v1/models` 等 OpenAI 兼容接口 |
| 异步任务 | 内置 asyncinference 引擎,支持 submit→poll→result 异步流水线 |
| 数据模板 | Jinja2 模板引擎,灵活适配不同供应商的请求/响应格式 |
| 参数映射 | `_file` 命名规范,自动处理文件 → URL 转换 |
**已接入模型**146+ 模型,涵盖文本对话、文生图、文生视频、语音识别、人脸识别、音频分离、歌曲评分、声音转换、超分辨率等。
### 3.2 计费引擎 (Pricing)
**功能**:灵活的多维度计费系统,支持按量计费、套餐计费、渠道折扣。
| 特性 | 说明 |
|------|------|
| 按量计费 | 支持 audio_seconds、image_count、video_seconds 等多种计价因子 |
| 独立定价 | 每个模型独立 ppid不同服务不同单价 |
| 自动记账 | backend_accounting 后台循环处理,实时结算 |
| 余额管控 | checkCustomerBalance 前置检查,欠费自动阻拦 |
| 定价模板 | YAML 格式定价数据price_factors + unit_prices 灵活配置 |
**定价示例KTV 产线)**
| 服务 | 单价 | 计价因子 |
|------|------|---------|
| 语音识别 | 0.01元/秒 | audio_seconds |
| 音频分离 | 0.02元/秒 | audio_seconds |
| 人脸检测 | 0.10元/次 | detect_count |
| 字幕渲染 | 0.01元/条 | subtitle_count |
| 超分辨率 | 0.50元/张 | image_count |
| 声音转换 | 0.15元/秒 | audio_seconds |
### 3.3 权限管理 (RBAC)
**功能**:基于角色的访问控制,支持 Session 管理、跨进程缓存同步。
| 特性 | 说明 |
|------|------|
| 角色体系 | 支持 admin/logined/anonymous/any 四级默认角色 + 自定义角色 |
| 路径权限 | 每个 DSPY/UI 端点可独立配置访问权限 |
| Session 管理 | Redis 存储,跨进程共享,自动过期 |
| 缓存同步 | 权限变更自动广播所有工作进程 |
| 审计日志 | 完整的访问日志和操作记录 |
### 3.4 产线编排 (Pipeline)
**功能**:将多个 AI 原子服务编排为完整的业务流程。
**KTV 产线示例**14 个 GPU 服务 → llmage API 统一调度):
```
音频准备 → Demucs 分离(人声/伴奏/MIDI) → ASR 语音识别(逐字时间戳)
↓ ↓
人声提取 精准字幕生成
↓ ↓
RVC 变声 卡拉OK渲染
↓ ↓
┌──────────────── 视频合并 ────────────────────┘
输出KTV 视频(双音轨) + MTV 视频 + ASS 字幕
```
**核心特性**
- 全链路通过 llmage API 调度,不直连 GPU
- 异步任务自动轮询
- 自动记账(每个子任务独立计费)
- 费用预估 + 模型选择(客户参与决策)
### 3.5 模型选择与费用预估
产线内置智能模型选择流程:
```
故事板生成 → 模型选择(费用预估) → 视频生成
客户看到:
- 快乐马0.03元/秒,快速经济
- 通义万象 WAN 2.70.05元/秒,高质量 ⭐推荐
- 豆包 Seedance 2.00.08元/秒,旗舰级
客户选择 → 按选择生成
```
**费用预估包含**
- 总视频时长 × 单价 = 基础费用
- 20% 容错系数(重试/失败)
- 其他服务费用明细demucs + ASR + 字幕等)
## 四、技术特性
### 4.1 异步流水线
Sage 的 asyncinference 引擎提供完整的异步任务管理:
```
POST /v1/pipeline/submit → {"taskid":"...","status":"PENDING"}
→ 后台轮询 (每 5s)
→ GET /status?task_id=xxx → {"status":"SUCCEEDED","usage":"..."}
→ 自动更新 llmusage → 触发记账
```
### 4.2 供应商抽象 (UAPI)
通过统一的 UAPI 层实现供应商无关的接口抽象:
```yaml
供应商配置:
ktv-gateway: https://ktv.opencomputing.net:10443
tongyi-wan: https://dashscope.aliyuncs.com
vidu: https://api.vidu.com
端点模板:
demucs-separate: POST /demucs/api/demucs-separate
asr-transcribe: POST /asr/api/asr-transcribe
realesrgan-upscale: POST /realesrgan/api/realesrgan-upscale
```
每个端点通过 Jinja2 模板处理请求/响应转换,实现供应商 API 差异的透明化。
### 4.3 数据库设计规范
- 统一使用 xls2ddl 建表工具
- 字符集标准:`utf8mb4 COLLATE utf8mb4_unicode_ci`
- 支持 emoji、多语言字符
- 自增 ID + UUID 双标识体系
### 4.4 前端框架
- 基于 bricks-mp自研 JSON 驱动 UI 框架)
- 支持 Jinja2 服务端渲染
- 暗色主题、响应式布局
- 浏览器端到端测试CDP 协议)
## 五、部署架构
```
┌─────────────────┐ ┌──────────────────┐
│ tokentest │ │ production │
│ 测试环境 │ │ 生产环境 │
├─────────────────┤ ├──────────────────┤
│ Sage :9180 │ │ Sage :9180 │
│ MariaDB │ │ MariaDB │
│ Redis │ │ Redis │
│ Nginx :443 │ │ Nginx :443 │
└────────┬────────┘ └────────┬─────────┘
│ │
└───────────┬───────────┘
┌──────────▼──────────┐
│ GPU 计算集群 │
│ opencomputing.net │
├─────────────────────┤
│ Demucs :9083 │
│ ASR :9925 │
│ RealESRGAN :9082 │
│ Face :9081 │
│ ... │
└─────────────────────┘
```
## 六、总结
Sage 平台通过统一的模型网关、灵活的计费引擎、完善的权限管理和可编排的产线系统,为企业提供了一站式的 AI 服务商业化平台。无论是简单的 API 代理还是复杂的多步骤 AI 工作流Sage 都能以一致的方式管理和计费。

Binary file not shown.

View File

@ -1,341 +0,0 @@
API: API
API Key管理: API Key Management
Add Error: Add Error
Add Success: Add Success
Cancel: Cancel
Conform: Confirm
DeepSeek: DeepSeek
Delete Error: Delete Error
Delete Success: Delete Success
Discard: Discard
Error: Error
LocalOllama: LocalOllama
Login: Login
Login Error: Login Error
Message: Message
MiniMax: MiniMax
RBAC工具: RBAC Tools
Reset: Reset
Reset Password: Reset Password
Submit: Submit
Token交易记录: Token Transaction Records
Update Error: Update Error
Update Success: Update Success
Welcome back: Welcome back
\u4ea4\u6613\u65e5\u671f: Transaction Date
\u4ea4\u6613\u65f6\u95f4: Transaction Time
\u4f1a\u8bdd\u6587\u4ef6\u540d: Session Filename
\u4f9b\u5e94\u5546id: Supplier ID
\u5176\u4ed6token\u4ef7\u683c: Other Token Price
\u5176\u4ed6tokens\u6d88\u8d39\u6570: Other Tokens Consumed
\u51fd\u6570\u540d: Function Name
\u54cd\u5e94\u65f6\u95f4: Response Time
\u5b8c\u6210\u65f6\u95f4: Completion Time
\u5ba2\u6237id: Customer ID
\u5bc6\u7801: Password
\u624b\u673a: Phone
\u6a21\u578b\u5b9e\u4f8bid: Model Instance ID
\u6a21\u578b\u7c7b\u578bid: Model Type ID
\u7528\u6237\u540d: Username
\u7528\u6237id: User ID
\u8ba1\u6b21\u4ef7\u683c: Per-Call Price
\u8ba1\u6b21\u91d1\u989d: Per-Call Amount
\u8ba1\u8d39\u6a21\u5f0f: Billing Mode
\u8ba1\u8d39token\u6570\u91cf: Billed Token Count
\u8bb0\u8d26\u72b6\u6001: Accounting Status
\u8bc4\u4ef7: Rating
\u8f93\u5165token\u4ef7\u683c: Input Token Price
\u8f93\u5165token\u6d88\u8d39\u6570: Input Tokens Consumed
\u8f93\u5165token\u91d1\u989d: Input Token Amount
\u8f93\u51fatoken\u4ef7\u683c: Output Token Price
\u8f93\u51fatoken\u6d88\u8d39\u6570: Output Tokens Consumed
\u8f93\u51fatoken\u91d1\u989d: Output Token Amount
\u90ae\u4ef6\u5730\u5740: Email Address
\u9644\u5c5e\u5bc6\u94a5: Associated Key
api\u5bc6\u94a5: API Secret
api密码: API Password
api密钥: API Secret
api用户: API User
failed: failed
http程序接口: HTTP Program Interface
id: ID
io数据id: IO Data ID
logout success: Logout Success
minimax账单: MiniMax Bill
minimax账号: MiniMax Account
minimax账号id: MiniMax Account ID
ok: OK
system error: System Error
token使用表: Token Usage Table
token数量: Token Count
token每天统计: Daily Token Statistics
token消耗量Top5: Top 5 Token Consumption
user name or password error: Username or Password Error
user register: User Register
 角色: Role
© 2024 版权所有, 开元云(北京)科技有限公司: © 2024 All Rights Reserved, Kaiyuan Cloud (Beijing) Technology Co., Ltd.
上位系统: Upper System
上位系统管理: Upper System Management
下位系统接口: Lower System Interface
主营业务描述: Main Business Description
主页: Home
交易日期: Transaction Date
交易时间: Transaction Time
产品管理: Product Management
产品类别管理: Product Category Management
产品类型管理: Product Type Management
产品类型规格: Product Type Specifications
代客充值: Agent Recharge
代理: Agent
仪表盘: Dashboard
会计分录配置: Accounting Entry Configuration
会话文件名: Session Filename
余额与充值: Balance and Recharge
使用日期: Usage Date
使用时间: Usage Time
供应协议: Supply Agreement
供应商id: Supplier ID
供应商充值: Supplier Recharge
供应商名: Supplier Name (Short)
供应商名称: Supplier Name
供应商对账: Supplier Reconciliation
供应商明细对账: Supplier Detail Reconciliation
供应商模型列表: Supplier Model List
供应商管理: Supplier Management
供应商结算: Supplier Settlement
供应商财务: Supplier Finance
供应链管理: Supply Chain Management
供销协议管理: Supply and Sales Agreement Management
信用额度: Credit Limit
值: Value
元境平台: Yuanjing Platform
充值: Recharge
关于我们: About Us
其他tokens: Other Tokens
其他价格: Other Price
其他金额: Other Amount
函数名: Function Name
分销协议: Distribution Agreement
分销协议管理: Distribution Agreement Management
分销商对账: Distributor Reconciliation
分销商管理: Distributor Management
分销商结算: Distributor Settlement
创建时间: Creation Time
创建时间戳: Creation Timestamp
删除标志: Delete Flag
刷新权限缓存: Refresh Permission Cache
单模型对话: Single Model Conversation
参与方科目配置: Participant Account Configuration
发送验证码: Send Verification Code
名称: Name
启动日期: Start Date
命令: Command
响应时间: Response Time
响应模式: Response Mode
图标: Icon
在响应包中的位置: Position in Response Package
地址: Address
多模型对话: Multi-Model Conversation
多级标志: Multi-Level Flag
大模型: Large Model
大模型API调用: Large Model API Call
大模型费用: Large Model Cost
大模型费用W: Large Model Cost (W)
失效日期: Expiration Date
姓名: Full Name
完成时间: Completion Time
定价管理: Pricing Management
实例名: Instance Name (Short)
实例名称: Instance Name
实例说明: Instance Description
客户id: Customer ID
客户信用额度: Customer Credit Limit
密码: Password
小数点数: Decimal Places
属主id: Owner ID
帐务: Accounting
带历史信息: With History
应用: Application
应用编码表: Application Code Table
开始日期: Start Date
开帐: Open Account
微信: WeChat
性能最优Top5: Top 5 Best Performance
我: Me
我的订单: My Orders
我的账单: My Bills
我的账户: My Account
我的资源: My Resources
所在地区id: District ID
所在城市id: City ID
所在省id: Province ID
所属机构: Affiliated Organization
手机: Phone
手机号: Phone Number
手机验证码: Phone Verification Code
扫描未授权文件: Scan Unauthorized Files
接口id: Interface ID
接口ur: Interface URL
接口内容: Interface Content
接口参数: Interface Parameters
接口名: Interface Name (Short)
接口名称: Interface Name
接口描述: Interface Description
接口提供方: Interface Provider
接口输入输出: Interface Input/Output
接口集: Interface Set
推理: Inference
描述: Description
提示词: Prompt
数据IO: Data IO
数据值: Data Value
数据名: Data Name
数据看板: Data Dashboard
数据类型: Data Type
明细对账: Detail Reconciliation
是否多模态: Is Multimodal
是否必须: Is Required
显示名: Display Name
智普: Zhipu
智能体: AI Agent
月之暗面: Moonshot
服务目录: Service Catalog
服务管理: Service Management
机构: Organization
机构id: Organization ID
机构别名: Organization Alias
机构名称: Organization Name
机构拥有角色: Organization Roles
机构类型: Organization Type
机构编码: Organization Code
机构角色: Organization Role
权限: Permission
权限id: Permission ID
权限管理: Permission Management
查询路径权限角色: Query Path Permission Role
标题: Title
模型: Model
模型id: Model ID
模型供应商: Model Provider
模型列表: Model List
模型名称: Model Name
模型图标URL: Model Icon URL
模型实例: Model Instance
模型实例id: Model Instance ID
模型广场: Model Marketplace
模型或实例id: Model or Instance ID
模型接口: Model Interface
模型消息模版: Model Message Template
模型用量: Model Usage
模型管理: Model Management
模型类型: Model Type
模型类型id: Model Type ID
模型类型输入数据: Model Type Input Data
模型类型输出数据: Model Type Output Data
模型计费: Model Billing
模型计费日志: Model Billing Log
模型说明: Model Description
模型调优: Model Tuning
模型输入输出数据: Model Input/Output Data
消费token数: Consumed Token Count
消费日期: Consumption Date
消费时间戳: Consumption Timestamp
消费金额: Consumption Amount
添加供应商: Add Supplier
添加管理员: Add Administrator
父id: Parent ID
父数据id: Parent Data ID
父机构id: Parent Organization ID
父权限id: Parent Permission ID
用户: User
用户api密码表: User API Password Table
用户id: User ID
用户名: Username
用户密码: User Password
用户消息模版: User Message Template
用户状态: User Status
用户管理: User Management
用户角色: User Role
用户部门表: User Department Table
百川: Baichuan
百度千帆: Baidu Qianfan
真人素材: Real Person Material
私有知识库: Private Knowledge Base
科目设置: Account Settings
科目配置: Account Configuration
签退: Sign Out
类型: Type
类型名: Type Name
类型说明: Type Description
系统参数管理: System Parameter Management
系统日志: System Log
系统权限管理: System Permission Management
系统消息模版: System Message Template
系统管理: System Management
组号: Group Number
组织结构代码: Organization Structure Code
终端: Terminal
终端名称: Terminal Name
结束日期: End Date
编码名称: Code Name
编码键值表: Code Key-Value Table
联系人: Contact Person
联系人电话: Contact Phone
英文名: English Name
营业执照: Business License
角色: Role
角色id: Role ID
角色名称: Role Name
角色权限管理: Role Permission Management
角色权限表: Role Permission Table
角色管理: Role Management
角色编码: Role Code
计次价格: Per-Call Price
计次金额: Per-Call Amount
计费模式: Billing Mode
计费类型: Billing Type
记账失败记录: Accounting Failure Records
记账状态: Accounting Status
设备组: Device Group
评价: Rating
评价最高Top5: Top 5 Highest Rated
说明: Description
调用名: Call Name
调用数量Top5: Top 5 Call Volume
豆包: Doubao
财务处理: Financial Processing
账务中心: Accounting Center
账务设置: Accounting Settings
账务配置: Accounting Configuration
账单查询: Bill Inquiry
账号: Account
账号apikey: Account API Key
账号名称: Account Name
账号密码: Account Password
账号状态: Account Status
费用记录: Expense Records
路径: Path
身份证: ID Card
输入tokens: Input Tokens
输入token数: Input Token Count
输入价格: Input Price
输入字段: Input Field
输入显示: Input Display
输入类型: Input Type
输入金额: Input Amount
输出tokens: Output Tokens
输出token数: Output Token Count
输出价格: Output Price
输出显示: Output Display
输出金额: Output Amount
运营商配置: Operator Configuration
通义千问: Tongyi Qianwen
邮件地址: Email Address
邮箱: Email
部门id: Department ID
配置账务: Configure Accounting
重置密码: Reset Password
错帐处理: Error Account Handling
键: Key
长度: Length
附属密钥: Associated Key

View File

@ -1,341 +0,0 @@
API: API
API Key管理: APIキー管理
Add Error: 追加エラー
Add Success: 追加成功
Cancel: キャンセル
Conform: 確認
DeepSeek: DeepSeek
Delete Error: 削除エラー
Delete Success: 削除成功
Discard: 破棄
Error: エラー
LocalOllama: LocalOllama
Login: ログイン
Login Error: ログインエラー
Message: メッセージ
MiniMax: MiniMax
RBAC工具: RBACツール
Reset: リセット
Reset Password: パスワードリセット
Submit: 送信
Token交易记录: Token取引記録
Update Error: 更新エラー
Update Success: 更新成功
Welcome back: お帰りなさい
\u4ea4\u6613\u65e5\u671f: 取引日
\u4ea4\u6613\u65f6\u95f4: 取引時間
\u4f1a\u8bdd\u6587\u4ef6\u540d: セッションファイル名
\u4f9b\u5e94\u5546id: サプライヤーID
\u5176\u4ed6token\u4ef7\u683c: その他Token価格
\u5176\u4ed6tokens\u6d88\u8d39\u6570: その他Token消費数
\u51fd\u6570\u540d: 関数名
\u54cd\u5e94\u65f6\u95f4: レスポンス時間
\u5b8c\u6210\u65f6\u95f4: 完了時間
\u5ba2\u6237id: 顧客ID
\u5bc6\u7801: パスワード
\u624b\u673a: 携帯電話
\u6a21\u578b\u5b9e\u4f8bid: モデルインスタンスID
\u6a21\u578b\u7c7b\u578bid: モデルタイプID
\u7528\u6237\u540d: ユーザー名
\u7528\u6237id: ユーザーID
\u8ba1\u6b21\u4ef7\u683c: 回数制価格
\u8ba1\u6b21\u91d1\u989d: 回数制金額
\u8ba1\u8d39\u6a21\u5f0f: 課金モード
\u8ba1\u8d39token\u6570\u91cf: 課金Token数
\u8bb0\u8d26\u72b6\u6001: 記帳ステータス
\u8bc4\u4ef7: 評価
\u8f93\u5165token\u4ef7\u683c: 入力Token価格
\u8f93\u5165token\u6d88\u8d39\u6570: 入力Token消費数
\u8f93\u5165token\u91d1\u989d: 入力Token金額
\u8f93\u51fatoken\u4ef7\u683c: 出力Token価格
\u8f93\u51fatoken\u6d88\u8d39\u6570: 出力Token消費数
\u8f93\u51fatoken\u91d1\u989d: 出力Token金額
\u90ae\u4ef6\u5730\u5740: メールアドレス
\u9644\u5c5e\u5bc6\u94a5: 付属キー
api\u5bc6\u94a5: APIシークレット
api密码: APIパスワード
api密钥: APIシークレット
api用户: APIユーザー
failed: 失敗
http程序接口: HTTPプログラムインターフェース
id: ID
io数据id: IOデータID
logout success: ログアウト成功
minimax账单: MiniMax請求書
minimax账号: MiniMaxアカウント
minimax账号id: MiniMaxアカウントID
ok: OK
system error: システムエラー
token使用表: Token使用表
token数量: Token数
token每天统计: Token日次統計
token消耗量Top5: Token消費量トップ5
user name or password error: ユーザー名またはパスワードエラー
user register: ユーザー登録
 角色: ロール
© 2024 版权所有, 开元云(北京)科技有限公司: © 2024 著作権所有、開元雲(北京)科技有限公司
上位系统: 上位システム
上位系统管理: 上位システム管理
下位系统接口: 下位システムインターフェース
主营业务描述: 主要業務記述
主页: ホーム
交易日期: 取引日
交易时间: 取引時間
产品管理: 製品管理
产品类别管理: 製品カテゴリ管理
产品类型管理: 製品タイプ管理
产品类型规格: 製品タイプ仕様
代客充值: 代理チャージ
代理: エージェント
仪表盘: ダッシュボード
会计分录配置: 仕訳設定
会话文件名: セッションファイル名
余额与充值: 残高とチャージ
使用日期: 使用日
使用时间: 使用時間
供应协议: 供給契約
供应商id: サプライヤーID
供应商充值: サプライヤーチャージ
供应商名: サプライヤー名
供应商名称: サプライヤー名称
供应商对账: サプライヤー照合
供应商明细对账: サプライヤー明細照合
供应商模型列表: サプライヤーモデル一覧
供应商管理: サプライヤー管理
供应商结算: サプライヤー決済
供应商财务: サプライヤー財務
供应链管理: サプライチェーン管理
供销协议管理: 供給販売契約管理
信用额度: 与信限度額
值: 値
元境平台: 元境プラットフォーム
充值: チャージ
关于我们: 私たちについて
其他tokens: その他Tokens
其他价格: その他価格
其他金额: その他金額
函数名: 関数名
分销协议: 販売代理契約
分销协议管理: 販売代理契約管理
分销商对账: 販売代理店照合
分销商管理: 販売代理店管理
分销商结算: 販売代理店決済
创建时间: 作成日時
创建时间戳: 作成タイムスタンプ
删除标志: 削除フラグ
刷新权限缓存: 権限キャッシュ更新
单模型对话: 単一モデル対話
参与方科目配置: 参加者科目設定
发送验证码: 認証コード送信
名称: 名称
启动日期: 開始日
命令: コマンド
响应时间: レスポンス時間
响应模式: レスポンスモード
图标: アイコン
在响应包中的位置: レスポンスパッケージ内の位置
地址: アドレス
多模型对话: マルチモデル対話
多级标志: マルチレベルフラグ
大模型: 大規模モデル
大模型API调用: 大規模モデルAPI呼び出し
大模型费用: 大規模モデル費用
大模型费用W: 大規模モデル費用W
失效日期: 有効期限
姓名: 氏名
完成时间: 完了時間
定价管理: 価格設定管理
实例名: インスタンス名
实例名称: インスタンス名称
实例说明: インスタンス説明
客户id: 顧客ID
客户信用额度: 顧客与信限度額
密码: パスワード
小数点数: 小数点桁数
属主id: オーナーID
帐务: 会計
带历史信息: 履歴情報付き
应用: アプリケーション
应用编码表: アプリケーションコード表
开始日期: 開始日
开帐: 口座開設
微信: WeChat
性能最优Top5: パフォーマンス最優秀トップ5
我: 自分
我的订单: マイオーダー
我的账单: マイ請求書
我的账户: マイアカウント
我的资源: マイリソース
所在地区id: 所在区域ID
所在城市id: 所在城市ID
所在省id: 所在省ID
所属机构: 所属機関
手机: 携帯電話
手机号: 携帯電話番号
手机验证码: 携帯電話認証コード
扫描未授权文件: 未認可ファイルスキャン
接口id: インターフェースID
接口ur: インターフェースURL
接口内容: インターフェース内容
接口参数: インターフェースパラメータ
接口名: インターフェース名
接口名称: インターフェース名称
接口描述: インターフェース記述
接口提供方: インターフェース提供者
接口输入输出: インターフェース入出力
接口集: インターフェースセット
推理: 推論
描述: 記述
提示词: プロンプト
数据IO: データIO
数据值: データ値
数据名: データ名
数据看板: データダッシュボード
数据类型: データタイプ
明细对账: 明細照合
是否多模态: マルチモーダルかどうか
是否必须: 必須かどうか
显示名: 表示名
智普: 智譜
智能体: AIエージェント
月之暗面: Moonshot
服务目录: サービスカタログ
服务管理: サービス管理
机构: 機関
机构id: 機関ID
机构别名: 機関別名
机构名称: 機関名称
机构拥有角色: 機関所有ロール
机构类型: 機関タイプ
机构编码: 機関コード
机构角色: 機関ロール
权限: 権限
权限id: 権限ID
权限管理: 権限管理
查询路径权限角色: クエリパス権限ロール
标题: タイトル
模型: モデル
模型id: モデルID
模型供应商: モデルサプライヤー
模型列表: モデル一覧
模型名称: モデル名称
模型图标URL: モデルアイコンURL
模型实例: モデルインスタンス
模型实例id: モデルインスタンスID
模型广场: モデルマーケットプレイ스
模型或实例id: モデルまたはインスタンスID
模型接口: モデルインターフェース
模型消息模版: モデルメッセージテンプレート
模型用量: モデル使用量
模型管理: モデル管理
模型类型: モデルタイプ
模型类型id: モデルタイプID
模型类型输入数据: モデルタイプ入力データ
模型类型输出数据: モデルタイプ出力データ
模型计费: モデル課金
模型计费日志: モデル課金ログ
模型说明: モデル説明
模型调优: モデルチューニング
模型输入输出数据: モデル入出力データ
消费token数: 消費Token数
消费日期: 消費日
消费时间戳: 消費タイムスタンプ
消费金额: 消費金額
添加供应商: サプライヤー追加
添加管理员: 管理者追加
父id: 親ID
父数据id: 親データID
父机构id: 親機関ID
父权限id: 親権限ID
用户: ユーザー
用户api密码表: ユーザーAPIパスワード表
用户id: ユーザーID
用户名: ユーザー名
用户密码: ユーザーパスワード
用户消息模版: ユーザーメッセージテンプレート
用户状态: ユーザーステータス
用户管理: ユーザー管理
用户角色: ユーザーロール
用户部门表: ユーザー部門表
百川: 百川
百度千帆: Baidu Qianfan
真人素材: 実写素材
私有知识库: プライベートナレッジベース
科目设置: 科目設定
科目配置: 科目構成
签退: サインアウト
类型: タイプ
类型名: タイプ名
类型说明: タイプ説明
系统参数管理: システムパラメータ管理
系统日志: システムログ
系统权限管理: システム権限管理
系统消息模版: システムメッセージテンプレート
系统管理: システム管理
组号: グループ番号
组织结构代码: 組織構造コード
终端: ターミナル
终端名称: ターミナル名
结束日期: 終了日
编码名称: コード名称
编码键值表: コードキーバリュー表
联系人: 連絡先
联系人电话: 連絡先電話番号
英文名: 英語名
营业执照: 営業許可証
角色: ロール
角色id: ロールID
角色名称: ロール名称
角色权限管理: ロール権限管理
角色权限表: ロール権限表
角色管理: ロール管理
角色编码: ロールコード
计次价格: 回数制価格
计次金额: 回数制金額
计费模式: 課金モード
计费类型: 課金タイプ
记账失败记录: 記帳失敗記録
记账状态: 記帳ステータス
设备组: デバイスグループ
评价: 評価
评价最高Top5: 最高評価トップ5
说明: 説明
调用名: 呼び出し名
调用数量Top5: 呼び出し数量トップ5
豆包: 豆包
财务处理: 財務処理
账务中心: 会計センター
账务设置: 会計設定
账务配置: 会計構成
账单查询: 請求書照会
账号: アカウント
账号apikey: アカウントAPIキー
账号名称: アカウント名称
账号密码: アカウントパスワード
账号状态: アカウントステータス
费用记录: 費用記録
路径: パス
身份证: 身分証
输入tokens: 入力Tokens
输入token数: 入力Token数
输入价格: 入力価格
输入字段: 入力フィールド
输入显示: 入力表示
输入类型: 入力タイプ
输入金额: 入力金額
输出tokens: 出力Tokens
输出token数: 出力Token数
输出价格: 出力価格
输出显示: 出力表示
输出金额: 出力金額
运营商配置: オペレーター設定
通义千问: 通義千問
邮件地址: メールアドレス
邮箱: メール
部门id: 部門ID
配置账务: 会計構成
重置密码: パスワードリセット
错帐处理: 誤記帳処理
键: キー
长度: 長さ
附属密钥: 付属キー

View File

@ -1,341 +0,0 @@
API: API
API Key管理: API 키 관리
Add Error: 추가 오류
Add Success: 추가 성공
Cancel: 취소
Conform: 확인
DeepSeek: DeepSeek
Delete Error: 삭제 오류
Delete Success: 삭제 성공
Discard: 폐기
Error: 오류
LocalOllama: LocalOllama
Login: 로그인
Login Error: 로그인 오류
Message: 메시지
MiniMax: MiniMax
RBAC工具: RBAC 도구
Reset: 초기화
Reset Password: 비밀번호 재설정
Submit: 제출
Token交易记录: Token 거래 기록
Update Error: 업데이트 오류
Update Success: 업데이트 성공
Welcome back: 다시 오신 것을 환영합니다
\u4ea4\u6613\u65e5\u671f: 거래 날짜
\u4ea4\u6613\u65f6\u95f4: 거래 시간
\u4f1a\u8bdd\u6587\u4ef6\u540d: 세션 파일명
\u4f9b\u5e94\u5546id: 공급업체 ID
\u5176\u4ed6token\u4ef7\u683c: 기타 Token 가격
\u5176\u4ed6tokens\u6d88\u8d39\u6570: 기타 Tokens 소비량
\u51fd\u6570\u540d: 함수명
\u54cd\u5e94\u65f6\u95f4: 응답 시간
\u5b8c\u6210\u65f6\u95f4: 완료 시간
\u5ba2\u6237id: 고객 ID
\u5bc6\u7801: 비밀번호
\u624b\u673a: 휴대폰
\u6a21\u578b\u5b9e\u4f8bid: 모델 인스턴스 ID
\u6a21\u578b\u7c7b\u578bid: 모델 유형 ID
\u7528\u6237\u540d: 사용자명
\u7528\u6237id: 사용자 ID
\u8ba1\u6b21\u4ef7\u683c: 회차 가격
\u8ba1\u6b21\u91d1\u989d: 회차 금액
\u8ba1\u8d39\u6a21\u5f0f: 과금 모드
\u8ba1\u8d39token\u6570\u91cf: 과금 Token 수량
\u8bb0\u8d26\u72b6\u6001: 기장 상태
\u8bc4\u4ef7: 평가
\u8f93\u5165token\u4ef7\u683c: 입력 Token 가격
\u8f93\u5165token\u6d88\u8d39\u6570: 입력 Token 소비량
\u8f93\u5165token\u91d1\u989d: 입력 Token 금액
\u8f93\u51fatoken\u4ef7\u683c: 출력 Token 가격
\u8f93\u51fatoken\u6d88\u8d39\u6570: 출력 Token 소비량
\u8f93\u51fatoken\u91d1\u989d: 출력 Token 금액
\u90ae\u4ef6\u5730\u5740: 이메일 주소
\u9644\u5c5e\u5bc6\u94a5: 부속 키
api\u5bc6\u94a5: API 비밀키
api密码: API 비밀번호
api密钥: API 비밀키
api用户: API 사용자
failed: 실패
http程序接口: HTTP 프로그램 인터페이스
id: ID
io数据id: IO 데이터 ID
logout success: 로그아웃 성공
minimax账单: MiniMax 청구서
minimax账号: MiniMax 계정
minimax账号id: MiniMax 계정 ID
ok: 확인
system error: 시스템 오류
token使用表: Token 사용 테이블
token数量: Token 수량
token每天统计: Token 일일 통계
token消耗量Top5: Token 소비량 Top5
user name or password error: 사용자명 또는 비밀번호 오류
user register: 사용자 등록
 角色: 역할
© 2024 版权所有, 开元云(北京)科技有限公司: © 2024 모든 권리 보유, 카이위안윈(베이징) 기술 유한공사
上位系统: 상위 시스템
上位系统管理: 상위 시스템 관리
下位系统接口: 하위 시스템 인터페이스
主营业务描述: 주요 업무 설명
主页: 홈
交易日期: 거래 날짜
交易时间: 거래 시간
产品管理: 제품 관리
产品类别管理: 제품 카테고리 관리
产品类型管理: 제품 유형 관리
产品类型规格: 제품 유형 사양
代客充值: 대리 충전
代理: 에이전트
仪表盘: 대시보드
会计分录配置: 회계 분개 설정
会话文件名: 세션 파일명
余额与充值: 잔액 및 충전
使用日期: 사용 날짜
使用时间: 사용 시간
供应协议: 공급 계약
供应商id: 공급업체 ID
供应商充值: 공급업체 충전
供应商名: 공급업체명
供应商名称: 공급업체 명칭
供应商对账: 공급업체 대조
供应商明细对账: 공급업체 세부 대조
供应商模型列表: 공급업체 모델 목록
供应商管理: 공급업체 관리
供应商结算: 공급업체 정산
供应商财务: 공급업체 재무
供应链管理: 공급망 관리
供销协议管理: 공급 판매 계약 관리
信用额度: 신용 한도
值: 값
元境平台: 위안징 플랫폼
充值: 충전
关于我们: 회사 소개
其他tokens: 기타 Tokens
其他价格: 기타 가격
其他金额: 기타 금액
函数名: 함수명
分销协议: 유통 계약
分销协议管理: 유통 계약 관리
分销商对账: 유통업체 대조
分销商管理: 유통업체 관리
分销商结算: 유통업체 정산
创建时间: 생성 시간
创建时间戳: 생성 타임스탬프
删除标志: 삭제 플래그
刷新权限缓存: 권한 캐시 새로고침
单模型对话: 단일 모델 대화
参与方科目配置: 참여자 계정 설정
发送验证码: 인증 코드 전송
名称: 명칭
启动日期: 시작 날짜
命令: 명령
响应时间: 응답 시간
响应模式: 응답 모드
图标: 아이콘
在响应包中的位置: 응답 패키지 내 위치
地址: 주소
多模型对话: 멀티 모델 대화
多级标志: 다단계 플래그
大模型: 대규모 모델
大模型API调用: 대규모 모델 API 호출
大模型费用: 대규모 모델 비용
大模型费用W: 대규모 모델 비용 W
失效日期: 만료 날짜
姓名: 성명
完成时间: 완료 시간
定价管理: 가격 관리
实例名: 인스턴스명
实例名称: 인스턴스 명칭
实例说明: 인스턴스 설명
客户id: 고객 ID
客户信用额度: 고객 신용 한도
密码: 비밀번호
小数点数: 소수점 자릿수
属主id: 소유자 ID
帐务: 회계
带历史信息: 이력 정보 포함
应用: 애플리케이션
应用编码表: 애플리케이션 코드 테이블
开始日期: 시작 날짜
开帐: 계좌 개설
微信: 위챗
性能最优Top5: 성능 최적 Top5
我: 나
我的订单: 내 주문
我的账单: 내 청구서
我的账户: 내 계정
我的资源: 내 리소스
所在地区id: 소재 지역 ID
所在城市id: 소재 도시 ID
所在省id: 소재 성 ID
所属机构: 소속 기관
手机: 휴대폰
手机号: 휴대폰 번호
手机验证码: 휴대폰 인증 코드
扫描未授权文件: 미인가 파일 스캔
接口id: 인터페이스 ID
接口ur: 인터페이스 URL
接口内容: 인터페이스 내용
接口参数: 인터페이스 매개변수
接口名: 인터페이스명
接口名称: 인터페이스 명칭
接口描述: 인터페이스 설명
接口提供方: 인터페이스 제공자
接口输入输出: 인터페이스 입출력
接口集: 인터페이스 세트
推理: 추론
描述: 설명
提示词: 프롬프트
数据IO: 데이터 IO
数据值: 데이터 값
数据名: 데이터명
数据看板: 데이터 대시보드
数据类型: 데이터 유형
明细对账: 세부 대조
是否多模态: 멀티모달 여부
是否必须: 필수 여부
显示名: 표시명
智普: 즈푸
智能体: AI 에이전트
月之暗面: 문샷
服务目录: 서비스 카탈로그
服务管理: 서비스 관리
机构: 기관
机构id: 기관 ID
机构别名: 기관 별칭
机构名称: 기관 명칭
机构拥有角色: 기관 보유 역할
机构类型: 기관 유형
机构编码: 기관 코드
机构角色: 기관 역할
权限: 권한
权限id: 권한 ID
权限管理: 권한 관리
查询路径权限角色: 조회 경로 권한 역할
标题: 제목
模型: 모델
模型id: 모델 ID
模型供应商: 모델 공급업체
模型列表: 모델 목록
模型名称: 모델 명칭
模型图标URL: 모델 아이콘 URL
模型实例: 모델 인스턴스
模型实例id: 모델 인스턴스 ID
模型广场: 모델 마켓플레이스
模型或实例id: 모델 또는 인스턴스 ID
模型接口: 모델 인터페이스
模型消息模版: 모델 메시지 템플릿
模型用量: 모델 사용량
模型管理: 모델 관리
模型类型: 모델 유형
模型类型id: 모델 유형 ID
模型类型输入数据: 모델 유형 입력 데이터
模型类型输出数据: 모델 유형 출력 데이터
模型计费: 모델 과금
模型计费日志: 모델 과금 로그
模型说明: 모델 설명
模型调优: 모델 튜닝
模型输入输出数据: 모델 입출력 데이터
消费token数: 소비 Token 수
消费日期: 소비 날짜
消费时间戳: 소비 타임스탬프
消费金额: 소비 금액
添加供应商: 공급업체 추가
添加管理员: 관리자 추가
父id: 부모 ID
父数据id: 부모 데이터 ID
父机构id: 부모 기관 ID
父权限id: 부모 권한 ID
用户: 사용자
用户api密码表: 사용자 API 비밀번호 테이블
用户id: 사용자 ID
用户名: 사용자명
用户密码: 사용자 비밀번호
用户消息模版: 사용자 메시지 템플릿
用户状态: 사용자 상태
用户管理: 사용자 관리
用户角色: 사용자 역할
用户部门表: 사용자 부서 테이블
百川: 바이촨
百度千帆: 바이두 치안판
真人素材: 실사 소재
私有知识库: 개인 지식 베이스
科目设置: 계정 설정
科目配置: 계정 구성
签退: 로그아웃
类型: 유형
类型名: 유형명
类型说明: 유형 설명
系统参数管理: 시스템 매개변수 관리
系统日志: 시스템 로그
系统权限管理: 시스템 권한 관리
系统消息模版: 시스템 메시지 템플릿
系统管理: 시스템 관리
组号: 그룹 번호
组织结构代码: 조직 구조 코드
终端: 터미널
终端名称: 터미널명
结束日期: 종료 날짜
编码名称: 코드 명칭
编码键值表: 코드 키-값 테이블
联系人: 연락처
联系人电话: 연락처 전화
英文名: 영문명
营业执照: 사업자 등록증
角色: 역할
角色id: 역할 ID
角色名称: 역할 명칭
角色权限管理: 역할 권한 관리
角色权限表: 역할 권한 테이블
角色管理: 역할 관리
角色编码: 역할 코드
计次价格: 회차 가격
计次金额: 회차 금액
计费模式: 과금 모드
计费类型: 과금 유형
记账失败记录: 기장 실패 기록
记账状态: 기장 상태
设备组: 디바이스 그룹
评价: 평가
评价最高Top5: 최고 평가 Top5
说明: 설명
调用名: 호출명
调用数量Top5: 호출 수량 Top5
豆包: 더우바오
财务处理: 재무 처리
账务中心: 회계 센터
账务设置: 회계 설정
账务配置: 회계 구성
账单查询: 청구서 조회
账号: 계정
账号apikey: 계정 API 키
账号名称: 계정 명칭
账号密码: 계정 비밀번호
账号状态: 계정 상태
费用记录: 비용 기록
路径: 경로
身份证: 신분증
输入tokens: 입력 Tokens
输入token数: 입력 Token 수
输入价格: 입력 가격
输入字段: 입력 필드
输入显示: 입력 표시
输入类型: 입력 유형
输入金额: 입력 금액
输出tokens: 출력 Tokens
输出token数: 출력 Token 수
输出价格: 출력 가격
输出显示: 출력 표시
输出金额: 출력 금액
运营商配置: 운영자 구성
通义千问: 퉁이 치엔원
邮件地址: 이메일 주소
邮箱: 이메일
部门id: 부서 ID
配置账务: 회계 구성
重置密码: 비밀번호 재설정
错帐处理: 오기장 처리
键: 키
长度: 길이
附属密钥: 부속 키

View File

@ -1,341 +0,0 @@
API: API
API Key管理: API Key管理
Add Error: Add Error
Add Success: Add Success
Cancel: Cancel
Conform: Conform
DeepSeek: DeepSeek
Delete Error: Delete Error
Delete Success: Delete Success
Discard: Discard
Error: Error
LocalOllama: LocalOllama
Login: Login
Login Error: Login Error
Message: Message
MiniMax: MiniMax
RBAC工具: RBAC工具
Reset: Reset
Reset Password: Reset Password
Submit: Submit
Token交易记录: Token交易记录
Update Error: Update Error
Update Success: Update Success
Welcome back: Welcome back
\u4ea4\u6613\u65e5\u671f: \u4ea4\u6613\u65e5\u671f
\u4ea4\u6613\u65f6\u95f4: \u4ea4\u6613\u65f6\u95f4
\u4f1a\u8bdd\u6587\u4ef6\u540d: \u4f1a\u8bdd\u6587\u4ef6\u540d
\u4f9b\u5e94\u5546id: \u4f9b\u5e94\u5546id
\u5176\u4ed6token\u4ef7\u683c: \u5176\u4ed6token\u4ef7\u683c
\u5176\u4ed6tokens\u6d88\u8d39\u6570: \u5176\u4ed6tokens\u6d88\u8d39\u6570
\u51fd\u6570\u540d: \u51fd\u6570\u540d
\u54cd\u5e94\u65f6\u95f4: \u54cd\u5e94\u65f6\u95f4
\u5b8c\u6210\u65f6\u95f4: \u5b8c\u6210\u65f6\u95f4
\u5ba2\u6237id: \u5ba2\u6237id
\u5bc6\u7801: \u5bc6\u7801
\u624b\u673a: \u624b\u673a
\u6a21\u578b\u5b9e\u4f8bid: \u6a21\u578b\u5b9e\u4f8bid
\u6a21\u578b\u7c7b\u578bid: \u6a21\u578b\u7c7b\u578bid
\u7528\u6237\u540d: \u7528\u6237\u540d
\u7528\u6237id: \u7528\u6237id
\u8ba1\u6b21\u4ef7\u683c: \u8ba1\u6b21\u4ef7\u683c
\u8ba1\u6b21\u91d1\u989d: \u8ba1\u6b21\u91d1\u989d
\u8ba1\u8d39\u6a21\u5f0f: \u8ba1\u8d39\u6a21\u5f0f
\u8ba1\u8d39token\u6570\u91cf: \u8ba1\u8d39token\u6570\u91cf
\u8bb0\u8d26\u72b6\u6001: \u8bb0\u8d26\u72b6\u6001
\u8bc4\u4ef7: \u8bc4\u4ef7
\u8f93\u5165token\u4ef7\u683c: \u8f93\u5165token\u4ef7\u683c
\u8f93\u5165token\u6d88\u8d39\u6570: \u8f93\u5165token\u6d88\u8d39\u6570
\u8f93\u5165token\u91d1\u989d: \u8f93\u5165token\u91d1\u989d
\u8f93\u51fatoken\u4ef7\u683c: \u8f93\u51fatoken\u4ef7\u683c
\u8f93\u51fatoken\u6d88\u8d39\u6570: \u8f93\u51fatoken\u6d88\u8d39\u6570
\u8f93\u51fatoken\u91d1\u989d: \u8f93\u51fatoken\u91d1\u989d
\u90ae\u4ef6\u5730\u5740: \u90ae\u4ef6\u5730\u5740
\u9644\u5c5e\u5bc6\u94a5: \u9644\u5c5e\u5bc6\u94a5
api\u5bc6\u94a5: api\u5bc6\u94a5
api密码: api密码
api密钥: api密钥
api用户: api用户
failed: failed
http程序接口: http程序接口
id: id
io数据id: io数据id
logout success: logout success
minimax账单: minimax账单
minimax账号: minimax账号
minimax账号id: minimax账号id
ok: ok
system error: system error
token使用表: token使用表
token数量: token数量
token每天统计: token每天统计
token消耗量Top5: token消耗量Top5
user name or password error: user name or password error
user register: user register
 角色:  角色
© 2024 版权所有, 开元云(北京)科技有限公司: © 2024 版权所有, 开元云(北京)科技有限公司
上位系统: 上位系统
上位系统管理: 上位系统管理
下位系统接口: 下位系统接口
主营业务描述: 主营业务描述
主页: 主页
交易日期: 交易日期
交易时间: 交易时间
产品管理: 产品管理
产品类别管理: 产品类别管理
产品类型管理: 产品类型管理
产品类型规格: 产品类型规格
代客充值: 代客充值
代理: 代理
仪表盘: 仪表盘
会计分录配置: 会计分录配置
会话文件名: 会话文件名
余额与充值: 余额与充值
使用日期: 使用日期
使用时间: 使用时间
供应协议: 供应协议
供应商id: 供应商id
供应商充值: 供应商充值
供应商名: 供应商名
供应商名称: 供应商名称
供应商对账: 供应商对账
供应商明细对账: 供应商明细对账
供应商模型列表: 供应商模型列表
供应商管理: 供应商管理
供应商结算: 供应商结算
供应商财务: 供应商财务
供应链管理: 供应链管理
供销协议管理: 供销协议管理
信用额度: 信用额度
值: 值
元境平台: 元境平台
充值: 充值
关于我们: 关于我们
其他tokens: 其他tokens
其他价格: 其他价格
其他金额: 其他金额
函数名: 函数名
分销协议: 分销协议
分销协议管理: 分销协议管理
分销商对账: 分销商对账
分销商管理: 分销商管理
分销商结算: 分销商结算
创建时间: 创建时间
创建时间戳: 创建时间戳
删除标志: 删除标志
刷新权限缓存: 刷新权限缓存
单模型对话: 单模型对话
参与方科目配置: 参与方科目配置
发送验证码: 发送验证码
名称: 名称
启动日期: 启动日期
命令: 命令
响应时间: 响应时间
响应模式: 响应模式
图标: 图标
在响应包中的位置: 在响应包中的位置
地址: 地址
多模型对话: 多模型对话
多级标志: 多级标志
大模型: 大模型
大模型API调用: 大模型API调用
大模型费用: 大模型费用
大模型费用W: 大模型费用W
失效日期: 失效日期
姓名: 姓名
完成时间: 完成时间
定价管理: 定价管理
实例名: 实例名
实例名称: 实例名称
实例说明: 实例说明
客户id: 客户id
客户信用额度: 客户信用额度
密码: 密码
小数点数: 小数点数
属主id: 属主id
帐务: 帐务
带历史信息: 带历史信息
应用: 应用
应用编码表: 应用编码表
开始日期: 开始日期
开帐: 开帐
微信: 微信
性能最优Top5: 性能最优Top5
我: 我
我的订单: 我的订单
我的账单: 我的账单
我的账户: 我的账户
我的资源: 我的资源
所在地区id: 所在地区id
所在城市id: 所在城市id
所在省id: 所在省id
所属机构: 所属机构
手机: 手机
手机号: 手机号
手机验证码: 手机验证码
扫描未授权文件: 扫描未授权文件
接口id: 接口id
接口ur: 接口ur
接口内容: 接口内容
接口参数: 接口参数
接口名: 接口名
接口名称: 接口名称
接口描述: 接口描述
接口提供方: 接口提供方
接口输入输出: 接口输入输出
接口集: 接口集
推理: 推理
描述: 描述
提示词: 提示词
数据IO: 数据IO
数据值: 数据值
数据名: 数据名
数据看板: 数据看板
数据类型: 数据类型
明细对账: 明细对账
是否多模态: 是否多模态
是否必须: 是否必须
显示名: 显示名
智普: 智普
智能体: 智能体
月之暗面: 月之暗面
服务目录: 服务目录
服务管理: 服务管理
机构: 机构
机构id: 机构id
机构别名: 机构别名
机构名称: 机构名称
机构拥有角色: 机构拥有角色
机构类型: 机构类型
机构编码: 机构编码
机构角色: 机构角色
权限: 权限
权限id: 权限id
权限管理: 权限管理
查询路径权限角色: 查询路径权限角色
标题: 标题
模型: 模型
模型id: 模型id
模型供应商: 模型供应商
模型列表: 模型列表
模型名称: 模型名称
模型图标URL: 模型图标URL
模型实例: 模型实例
模型实例id: 模型实例id
模型广场: 模型广场
模型或实例id: 模型或实例id
模型接口: 模型接口
模型消息模版: 模型消息模版
模型用量: 模型用量
模型管理: 模型管理
模型类型: 模型类型
模型类型id: 模型类型id
模型类型输入数据: 模型类型输入数据
模型类型输出数据: 模型类型输出数据
模型计费: 模型计费
模型计费日志: 模型计费日志
模型说明: 模型说明
模型调优: 模型调优
模型输入输出数据: 模型输入输出数据
消费token数: 消费token数
消费日期: 消费日期
消费时间戳: 消费时间戳
消费金额: 消费金额
添加供应商: 添加供应商
添加管理员: 添加管理员
父id: 父id
父数据id: 父数据id
父机构id: 父机构id
父权限id: 父权限id
用户: 用户
用户api密码表: 用户api密码表
用户id: 用户id
用户名: 用户名
用户密码: 用户密码
用户消息模版: 用户消息模版
用户状态: 用户状态
用户管理: 用户管理
用户角色: 用户角色
用户部门表: 用户部门表
百川: 百川
百度千帆: 百度千帆
真人素材: 真人素材
私有知识库: 私有知识库
科目设置: 科目设置
科目配置: 科目配置
签退: 签退
类型: 类型
类型名: 类型名
类型说明: 类型说明
系统参数管理: 系统参数管理
系统日志: 系统日志
系统权限管理: 系统权限管理
系统消息模版: 系统消息模版
系统管理: 系统管理
组号: 组号
组织结构代码: 组织结构代码
终端: 终端
终端名称: 终端名称
结束日期: 结束日期
编码名称: 编码名称
编码键值表: 编码键值表
联系人: 联系人
联系人电话: 联系人电话
英文名: 英文名
营业执照: 营业执照
角色: 角色
角色id: 角色id
角色名称: 角色名称
角色权限管理: 角色权限管理
角色权限表: 角色权限表
角色管理: 角色管理
角色编码: 角色编码
计次价格: 计次价格
计次金额: 计次金额
计费模式: 计费模式
计费类型: 计费类型
记账失败记录: 记账失败记录
记账状态: 记账状态
设备组: 设备组
评价: 评价
评价最高Top5: 评价最高Top5
说明: 说明
调用名: 调用名
调用数量Top5: 调用数量Top5
豆包: 豆包
财务处理: 财务处理
账务中心: 账务中心
账务设置: 账务设置
账务配置: 账务配置
账单查询: 账单查询
账号: 账号
账号apikey: 账号apikey
账号名称: 账号名称
账号密码: 账号密码
账号状态: 账号状态
费用记录: 费用记录
路径: 路径
身份证: 身份证
输入tokens: 输入tokens
输入token数: 输入token数
输入价格: 输入价格
输入字段: 输入字段
输入显示: 输入显示
输入类型: 输入类型
输入金额: 输入金额
输出tokens: 输出tokens
输出token数: 输出token数
输出价格: 输出价格
输出显示: 输出显示
输出金额: 输出金额
运营商配置: 运营商配置
通义千问: 通义千问
邮件地址: 邮件地址
邮箱: 邮箱
部门id: 部门id
配置账务: 配置账务
重置密码: 重置密码
错帐处理: 错帐处理
键: 键
长度: 长度
附属密钥: 附属密钥

View File

@ -1,138 +0,0 @@
#!/usr/bin/env python3
"""
导入 init/data.json 中的 appcodes / appcodes_kv 编码字典到 sage 数据库
用法:
cd ~/repos/sage
py3/bin/python import_codes.py ../supplychain/init/data.json
py3/bin/python import_codes.py ../product_management/init/data.json ../supplychain/init/data.json
"""
import sys
import json
import os
import asyncio
import argparse
# 修正 venv site-packages 路径venv 可能是旧版 Python 创建的)
_script_dir = os.path.dirname(os.path.abspath(__file__))
_venv_lib = os.path.join(_script_dir, 'py3', 'lib')
if os.path.isdir(_venv_lib):
for _d in os.listdir(_venv_lib):
_sp = os.path.join(_venv_lib, _d, 'site-packages')
if os.path.isdir(_sp) and _sp not in sys.path:
sys.path.insert(0, _sp)
# 添加本地依赖路径editable install 可能指向 Docker 路径)
_repos_dir = os.path.dirname(_script_dir)
for _dep in ['apppublic', 'sqlor']:
_dep_dir = os.path.join(_repos_dir, _dep)
if os.path.isdir(_dep_dir) and _dep_dir not in sys.path:
sys.path.insert(0, _dep_dir)
from appPublic.jsonConfig import getConfig
from sqlor.dbpools import DBPools
async def import_data_json(sor, filepath):
"""将单个 data.json 中的 appcodes 和 appcodes_kv 导入数据库"""
with open(filepath, 'r', encoding='utf-8') as f:
data = json.load(f)
# 导入 appcodes — 支持两种格式:
# 格式1: [{"id":..., "name":..., "hierarchy_flg":...}]
# 格式2: [{"parentid":..., "parentname":..., "items":[...]}]
appcodes = data.get('appcodes', [])
codes_count = 0
kv_count = 0
for item in appcodes:
# 格式2: parentid/parentname + 内嵌 items
if 'parentid' in item and 'items' in item:
parentid = item['parentid']
parentname = item.get('parentname', parentid)
await sor.sqlExe("""
INSERT INTO appcodes (id, name, hierarchy_flg)
VALUES (${id}$, ${name}$, ${hierarchy_flg}$)
ON DUPLICATE KEY UPDATE name=VALUES(name), hierarchy_flg=VALUES(hierarchy_flg)
""", {
'id': parentid,
'name': parentname,
'hierarchy_flg': item.get('hierarchy_flg', '0')
})
codes_count += 1
# 导入内嵌的 kv 条目
for kv_item in item.get('items', []):
kv_id = f"{parentid}_{kv_item['k']}"
await sor.sqlExe("""
INSERT INTO appcodes_kv (id, parentid, k, v)
VALUES (${id}$, ${parentid}$, ${k}$, ${v}$)
ON DUPLICATE KEY UPDATE id=VALUES(id), v=VALUES(v)
""", {
'id': kv_id,
'parentid': parentid,
'k': kv_item['k'],
'v': kv_item['v']
})
kv_count += 1
# 格式1: 标准 id/name
elif 'id' in item:
await sor.sqlExe("""
INSERT INTO appcodes (id, name, hierarchy_flg)
VALUES (${id}$, ${name}$, ${hierarchy_flg}$)
ON DUPLICATE KEY UPDATE name=VALUES(name), hierarchy_flg=VALUES(hierarchy_flg)
""", {
'id': item['id'],
'name': item['name'],
'hierarchy_flg': item.get('hierarchy_flg', '0')
})
codes_count += 1
print(f" appcodes: {codes_count}")
# 导入独立 appcodes_kv (格式1兼容)
appcodes_kv = data.get('appcodes_kv', [])
for item in appcodes_kv:
await sor.sqlExe("""
INSERT INTO appcodes_kv (id, parentid, k, v)
VALUES (${id}$, ${parentid}$, ${k}$, ${v}$)
ON DUPLICATE KEY UPDATE id=VALUES(id), v=VALUES(v)
""", {
'id': item['id'],
'parentid': item['parentid'],
'k': item['k'],
'v': item['v']
})
kv_count += 1
if appcodes_kv:
print(f" appcodes_kv: {len(appcodes_kv)} 条 (独立)")
print(f" appcodes_kv: {kv_count} 条 (合计)")
return codes_count, kv_count
async def main():
parser = argparse.ArgumentParser(description='导入编码字典到 sage 数据库')
parser.add_argument('files', nargs='+', help='init/data.json 文件路径')
args = parser.parse_args()
# 使用 getConfig() 获取配置DBPools 初始化数据库池
config = getConfig('.')
db = DBPools(config.databases)
print(f"连接数据库: sage")
total_codes = 0
total_kv = 0
async with db.sqlorContext('sage') as sor:
for filepath in args.files:
print(f"导入: {filepath}")
c, kv = await import_data_json(sor, filepath)
total_codes += c
total_kv += kv
print(f"\n完成! 共导入 appcodes: {total_codes} 条, appcodes_kv: {total_kv}")
if __name__ == '__main__':
asyncio.run(main())

View File

@ -1,6 +1,6 @@
{ {
"models_dir": "${HOME}$/py/accounting/models", "models_dir": "${HOME}$/py/accounting/models",
"output_dir": "${HOME}$/py/accounting/wwwroot/accounting_config", "output_dir": "${HOME}$/py/sage/wwwroot/_a/accounting_config",
"dbname": "sage", "dbname": "sage",
"tblname": "accounting_config", "tblname": "accounting_config",
"params": { "params": {

View File

@ -1,3 +0,0 @@
#!/bin/bash
xls2ui -m ../models -o ../wwwroot sage *.json

View File

@ -1,6 +1,6 @@
{ {
"models_dir": "${HOME}$/py/accounting/models", "models_dir": "${HOME}$/py/accounting/models",
"output_dir": "${HOME}$/py/accounting/wwwroot/subject", "output_dir": "${HOME}$/py/sage/wwwroot/_a/subject",
"dbname": "sage", "dbname": "sage",
"tblname": "subject", "tblname": "subject",
"params": { "params": {

View File

@ -8,9 +8,6 @@ paths="""/ any
/favicon.ico any /favicon.ico any
/top.ui any /top.ui any
/i18n_getmsgs any /i18n_getmsgs any
/tenant any
/tenant/index.ui any
/get_domain_info.dspy any
/uapi logined /uapi logined
/uapi/uapi logined /uapi/uapi logined
/uapi/uapi/delete_uapi.dspy logined /uapi/uapi/delete_uapi.dspy logined
@ -45,8 +42,6 @@ paths="""/ any
/uapi/uapiset/index.ui logined /uapi/uapiset/index.ui logined
/uapi/uapiset/delete_uapiset.dspy logined /uapi/uapiset/delete_uapiset.dspy logined
/uapi/menu.ui any /uapi/menu.ui any
/uapi/copy_uapi.ui logined
/uapi/api/copy_uapi.dspy logined
/llmage logined /llmage logined
/llmage/llmcost.dspy logined /llmage/llmcost.dspy logined
/llmage/menu.ui any /llmage/menu.ui any
@ -54,12 +49,6 @@ paths="""/ any
/llmage/llm_dialog.ui logined /llmage/llm_dialog.ui logined
/llmage/show_same_catelog_llm.ui logined /llmage/show_same_catelog_llm.ui logined
/llmage/model_estimate.dspy logined /llmage/model_estimate.dspy logined
/llmage/model_plaza.ui logined
/llmage/dim_test.ui logined
/llmage/plaza_model_cards.ui logined
/llmage/api/get_plaza_models.dspy logined
/llmage/api/plaza_categories.dspy logined
/llmage/api/plaza_providers.dspy logined
/llmage/show_llms.ui logined /llmage/show_llms.ui logined
/llmage/llmusage logined /llmage/llmusage logined
/llmage/llmusage/update_llmusage.dspy logined /llmage/llmusage/update_llmusage.dspy logined
@ -67,24 +56,7 @@ paths="""/ any
/llmage/llmusage/add_llmusage.dspy logined /llmage/llmusage/add_llmusage.dspy logined
/llmage/llmusage/index.ui logined /llmage/llmusage/index.ui logined
/llmage/llmusage/get_llmusage.dspy logined /llmage/llmusage/get_llmusage.dspy logined
/llmage/llm_metrics logined
/llmage/llm_metrics/get_llm_metrics.dspy logined
/llmage/llm_metrics/index.ui logined
/llmage/user_llm_policy logined
/llmage/user_llm_policy/get_user_llm_policy.dspy logined
/llmage/user_llm_policy/add_user_llm_policy.dspy logined
/llmage/user_llm_policy/update_user_llm_policy.dspy logined
/llmage/user_llm_policy/delete_user_llm_policy.dspy logined
/llmage/user_llm_policy/index.ui logined
/llmage/llmcheck.dspy logined /llmage/llmcheck.dspy logined
/llmage/check_model_record.dspy logined
/llmage/check_date_status.dspy logined
/llmage/check_upapp.dspy logined
/llmage/check_uapi.dspy logined
/llmage/check_uapiio.dspy logined
/llmage/check_llm_api_map.dspy logined
/llmage/check_pricing_program.dspy logined
/llmage/check_pricing_data.dspy logined
/llmage/imgs any /llmage/imgs any
/llmage/imgs/kdb.svg any /llmage/imgs/kdb.svg any
/llmage/list_catelog_models.dspy any /llmage/list_catelog_models.dspy any
@ -112,8 +84,6 @@ paths="""/ any
/llmage/v1/video/generations/index.dspy logined /llmage/v1/video/generations/index.dspy logined
/llmage/v1/image/generations logined /llmage/v1/image/generations logined
/llmage/v1/image/generations/index.dspy logined /llmage/v1/image/generations/index.dspy logined
/llmage/v1/pricing logined
/llmage/v1/pricing/index.dspy logined
/public any /public any
/public/mainpage any /public/mainpage any
/public/mainpage/wish.webp any /public/mainpage/wish.webp any
@ -158,56 +128,6 @@ paths="""/ any
/public/llmsquare/statistic/total_usage.dspy any /public/llmsquare/statistic/total_usage.dspy any
/public/about any /public/about any
/public/about/index_zh.md any /public/about/index_zh.md any
# sage_datamart
/sage_datamart logined
/sage_datamart/index.ui logined
/sage_datamart/menu.ui any
/sage_datamart/api/currency_stats.dspy logined
/sage_datamart/api/customer_models.dspy logined
/sage_datamart/api/daily_trend.dspy logined
/sage_datamart/api/distributor_currency.dspy logined
/sage_datamart/api/distributor_customers.dspy logined
/sage_datamart/api/distributor_financial.dspy logined
/sage_datamart/api/financial_chart.dspy logined
/sage_datamart/api/financial_summary.dspy logined
/sage_datamart/api/hourly_concurrency.dspy logined
/sage_datamart/api/model_perf.dspy logined
/sage_datamart/api/provider_roi.dspy logined
/sage_datamart/api/realtime_cards.dspy logined
/sage_datamart/api/stats.dspy logined
/sage_datamart/api/top_models.dspy logined
/sage_datamart/api/top_providers.dspy logined
/sage_datamart/api/top_users.dspy logined
/sage_datamart/api/user_apikeys.dspy logined
/sage_datamart/cron/etl_aggregate.dspy logined
/sage_datamart/cron/etl_provider_cost.dspy logined
/sage_datamart/cron/etl_sync.dspy logined
/sage_datamart/provider_roi.ui logined
/sage_datamart/rt_card_active.ui logined
/sage_datamart/rt_card_amount.ui logined
/sage_datamart/rt_card_calls.ui logined
/sage_datamart/rt_card_fail.ui logined
/sage_datamart/rt_card_online.ui logined
/sage_datamart/rt_card_success.ui logined
/sage_datamart/rt_card_users.ui logined
/sage_datamart/sect_currency.ui logined
/sage_datamart/sect_customer_currency.ui logined
/sage_datamart/sect_distributor_currency.ui logined
/sage_datamart/sect_distributor_financial.ui logined
/sage_datamart/sect_model_perf.ui logined
/sage_datamart/sect_provider_roi.ui logined
/sage_datamart/sect_top_models.ui logined
/sage_datamart/sect_top_providers.ui logined
/sage_datamart/sect_top_users.ui logined
/sage_datamart/sect_user_apikeys.ui logined
/sage_datamart/stat_avg_ttft.ui logined
/sage_datamart/stat_fail_calls.ui logined
/sage_datamart/stat_success_rate.ui logined
/sage_datamart/stat_today_amount.ui logined
/sage_datamart/stat_today_usage.ui logined
/sage_datamart/stat_total_calls.ui logined
/sage_datamart/stat_total_users.ui logined
/public/about/index.md any /public/about/index.md any
/public/about/index.ui any /public/about/index.ui any
/public/about/index_en.md any /public/about/index_en.md any
@ -568,7 +488,6 @@ paths="""/ any
/bricks/bricks.js any /bricks/bricks.js any
/bricks/css any /bricks/css any
/bricks/css/bricks.css any /bricks/css/bricks.css any
/bricks/css/api_doc.css any
/dashboard_for_sage logined /dashboard_for_sage logined
/dashboard_for_sage/index.ui logined /dashboard_for_sage/index.ui logined
/dashboard_for_sage/menu.ui any /dashboard_for_sage/menu.ui any
@ -607,19 +526,6 @@ paths="""/ any
/accounting/subject/index.ui logined /accounting/subject/index.ui logined
/accounting/account_config logined /accounting/account_config logined
/accounting/account_config/update_account_config.dspy logined /accounting/account_config/update_account_config.dspy logined
/accounting/credit_limit logined
/accounting/credit_limit/credit_manage.ui logined
/accounting/credit_limit/credit_overview.ui logined
/accounting/credit_limit/hub.ui logined
/accounting/credit_limit/index.ui logined
/accounting/credit_limit/get_credit_limit.dspy logined
/accounting/credit_limit/add_credit_limit.dspy logined
/accounting/credit_limit/update_credit_limit.dspy logined
/accounting/credit_limit/delete_credit_limit.dspy logined
/accounting/credit_limit/api logined
/accounting/credit_limit/api/set_credit_form.ui logined
/accounting/credit_limit/api/set_customer_credit.dspy logined
/accounting/credit_limit/api/credit_summary.dspy logined
/accounting/account_config/get_account_config.dspy logined /accounting/account_config/get_account_config.dspy logined
/accounting/account_config/index.ui logined /accounting/account_config/index.ui logined
/accounting/account_config/add_account_config.dspy logined /accounting/account_config/add_account_config.dspy logined
@ -651,61 +557,6 @@ paths="""/ any
/accounting/acc_detail/index.ui logined /accounting/acc_detail/index.ui logined
/accounting/acc_detail/get_acc_detail.dspy logined /accounting/acc_detail/get_acc_detail.dspy logined
/accounting/open_reseller_accounts.dspy logined /accounting/open_reseller_accounts.dspy logined
/cpcc logined
/cpcc/index.ui logined
/cpcc/menu.ui any
/cpcc/top.ui logined
/cpcc/bottom.ui logined
/cpcc/center.ui logined
/cpcc/app_panel.ui logined
/cpcc/components logined
/cpcc/components/index.ui logined
/cpcc/components/get_components.dspy logined
/cpcc/components/add_components.dspy logined
/cpcc/components/update_components.dspy logined
/cpcc/components/delete_components.dspy logined
/cpcc/cpccluster logined
/cpcc/cpccluster/index.ui logined
/cpcc/cpccluster/get_cpccluster.dspy logined
/cpcc/cpccluster/add_cpccluster.dspy logined
/cpcc/cpccluster/update_cpccluster.dspy logined
/cpcc/cpccluster/delete_cpccluster.dspy logined
/cpcc/cpclist logined
/cpcc/cpclist/index.ui logined
/cpcc/cpclist/get_cpclist.dspy logined
/cpcc/cpclist/add_cpclist.dspy logined
/cpcc/cpclist/update_cpclist.dspy logined
/cpcc/cpclist/delete_cpclist.dspy logined
/cpcc/cpcnode logined
/cpcc/cpcnode/index.ui logined
/cpcc/cpcnode/get_cpcnode.dspy logined
/cpcc/cpcnode/add_cpcnode.dspy logined
/cpcc/cpcnode/update_cpcnode.dspy logined
/cpcc/cpcnode/delete_cpcnode.dspy logined
/cpcc/cpcpod logined
/cpcc/cpcpod/index.ui logined
/cpcc/cpcpod/get_cpcpod.dspy logined
/cpcc/cpcpod/get_node_labels.dspy logined
/cpcc/cpcpod/new_cpcpodyaml.dspy logined
/cpcc/cpcpod/new_podyaml.ui logined
/cpcc/cpcpodyaml logined
/cpcc/cpcpodyaml/index.ui logined
/cpcc/cpcpodyaml/get_cpcpodyaml.dspy logined
/cpcc/cpcpodyaml/update_cpcpodyaml.dspy logined
/cpcc/cpcpodyaml/delete_cpcpodyaml.dspy logined
/cpcc/cpcworker logined
/cpcc/cpcworker/index.ui logined
/cpcc/cpcworker/get_cpcworker.dspy logined
/cpcc/cpcworker/get_availableworker.dspy logined
/cpcc/cpcworker/add_cpcworker.dspy logined
/cpcc/cpcworker/update_cpcworker.dspy logined
/cpcc/cpcworker/delete_cpcworker.dspy logined
/cpcc/cpcworker/new_cpcworker.dspy logined
/cpcc/cpcworker/new_worker.ui logined
/cpcc/handy logined
/cpcc/handy/get_cpcnodes.dspy logined
/cpcc/handy/new_cluster.dspy logined
/cpcc/handy/new_cluster.ui logined
/appbase logined /appbase logined
/appbase/menu.ui any /appbase/menu.ui any
/appbase/appcodes_kv owner.superuser /appbase/appcodes_kv owner.superuser
@ -738,19 +589,6 @@ paths="""/ any
/appbase/svgicon/add_svgicon.dspy owner.superuser /appbase/svgicon/add_svgicon.dspy owner.superuser
/appbase/svgicon/update_svgicon.dspy owner.superuser /appbase/svgicon/update_svgicon.dspy owner.superuser
/appbase/svgicon/index.ui owner.superuser /appbase/svgicon/index.ui owner.superuser
/accounting/currency_list owner.superuser
/accounting/currency_list/index.ui owner.superuser
/accounting/currency_list/get_currency_list.dspy owner.superuser
/accounting/currency_list/add_currency_list.dspy owner.superuser
/accounting/currency_list/update_currency_list.dspy owner.superuser
/accounting/currency_list/delete_currency_list.dspy owner.superuser
/accounting/exchange_rate_list owner.superuser
/accounting/exchange_rate_list/index.ui owner.superuser
/accounting/exchange_rate_list/get_exchange_rate_list.dspy owner.superuser
/accounting/exchange_rate_list/add_exchange_rate_list.dspy owner.superuser
/accounting/exchange_rate_list/update_exchange_rate_list.dspy owner.superuser
/accounting/exchange_rate_list/delete_exchange_rate_list.dspy owner.superuser
/msp logined /msp logined
/msp/keypress.ui logined /msp/keypress.ui logined
/msp/devgroup logined /msp/devgroup logined
@ -825,7 +663,6 @@ paths="""/ any
/pricing/pricing_program_timing/get_pricing_program_timing.dspy logined /pricing/pricing_program_timing/get_pricing_program_timing.dspy logined
/pricing/pricing_program_timing/index.ui logined /pricing/pricing_program_timing/index.ui logined
/pricing/pricing_program_timing/add_pricing_program_timing.dspy logined /pricing/pricing_program_timing/add_pricing_program_timing.dspy logined
/pricing/pricing_data_display.ui logined
/api /api
/api/callback /api/callback
/api/callback/alipay /api/callback/alipay
@ -856,15 +693,10 @@ paths="""/ any
/rbac/get_reseller.dspy owner.* /rbac/get_reseller.dspy owner.*
/rbac/users logined /rbac/users logined
/rbac/users/delete_users.dspy *.admin /rbac/users/delete_users.dspy *.admin
/rbac/users/add_users.dspy *.admin /rbac/users/add_users.dsp *.adminy
/rbac/users/update_users.dspy *.admin /rbac/users/update_users.dsp *.adminy
/rbac/users/index.ui *.admin /rbac/users/index.u *.admini
/rbac/users/get_users.dspy *.admin /rbac/users/get_users.dspy
/rbac/users/enable_user.dspy *.admin
/rbac/users/disable_user.dspy *.admin
/rbac/api/add_user.dspy *.admin
/rbac/api/update_user.dspy *.admin
/rbac/api/get_search_roleid.dspy logined
/rbac/add_adminuser.dspy owner.superuser /rbac/add_adminuser.dspy owner.superuser
/rbac/reseller logined /rbac/reseller logined
/rbac/reseller/update_organization.dspy logined /rbac/reseller/update_organization.dspy logined
@ -1270,12 +1102,12 @@ paths="""/ any
/unipay/imgs/payment_log.svg any /unipay/imgs/payment_log.svg any
/unipay/usermenu.ui logined /unipay/usermenu.ui logined
/unipay/refund.ui customer.* /unipay/refund.ui customer.*
/unipay/transfer_info.ui logined
/product_management logined /product_management logined
/product_management/index.ui logined /product_management/index.ui logined
/product_management/menu.ui any /product_management/menu.ui any
/product_management/category_manage.ui logined /product_management/category_manage.ui logined
/product_management/product_manage.ui logined /product_management/product_manage.ui logined
/product_management/product_type_config_manage.ui logined
/product_management/api/category_options.dspy logined /product_management/api/category_options.dspy logined
/product_management/api/product_category_create.dspy logined /product_management/api/product_category_create.dspy logined
/product_management/api/product_category_update.dspy logined /product_management/api/product_category_update.dspy logined
@ -1283,196 +1115,20 @@ paths="""/ any
/product_management/api/product_create.dspy logined /product_management/api/product_create.dspy logined
/product_management/api/product_update.dspy logined /product_management/api/product_update.dspy logined
/product_management/api/product_delete.dspy logined /product_management/api/product_delete.dspy logined
/product_management/api/product_type_config_create.dspy logined
/product_management/api/product_type_config_update.dspy logined
/product_management/api/product_type_config_delete.dspy logined
/product_management/api/product_brief.dspy logined /product_management/api/product_brief.dspy logined
/product_management/api/product_detail.dspy logined /product_management/api/product_detail.dspy logined
/product_management/api/product_purchase.dspy logined /product_management/api/product_purchase.dspy logined
/product_management/api/product_use.dspy logined /product_management/api/product_use.dspy logined
/product_management/product_category_tree logined /product_management/product_category_tree logined
/product_management/product_list logined /product_management/product_list logined
/product_management/product_type_config_list logined
/supplychain logined /supplychain logined
/supplychain/api/calculate_accounting.dspy logined
/supplychain/api/add_sub_distributor_admin.dspy logined
/supplychain/agreement_discount_setting.ui logined
/supplychain/contract_discount_setting.ui logined
/supplychain/api/get_agreement_discount_items.dspy logined
/supplychain/api/get_contract_discount_items.dspy logined
/supplychain/api/save_agreement_discount.dspy logined
/supplychain/api/save_contract_discount.dspy logined
/supplychain/api/distribution_agreement_items_create.dspy logined
/supplychain/api/distribution_agreement_items_delete.dspy logined
/supplychain/api/distribution_agreement_items_update.dspy logined
/supplychain/api/distribution_agreements_create.dspy logined
/supplychain/api/distribution_agreements_delete.dspy logined
/supplychain/api/distribution_agreements_update.dspy logined
/supplychain/api/ensure_distribution_agreement.dspy logined
/supplychain/api/ensure_supply_contract.dspy logined
/supplychain/api/get_search_agreement_id.dspy logined
/supplychain/api/get_search_contract_id.dspy logined
/supplychain/api/get_search_orgid.dspy logined
/supplychain/api/get_search_prodtypeid.dspy logined
/supplychain/api/get_search_productid.dspy logined
/supplychain/api/get_search_sub_distributor_id.dspy logined
/supplychain/api/get_search_sub_reseller_id.dspy logined
/supplychain/api/get_search_supplier_id.dspy logined
/supplychain/api/get_search_supply_relation_id.dspy logined
/supplychain/api/import_supplier_product.dspy logined
/supplychain/api/platform_supply_products_create.dspy logined
/supplychain/api/platform_supply_products_delete.dspy logined
/supplychain/api/platform_supply_products_update.dspy logined
/supplychain/api/platform_supply_relations_create.dspy logined
/supplychain/api/platform_supply_relations_delete.dspy logined
/supplychain/api/platform_supply_relations_update.dspy logined
/supplychain/api/product_supplier_mapping_create.dspy logined
/supplychain/api/product_supplier_mapping_delete.dspy logined
/supplychain/api/product_supplier_mapping_update.dspy logined
/supplychain/api/query_dist_discount.dspy logined
/supplychain/api/query_platform_products.dspy logined
/supplychain/api/query_platform_suppliers.dspy logined
/supplychain/api/query_supply_discount.dspy logined
/supplychain/api/reset_sub_distributor_admin_pwd.dspy logined
/supplychain/api/sales_ledger_create.dspy logined
/supplychain/api/sales_ledger_delete.dspy logined
/supplychain/api/sales_ledger_update.dspy logined
/supplychain/api/sub_distributors_create.dspy logined
/supplychain/api/sub_distributors_delete.dspy logined
/supplychain/api/sub_distributors_update.dspy logined
/supplychain/api/sub_resellers_create.dspy logined
/supplychain/api/sub_resellers_delete.dspy logined
/supplychain/api/sub_resellers_update.dspy logined
/supplychain/api/supplier_resource_price_create.dspy logined
/supplychain/api/supplier_resource_price_delete.dspy logined
/supplychain/api/supplier_resource_price_update.dspy logined
/supplychain/api/suppliers_create.dspy logined
/supplychain/api/suppliers_delete.dspy logined
/supplychain/api/suppliers_update.dspy logined
/supplychain/api/supply_contract_items_create.dspy logined
/supplychain/api/supply_contract_items_delete.dspy logined
/supplychain/api/supply_contract_items_update.dspy logined
/supplychain/api/supply_contracts_create.dspy logined
/supplychain/api/supply_contracts_delete.dspy logined
/supplychain/api/supply_contracts_update.dspy logined
/supplychain/api/supplychain_accounting_create.dspy logined
/supplychain/api/supplychain_accounting_delete.dspy logined
/supplychain/api/supplychain_accounting_update.dspy logined
/supplychain/api/contract_attach_list.dspy logined
/supplychain/api/contract_attach.ui logined
/supplychain/api/contract_upload.dspy logined
/supplychain/api/contract_attach_delete.dspy logined
/supplychain/distribution_agreement_items_list logined
/supplychain/distribution_agreement_items_list/add_distribution_agreement_items.dspy logined
/supplychain/distribution_agreement_items_list/delete_distribution_agreement_items.dspy logined
/supplychain/distribution_agreement_items_list/get_distribution_agreement_items.dspy logined
/supplychain/distribution_agreement_items_list/index.ui logined
/supplychain/distribution_agreement_items_list/update_distribution_agreement_items.dspy logined
/supplychain/distribution_agreements_list logined
/supplychain/distribution_agreements_list/add_distribution_agreements.dspy logined
/supplychain/distribution_agreements_list/delete_distribution_agreements.dspy logined
/supplychain/distribution_agreements_list/get_distribution_agreements.dspy logined
/supplychain/distribution_agreements_list/index.ui logined
/supplychain/distribution_agreements_list/update_distribution_agreements.dspy logined
/supplychain/platform_supply_products_list logined
/supplychain/platform_supply_products_list/add_platform_supply_products.dspy logined
/supplychain/platform_supply_products_list/delete_platform_supply_products.dspy logined
/supplychain/platform_supply_products_list/get_platform_supply_products.dspy logined
/supplychain/platform_supply_products_list/index.ui logined
/supplychain/platform_supply_products_list/update_platform_supply_products.dspy logined
/supplychain/platform_supply_relations_list logined
/supplychain/platform_supply_relations_list/add_platform_supply_relations.dspy logined
/supplychain/platform_supply_relations_list/delete_platform_supply_relations.dspy logined
/supplychain/platform_supply_relations_list/get_platform_supply_relations.dspy logined
/supplychain/platform_supply_relations_list/index.ui logined
/supplychain/platform_supply_relations_list/update_platform_supply_relations.dspy logined
/supplychain/product_supplier_mapping_list logined
/supplychain/product_supplier_mapping_list/add_product_supplier_mapping.dspy logined
/supplychain/product_supplier_mapping_list/delete_product_supplier_mapping.dspy logined
/supplychain/product_supplier_mapping_list/get_product_supplier_mapping.dspy logined
/supplychain/product_supplier_mapping_list/index.ui logined
/supplychain/product_supplier_mapping_list/update_product_supplier_mapping.dspy logined
/supplychain/sales_ledger_list logined
/supplychain/sales_ledger_list/add_sales_ledger.dspy logined
/supplychain/sales_ledger_list/delete_sales_ledger.dspy logined
/supplychain/sales_ledger_list/get_sales_ledger.dspy logined
/supplychain/sales_ledger_list/index.ui logined
/supplychain/sales_ledger_list/update_sales_ledger.dspy logined
/supplychain/sub_distributors_list logined
/supplychain/sub_distributors_list/add_sub_distributors.dspy logined
/supplychain/sub_distributors_list/delete_sub_distributors.dspy logined
/supplychain/sub_distributors_list/get_sub_distributors.dspy logined
/supplychain/sub_distributors_list/index.ui logined
/supplychain/sub_distributors_list/update_sub_distributors.dspy logined
/supplychain/sub_resellers_list logined
/supplychain/sub_resellers_list/add_sub_resellers.dspy logined
/supplychain/sub_resellers_list/delete_sub_resellers.dspy logined
/supplychain/sub_resellers_list/get_sub_resellers.dspy logined
/supplychain/sub_resellers_list/index.ui logined
/supplychain/sub_resellers_list/update_sub_resellers.dspy logined
/supplychain/supplier_resource_price_list logined
/supplychain/supplier_resource_price_list/index.ui logined
/supplychain/suppliers_list logined
/supplychain/suppliers_list/add_suppliers.dspy logined
/supplychain/suppliers_list/delete_suppliers.dspy logined
/supplychain/suppliers_list/get_suppliers.dspy logined
/supplychain/suppliers_list/index.ui logined
/supplychain/suppliers_list/update_suppliers.dspy logined
/supplychain/supply_contract_items_list logined
/supplychain/supply_contract_items_list/add_supply_contract_items.dspy logined
/supplychain/supply_contract_items_list/delete_supply_contract_items.dspy logined
/supplychain/supply_contract_items_list/get_supply_contract_items.dspy logined
/supplychain/supply_contract_items_list/index.ui logined
/supplychain/supply_contract_items_list/update_supply_contract_items.dspy logined
/supplychain/supply_contracts_list logined
/supplychain/supply_contracts_list/add_supply_contracts.dspy logined
/supplychain/supply_contracts_list/delete_supply_contracts.dspy logined
/supplychain/supply_contracts_list/get_supply_contracts.dspy logined
/supplychain/supply_contracts_list/index.ui logined
/supplychain/supply_contracts_list/update_supply_contracts.dspy logined
/supplychain/supplychain_accounting_list logined
/supplychain/supplychain_accounting_list/add_supplychain_accounting.dspy logined
/supplychain/supplychain_accounting_list/delete_supplychain_accounting.dspy logined
/supplychain/supplychain_accounting_list/get_supplychain_accounting.dspy logined
/supplychain/supplychain_accounting_list/index.ui logined
/supplychain/supplychain_accounting_list/update_supplychain_accounting.dspy logined
/supplychain/accounting.ui logined
/supplychain/distribution_agreements.ui logined
/supplychain/index.ui logined /supplychain/index.ui logined
/supplychain/menu.ui logined
/supplychain/provider_detail_reconcile.ui logined
/supplychain/provider_recharge.ui logined
/supplychain/provider_reconcile.ui logined
/supplychain/provider_settlement.ui logined
/supplychain/reseller_detail_reconcile.ui logined
/supplychain/reseller_reconcile.ui logined
/supplychain/reseller_settlement.ui logined
/supplychain/sub_distributors.ui logined
/supplychain/suppliers.ui logined
/supplychain/supply_contracts.ui logined
/supplychain/add_provider_recharge.dspy logined
/supplychain/add_provider_settlement.dspy logined
/supplychain/get_provider_detail_reconcile.dspy logined
/supplychain/get_provider_recharge.dspy logined
/supplychain/get_provider_reconcile.dspy logined
/supplychain/get_provider_settlement.dspy logined
/supplychain/get_reseller_detail_reconcile.dspy logined
/supplychain/get_reseller_reconcile.dspy logined
/supplychain/get_reseller_settlement.dspy logined
/supplychain/update_provider_recharge.dspy logined
/supplychain/update_provider_settlement.dspy logined
/supplychain/update_reseller_settlement.dspy logined
/imgs/supply_contract_items.svg any
/imgs/supply_contracts.svg any
/imgs/contract_attach.svg any
/imgs/distribution_agreement_items.svg any
/imgs/sub_resellers.svg any
/imgs/sub_distributors.svg any
/imgs/suppliers.svg any
/imgs/globe.svg any
/imgs/setting.svg any
/imgs/userrole.svg any
/appbase/get_code.dspy logined
/appbase/get_icon.dspy logined
/shell_theme.css any /shell_theme.css any
/shell_theme.js any /shell_theme.js any
/download/** logined
/global_menu.ui logined /global_menu.ui logined
/shell.ui logined /shell.ui logined
/index.ui any /index.ui any
@ -1487,47 +1143,6 @@ paths="""/ any
/dashboard_for_sage/table_top_providers_count.ui logined /dashboard_for_sage/table_top_providers_count.ui logined
/dashboard_for_sage/table_top_users_count.ui logined /dashboard_for_sage/table_top_users_count.ui logined
/dashboard_for_sage/chart_top_models.ui logined /dashboard_for_sage/chart_top_models.ui logined
/hotspot logined
/hotspot/index.ui logined
/hotspot/stats.dspy logined
/hotspot/fetch_now.dspy logined
/hotspot/analyze.dspy logined
/hotspot_source logined
/hotspot_source/index.ui logined
/hotspot_source/get_hotspot_source.dspy logined
/hotspot_source/add_hotspot_source.dspy logined
/hotspot_source/update_hotspot_source.dspy logined
/hotspot_source/delete_hotspot_source.dspy logined
/hotspot_item logined
/hotspot_item/index.ui logined
/hotspot_item/get_hotspot_item.dspy logined
/hotspot_item/add_hotspot_item.dspy logined
/hotspot_item/update_hotspot_item.dspy logined
/hotspot_item/delete_hotspot_item.dspy logined
/hotspot_analysis logined
/hotspot_analysis/index.ui logined
/hotspot_analysis/get_hotspot_analysis.dspy logined
/hotspot_analysis/add_hotspot_analysis.dspy logined
/hotspot_analysis/update_hotspot_analysis.dspy logined
/hotspot_analysis/delete_hotspot_analysis.dspy logined
/hotspot_schedule logined
/hotspot_schedule/index.ui logined
/hotspot_schedule/get_hotspot_schedule.dspy logined
/hotspot_schedule/add_hotspot_schedule.dspy logined
/hotspot_schedule/update_hotspot_schedule.dspy logined
/hotspot_schedule/delete_hotspot_schedule.dspy logined
/hotspot_fetch_log logined
/hotspot_fetch_log/index.ui logined
/hotspot_fetch_log/get_hotspot_fetch_log.dspy logined
/hotspot_fetch_log/add_hotspot_fetch_log.dspy logined
/hotspot_fetch_log/update_hotspot_fetch_log.dspy logined
/hotspot_fetch_log/delete_hotspot_fetch_log.dspy logined
/hotspot_alert logined
/hotspot_alert/index.ui logined
/hotspot_alert/get_hotspot_alert.dspy logined
/hotspot_alert/add_hotspot_alert.dspy logined
/hotspot_alert/update_hotspot_alert.dspy logined
/hotspot_alert/delete_hotspot_alert.dspy logined
""" """
@ -1579,7 +1194,7 @@ async def main():
cnt = 0 cnt = 0
async with db.sqlorContext('sage') as sor: async with db.sqlorContext('sage') as sor:
for l in paths.split('\n'): for l in paths.split('\n'):
if not l or l.startswith('#'): if not l:
continue continue
parts = l.split() parts = l.split()
path = parts[0] path = parts[0]

View File

@ -1,5 +0,0 @@
for s in $(ls ls pkgs/*/scripts/load_path.py)
do
echo $s
python $s
done

View File

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDXTTNYz/VOr6KV
a74kO1Ivj30YiQ9xxASJYxpH51gtHRXO2HUKO7VVArnyMbqWEBvSdSBI/mDCoxhm
TMVxt752VzngPYhGm6M5cFXlzCDJmodnyNEjWrQjTwOZ49mSNXyhSCLzpzAs9Prx
Q6NpltYz+FFs2K9DAWkns0C4Ke0vMd5H0/Cs9pjWsQVSi1TW0bj876xrouU+4jsO
hK+WxA8sBsCdus7iuSkHjimDVYcVde/+N/WFSunY8Et5lb1mueSIL3d8EYucshF2
ZN93CqcvnEiVAycGaZqWakwgQWrtKzaVNSgq1npdycCkhy2qkwoMBk/1Ls4ZzkQW
fQc+eiBFAgMBAAECggEACF22mUStB1uDZmnJkxM/B7Wvd1M0GqHMSO5lG6Ndfy56
WQ96+zFqXWnkTqLCDLy5gaPaSk8GjlAG50q9miqfdKFbdvkAVGx0NKVgOrRQ5D4x
KF/arvrPG/Dt3Rf7R1dbhwTZK6POfaC5wF0P4Rviw1UEQCxQ7lPRGzrRUMnh4b7s
q3ceJ58wY3LB4UND0DLCMwh23XjyVPNOy3fnJ4f5sJSh9ddCcZVheNZ6YvQmucio
WPdWKUXV3phPxO6YGfIqcaNdkSUFkpQywCitmiuAcK/LqUmHV9S8CMpHodzk/U8U
BWQyq79h3imrkydssnEBhi2EYhpJcugjwA+0I8T3TQKBgQDik4ez5lLeACznCS1D
ZNHCpJFVqwVNW+VmdF9nCgyRDCixwUbBwg6fHmJiAyG4LZnsSaRQhtbTwP8Q1wnk
xefPcCFEacwkbyD/zbfsAWNYUAdnP5DB0bDOULjSP5NlMdgYfM86d99mhWRGpx1m
VSwTIeBNGGBokoivY07T5y4yFwKBgQDzQthecCwu3I2YV+3fjtBAtx47xwxP+weN
VNpowT0cJ/Uf7FB6A2P2t/A0fPOarcbuVMROdcdEeScszFQhmJxnBb0YLfotdK6M
42FHX7+dQ812Kh7+6h+mV1qzGllVeAFqur79C3uwq/MvPHaZxLwSzV+tSupjUUUx
cLUGszUGAwKBgQDaIx9rXDw77/9LD9K8J7yroLUrvVOFfwwE79VJ5qrimsozGNl+
gc6B80bVBh7Yq06d5uiDfs4lYJIxLFciIkdjt5jPvOwFx9gFb5G7bjqvM51tEg3U
DIYknCLUiNDnhG2AZek9aVtz4MkCHLJ5a1bbtKm2j9mB1FI0SXADI3eeUQKBgQDh
JcA/ABFUuhtvogpu/K5xB0s7Rop1yECAJcYUaK3Xzn/IsR73HwY5hpsS6YdKZYaW
dexPNiFdlciVZPSFN8uiaqROqddAlRstGRKjTdJ6ixOyR1/yzdzHR1iSJlQCkBS3
pOo6KJOtvChTUuHuhjEQMfdY29q+W6zwCoHyFpF/4wKBgQDiYcg8wpceWpGA1rbf
miY/tysjRe4KnFRr/4QSfIlhxubHyTuteviI92TemLWQzBmZ1iK0AimLDUGawulf
Qrnuz53SLznQs4gNoUHuP4V+0W5BFuWy0CHzoxS2fRSUNSWhdJgBJTsSpC9q+IVW
eXfGkqt1kXKZ9JP5Hjnz1FBCTg==
-----END PRIVATE KEY-----

View File

@ -1,9 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA100zWM/1Tq+ilWu+JDtS
L499GIkPccQEiWMaR+dYLR0Vzth1Cju1VQK58jG6lhAb0nUgSP5gwqMYZkzFcbe+
dlc54D2IRpujOXBV5cwgyZqHZ8jRI1q0I08DmePZkjV8oUgi86cwLPT68UOjaZbW
M/hRbNivQwFpJ7NAuCntLzHeR9PwrPaY1rEFUotU1tG4/O+sa6LlPuI7DoSvlsQP
LAbAnbrO4rkpB44pg1WHFXXv/jf1hUrp2PBLeZW9ZrnkiC93fBGLnLIRdmTfdwqn
L5xIlQMnBmmalmpMIEFq7Ss2lTUoKtZ6XcnApIctqpMKDAZP9S7OGc5EFn0HPnog
RQIDAQAB
-----END PUBLIC KEY-----

View File

@ -1,166 +0,0 @@
#!/usr/bin/env python3
"""
合并所有Sage模块的i18n内容到 wwwroot/i18n
模块清单与 build.sh 保持一致第29行 for m in ...
读取每个模块的 i18n/{lang}/msg.txt
合并输出到 wwwroot/i18n/{lang}/i18n.json + msg.txt
冲突策略 build.sh 中模块顺序后加载的覆盖先加载的
sage 自身排在首位优先级最低
"""
import json
import re
import sys
from pathlib import Path
# --- 配置 ---
SAGE_DIR = Path(__file__).resolve().parent # /d/ymq/repos/sage
REPOS_DIR = SAGE_DIR.parent # /d/ymq/repos
I18N_OUTPUT_DIR = SAGE_DIR / 'wwwroot' / 'i18n' # 输出目标
LANGS = ['zh', 'en', 'jp', 'ko'] # 支持的语言
def parse_build_sh(build_sh_path):
"""从 build.sh 中提取模块清单第29行 for m in ...
build.sh 有两个 for m in 循环
- 第21行: pip基础库apppublic, sqlor, ahserver, ...
- 第29行: Sage业务模块appbase, rbac, accounting, ...
我们取第二个业务模块 sage wwwroot 符号链接配置一致
"""
with open(build_sh_path, 'r', encoding='utf-8') as f:
content = f.read()
# 匹配所有 "for m in ..." 行 —— 只到行尾(不用 \s 防止跨行匹配到 do
matches = re.findall(r'^for m in ((?:[a-z][\w-]*[ \t]*)+)$', content, re.MULTILINE)
if len(matches) < 2:
sys.exit(f"错误: 在 build.sh 中找到 {len(matches)} 个 for m in 行期望至少2个")
# 第二个 for m in 是 Sage 业务模块清单
modules_str = matches[1]
modules = [m for m in modules_str.strip().split() if '-' not in m]
# 业务模块 → bricks最后加载优先级最高确保框架内置文本不被覆盖
# bricks 是基础框架,不在 build.sh 业务模块循环中,需手动加入
result = ['sage'] + modules + ['bricks']
return result
def find_module_i18n_dir(module_name):
"""查找模块的 i18n 目录(先查 repos/ 同级目录,再查 sage/pkgs/ 内)"""
candidate = REPOS_DIR / module_name / 'i18n'
if candidate.is_dir():
return candidate
candidate = SAGE_DIR / 'pkgs' / module_name / 'i18n'
if candidate.is_dir():
return candidate
return None
def parse_msg_txt(filepath):
"""解析 msg.txt格式: key: value每行一个"""
result = {}
if not filepath.is_file():
return result
with open(filepath, 'r', encoding='utf-8') as f:
for line in f:
line = line.rstrip('\n').rstrip('\r')
if not line:
continue
# 格式: key: value
idx = line.find(': ')
if idx > 0:
key = line[:idx]
value = line[idx+2:]
result[key] = value
else:
# 可能只有 key 没有 value或者格式不对跳过
idx = line.find(':')
if idx > 0:
key = line[:idx]
value = line[idx+1:]
result[key] = value
return result
def merge_i18n(modules):
"""合并所有模块的 i18n返回 {lang: {key: value}}"""
merged = {lang: {} for lang in LANGS}
for module_name in modules:
i18n_dir = find_module_i18n_dir(module_name)
if not i18n_dir:
print(f" [跳过] {module_name}: 未找到i18n目录")
continue
for lang in LANGS:
msg_file = i18n_dir / lang / 'msg.txt'
if msg_file.is_file():
translations = parse_msg_txt(msg_file)
count = len(translations)
before = len(merged[lang])
merged[lang].update(translations)
after = len(merged[lang])
new_keys = after - before
if new_keys > 0 or count > 0:
print(f" {module_name}/{lang}: {count}条, 新增{new_keys}个唯一key")
else:
print(f" [警告] {module_name}/{lang}: msg.txt 不存在")
return merged
def write_output(merged):
"""将合并结果写入 wwwroot/i18n/{lang}/i18n.json 和 msg.txt"""
for lang in LANGS:
lang_dir = I18N_OUTPUT_DIR / lang
lang_dir.mkdir(parents=True, exist_ok=True)
data = merged[lang]
# 写入 i18n.json前端读取此文件
json_file = lang_dir / 'i18n.json'
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent='\t')
# 同时写入 msg.txt人类可读格式
msg_file = lang_dir / 'msg.txt'
with open(msg_file, 'w', encoding='utf-8') as f:
for key, value in data.items():
f.write(f"{key}: {value}\n")
print(f" 写入: {json_file} ({len(data)} 条)")
print(f" 写入: {msg_file} ({len(data)} 条)")
def main():
build_sh_path = SAGE_DIR / 'build.sh'
if not build_sh_path.is_file():
print(f"错误: 找不到 {build_sh_path}")
sys.exit(1)
print(f"解析 build.sh: {build_sh_path}")
modules = parse_build_sh(build_sh_path)
print(f"发现 {len(modules)} 个模块:")
for m in modules:
has_i18n = (REPOS_DIR / m / 'i18n').is_dir()
status = '' if has_i18n else ''
print(f" {status} {m}")
print(f"\n开始合并 i18n...")
merged = merge_i18n(modules)
print(f"\n合并结果:")
for lang in LANGS:
print(f" {lang}: {len(merged[lang])} 个唯一key")
print(f"\n写入 wwwroot/i18n...")
write_output(merged)
print(f"\n完成!")
if __name__ == '__main__':
main()

View File

@ -1,68 +0,0 @@
import asyncio
from sqlor.dbpools import DBPools
from appPublic.jsonConfig import getConfig
from appPublic.uniqueID import getID
async def migrate():
config = getConfig('.')
db = DBPools(config.databases)
# sage数据库
dbname = 'sage'
async with db.sqlorContext(dbname) as sor:
# 1. Create table if not exists
print("Creating llm_catalog_rel table...")
create_sql = """
CREATE TABLE IF NOT EXISTS llm_catalog_rel (
id VARCHAR(32) NOT NULL PRIMARY KEY,
llmid VARCHAR(32) NOT NULL,
llmcatelogid VARCHAR(32) NOT NULL,
INDEX idx_llm (llmid),
INDEX idx_catelog (llmcatelogid)
)
"""
try:
await sor.sqlExe(create_sql, {})
print("Table llm_catalog_rel created or exists.")
except Exception as e:
print(f"Create table warning: {e}")
# 2. Migrate data
print("Migrating data...")
sql = "select id, llmcatelogid from llm where llmcatelogid is not null and llmcatelogid != ''"
rows = await sor.sqlExe(sql, {})
print(f"Found {len(rows)} records to migrate.")
migrated = 0
for r in rows:
new_id = getID()
data = {
'id': new_id,
'llmid': r['id'],
'llmcatelogid': r['llmcatelogid']
}
try:
await sor.C('llm_catalog_rel', data)
migrated += 1
except Exception as e:
print(f"Insert error for {r['id']}: {e}")
print(f"Migration complete. Migrated {migrated} records.")
# 3. Drop column
print("Dropping column llmcatelogid from llm...")
try:
await sor.sqlExe("alter table llm drop column llmcatelogid", {})
print("Column dropped.")
except Exception as e:
print(f"Drop column error: {e}")
return True
if __name__ == '__main__':
success = asyncio.get_event_loop().run_until_complete(migrate())
if success:
print('Migration complete.')
else:
print('Migration failed.')

BIN
models/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -1,83 +0,0 @@
{
"summary": [
{
"name": "apiparams",
"title": "接口参数",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "params_type",
"title": "接口名称",
"type": "str",
"length": 1
},
{
"name": "objid",
"title": "模型或实例id",
"type": "str",
"length": 32
},
{
"name": "apidataid",
"title": "父数据id",
"type": "str",
"length": 32
},
{
"name": "datatype",
"title": "数据类型",
"type": "str",
"length": 2
},
{
"name": "value",
"title": "数据值",
"type": "str",
"length": 1000
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "index",
"idxfields": [
"apidataid"
]
},
{
"name": "idx2",
"idxtype": "unique",
"idxfields": [
"apidataid",
"params_type",
"objid"
]
}
],
"codes": [
{
"field": "params_type",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='params_type'"
},
{
"field": "datatype",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='datatype'"
}
]
}

View File

@ -1,40 +0,0 @@
{
"summary": [
{
"name": "appcodes",
"title": "应用编码表",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "编码名称",
"type": "str",
"length": 255
},
{
"name": "hierarchy_flg",
"title": "多级标志",
"type": "str",
"length": 1
}
],
"codes": [
{
"field": "hierarchy_flg",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='code_hierarchy'"
}
]
}

View File

@ -1,54 +0,0 @@
{
"summary": [
{
"name": "appcodes_kv",
"title": "编码键值表",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "parentid",
"title": "父id",
"type": "str",
"length": 32
},
{
"name": "k",
"title": "键",
"type": "str",
"length": 32
},
{
"name": "v",
"title": "值",
"type": "str",
"length": 255
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "unique",
"idxfields": [
"parentid",
"k"
]
},
{
"name": "idx2",
"idxtype": "index",
"idxfields": [
"parentid"
]
}
]
}

View File

@ -1,211 +0,0 @@
{
"summary": [
{
"name": "feelog",
"title": "模型计费日志",
"primary": [
"id"
],
"catelog": "entity"
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "transdate",
"title": "交易日期",
"type": "date"
},
{
"name": "transtime",
"title": "交易时间",
"type": "timestamp"
},
{
"name": "modelinstanceid",
"title": "模型实例id",
"type": "str",
"length": 32
},
{
"name": "modeltypeid",
"title": "模型类型id",
"type": "str",
"length": 32
},
{
"name": "customerid",
"title": "客户id",
"type": "str",
"length": 32
},
{
"name": "userid",
"title": "用户id",
"type": "str",
"length": 32
},
{
"name": "pricing_mode",
"title": "计费模式",
"type": "str",
"length": 30
},
{
"name": "dialog_file",
"title": "会话文件名",
"type": "str",
"length": 400
},
{
"name": "input_tokens",
"title": "输入tokens",
"type": "long"
},
{
"name": "output_tokens",
"title": "输出tokens",
"type": "long"
},
{
"name": "other_tokens",
"title": "其他tokens",
"type": "long"
},
{
"name": "input_price",
"title": "输入价格",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "output_price",
"title": "输出价格",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "other_price",
"title": "其他价格",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "timing_price",
"title": "计次价格",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "timing_amount",
"title": "计次金额",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "input_amount",
"title": "输入金额",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "output_amount",
"title": "输出金额",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "other_amount",
"title": "其他金额",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "accounting_status",
"title": "记账状态",
"type": "str",
"length": 30
},
{
"name": "resp_time",
"title": "响应时间",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "finish_time",
"title": "完成时间",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "estimate",
"title": "评价",
"type": "short"
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "index",
"idxfields": [
"transdate"
]
},
{
"name": "idx2",
"idxtype": "index",
"idxfields": [
"customerid"
]
},
{
"name": "idx3",
"idxtype": "index",
"idxfields": [
"userid"
]
}
],
"codes": [
{
"field": "modelinstanceid",
"table": "modelinstance",
"valuefield": "id",
"textfield": "name"
},
{
"field": "modeltypeid",
"table": "modeltypes",
"valuefield": "id",
"textfield": "name"
},
{
"field": "customerid",
"table": "organization",
"valuefield": "id",
"textfield": "orgname"
},
{
"field": "userid",
"table": "users",
"valuefield": "id",
"textfield": "username"
}
]
}

View File

@ -1,110 +0,0 @@
{
"summary": [
{
"name": "httpapi",
"title": "http程序接口",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "apiname",
"title": "接口名",
"type": "str",
"length": 100
},
{
"name": "label",
"title": "接口名称",
"type": "str",
"length": 100
},
{
"name": "providerid",
"title": "接口提供方",
"type": "str",
"length": 32
},
{
"name": "apiinfo",
"title": "接口内容",
"type": "str",
"length": 4000
},
{
"name": "apinote",
"title": "接口描述",
"type": "str",
"length": 500
},
{
"name": "use_session",
"title": "带历史信息",
"type": "str",
"length": 1
},
{
"name": "response_mode",
"title": "响应模式",
"type": "str",
"length": 50
},
{
"name": "system_msg_format",
"title": "系统消息模版",
"type": "str",
"length": 1000
},
{
"name": "user_msg_format",
"title": "用户消息模版",
"type": "str",
"length": 1000
},
{
"name": "llm_msg_format",
"title": "模型消息模版",
"type": "str",
"length": 1000
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "unique",
"idxfields": [
"apiname"
]
}
],
"codes": [
{
"field": "providerid",
"table": "supplychain.suppliers",
"valuefield": "id",
"textfield": "supplier_name"
},
{
"field": "use_session",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='yesno'"
},
{
"field": "response_mode",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='resp_mode'"
}
]
}

View File

@ -1,70 +0,0 @@
{
"summary": [
{
"name": "minimax_acc",
"title": "minimax账号",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "userid",
"title": "用户id",
"type": "str",
"length": 100
},
{
"name": "acc_id",
"title": "minimax账号id",
"type": "str",
"length": 100
},
{
"name": "acc_name",
"title": "账号名称",
"type": "str",
"length": 300
},
{
"name": "password",
"title": "账号密码",
"type": "str",
"length": 100
},
{
"name": "apikey",
"title": "账号apikey",
"type": "str",
"length": 4000
},
{
"name": "groupid",
"title": "组号",
"type": "str",
"length": 100
},
{
"name": "acc_status",
"title": "账号状态",
"type": "short",
"default": 0
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "unique",
"idxfields": [
"userid"
]
}
]
}

View File

@ -1,80 +0,0 @@
{
"summary": [
{
"name": "minimax_bill",
"title": "minimax账单",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "customerid",
"title": "客户id",
"type": "str",
"length": 32
},
{
"name": "acc_id",
"title": "用户id",
"type": "str",
"length": 100
},
{
"name": "modelinstanceid",
"title": "模型实例id",
"type": "str",
"length": 100
},
{
"name": "acc_name",
"title": "账号名称",
"type": "str",
"length": 100,
"default": "0"
},
{
"name": "consume_time",
"title": "消费时间戳",
"type": "timestamp"
},
{
"name": "consume_token",
"title": "消费token数",
"type": "long"
},
{
"name": "consume_amt",
"title": "消费金额",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "create_at",
"title": "创建时间",
"type": "timestamp"
},
{
"name": "consume_date",
"title": "消费日期",
"type": "date"
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "index",
"idxfields": [
"customerid"
]
}
]
}

View File

@ -1,57 +0,0 @@
{
"summary": [
{
"name": "modelapi",
"title": "模型接口",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "modelid",
"title": "模型id",
"type": "str",
"length": 32
},
{
"name": "apiid",
"title": "接口id",
"type": "str",
"length": 32
},
{
"name": "modeltypeid",
"title": "模型类型",
"type": "str",
"length": 32
}
],
"codes": [
{
"field": "modelid",
"table": "models",
"valuefield": "id",
"textfield": "name"
},
{
"field": "apiid",
"table": "httpapi",
"valuefield": "id",
"textfield": "apiname"
},
{
"field": "modeltypeid",
"table": "modeltype",
"valuefield": "id",
"textfield": "name"
}
]
}

View File

@ -1,73 +0,0 @@
{
"summary": [
{
"name": "modelinstance",
"title": "模型实例",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "modelid",
"title": "模型id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "实例名",
"type": "str",
"length": 100
},
{
"name": "label",
"title": "实例名称",
"type": "str",
"length": 100
},
{
"name": "description",
"title": "实例说明",
"type": "str",
"length": 500
},
{
"name": "base_url",
"title": "接口ur",
"type": "str",
"length": 500
},
{
"name": "ownerid",
"title": "属主id",
"type": "str",
"length": 32
},
{
"name": "enable_date",
"title": "启动日期",
"type": "date"
},
{
"name": "expore_date",
"title": "失效日期",
"type": "date"
}
],
"codes": [
{
"field": "modelid",
"table": "models",
"valuefield": "id",
"textfield": "name"
}
]
}

View File

@ -1,69 +0,0 @@
{
"summary": [
{
"name": "modeliodata",
"title": "模型输入输出数据",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "数据名",
"type": "str",
"length": 100
},
{
"name": "label",
"title": "标题",
"type": "str",
"length": 500
},
{
"name": "datatype",
"title": "数据类型",
"type": "str",
"length": 2
},
{
"name": "uitype",
"title": "输入类型",
"type": "str",
"length": 2
},
{
"name": "length",
"title": "长度",
"type": "short"
},
{
"name": "dec",
"title": "小数点数",
"type": "short"
}
],
"codes": [
{
"field": "uitype",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='uitype'"
},
{
"field": "datatype",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='datatype'"
}
]
}

View File

@ -1,94 +0,0 @@
{
"summary": [
{
"name": "modelpricing",
"title": "模型计费",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "modelinstanceid",
"title": "模型实例id",
"type": "str",
"length": 32
},
{
"name": "modeltypeid",
"title": "模型类型id",
"type": "str",
"length": 32
},
{
"name": "enable_date",
"title": "开始日期",
"type": "date"
},
{
"name": "expired_date",
"title": "失效日期",
"type": "date"
},
{
"name": "pricing_mode",
"title": "计费类型",
"type": "str",
"length": 30
},
{
"name": "token_cnt",
"title": "token数量",
"type": "long"
},
{
"name": "input_price",
"title": "输入价格",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "output_price",
"title": "输出价格",
"type": "float",
"length": 18,
"dec": 2
},
{
"name": "timing_price",
"title": "计次价格",
"type": "float",
"length": 18,
"dec": 2
}
],
"codes": [
{
"field": "pricing_mode",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='pricing_mode'"
},
{
"field": "modelinstanceid",
"table": "modelinstance",
"valuefield": "id",
"textfield": "name"
},
{
"field": "modeltypeid",
"table": "modeltype",
"valuefield": "id",
"textfield": "name"
}
]
}

View File

@ -1,37 +0,0 @@
{
"summary": [
{
"name": "modelprovider",
"title": "模型供应商",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "供应商名",
"type": "str",
"length": 32
},
{
"name": "label",
"title": "供应商名称",
"type": "str",
"length": 32
},
{
"name": "description",
"title": "说明",
"type": "str",
"length": 500
}
]
}

View File

@ -1,57 +0,0 @@
{
"summary": [
{
"name": "models",
"title": "大模型",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "英文名",
"type": "str",
"length": 100
},
{
"name": "title",
"title": "模型名称",
"type": "str",
"length": 100
},
{
"name": "description",
"title": "模型说明",
"type": "str",
"length": 500
},
{
"name": "icon_url",
"title": "模型图标URL",
"type": "str",
"length": 500
},
{
"name": "providerid",
"title": "供应商id",
"type": "str",
"length": 32
}
],
"codes": [
{
"field": "providerid",
"table": "organization",
"valuefield": "id",
"textfield": "orgname"
}
]
}

View File

@ -1,64 +0,0 @@
{
"summary": [
{
"name": "modeltype",
"title": "模型类型",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "类型名",
"type": "str",
"length": 100
},
{
"name": "description",
"title": "类型说明",
"type": "str",
"length": 500
},
{
"name": "is_multiple",
"title": "是否多模态",
"type": "str",
"length": 1
},
{
"name": "input_fields",
"title": "输入字段",
"type": "str",
"length": 4000
},
{
"name": "input_view",
"title": "输入显示",
"type": "str",
"length": 4000
},
{
"name": "output_view",
"title": "输出显示",
"type": "str",
"length": 4000
}
],
"codes": [
{
"field": "is_multiple",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='yesno'"
}
]
}

View File

@ -1,46 +0,0 @@
{
"summary": [
{
"name": "modeltypein",
"title": "模型类型输入数据",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "modeltypeid",
"title": "模型类型id",
"type": "str",
"length": 32
},
{
"name": "iodataid",
"title": "io数据id",
"type": "str",
"length": 32
},
{
"name": "required",
"title": "是否必须",
"type": "str",
"length": 1
}
],
"codes": [
{
"field": "required",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='yesno'"
}
]
}

View File

@ -1,37 +0,0 @@
{
"summary": [
{
"name": "modeltypeout",
"title": "模型类型输出数据",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "modeltypeid",
"title": "模型类型id",
"type": "str",
"length": 32
},
{
"name": "iodataid",
"title": "io数据id",
"type": "str",
"length": 32
},
{
"name": "resp_keys",
"title": "在响应包中的位置",
"type": "str",
"length": 1
}
]
}

View File

@ -6578,151 +6578,4 @@ default charset=utf8
comment '模型供应商' comment '模型供应商'
; ;
-- ============================================
-- 热点雷达系统 - 6 tables
-- ============================================
-- ./hotspot_source (来源配置: API / Browser / Crawler)
drop table if exists hotspot_source;
CREATE TABLE hotspot_source
(
`id` VARCHAR(32) comment 'id',
`name` VARCHAR(200) comment '来源名称',
`type` VARCHAR(20) comment '类型: rss/api/browser/crawler',
`url` VARCHAR(2000) comment '目标URL',
-- API 类型专用
`api_key` VARCHAR(500) comment 'API Key',
`api_secret` VARCHAR(500) comment 'API Secret(加密)',
`headers` TEXT comment '自定义请求头 JSON',
`fetch_method` VARCHAR(10) DEFAULT 'GET' comment 'HTTP方法',
`request_body` TEXT comment 'POST请求体',
-- Browser 类型专用
`browser_headless` VARCHAR(1) DEFAULT '1' comment '无头模式',
`browser_wait_selector` VARCHAR(500) comment '等待元素选择器',
`browser_scroll` VARCHAR(1) DEFAULT '0' comment '是否自动滚动',
-- Crawler 类型专用
`crawler_depth` INT DEFAULT 1 comment '爬取深度',
`crawler_rules` TEXT comment '爬取规则 JSON',
`crawler_start_urls` TEXT comment '起始URL列表 JSON',
-- 通用
`proxy_enabled` VARCHAR(1) DEFAULT '0' comment '启用代理',
`proxy_url` VARCHAR(500) comment '代理地址',
`parser_config` TEXT comment '提取规则 JSON: parser/item_path/field_map/builtin_name',
`enabled` VARCHAR(1) DEFAULT '1' comment '是否启用',
`priority` INT DEFAULT 0 comment '优先级(越大越高)',
`last_fetch` VARCHAR(50) comment '上次抓取时间',
`created_at` VARCHAR(50) comment '创建时间'
,primary key(id)
)
engine=innodb default charset=utf8 comment '热点来源配置'
;
-- ./hotspot_schedule (调度配置)
drop table if exists hotspot_schedule;
CREATE TABLE hotspot_schedule
(
`id` VARCHAR(32) comment 'id',
`source_id` VARCHAR(32) comment '关联来源ID',
`cron_expr` VARCHAR(100) comment 'cron表达式',
`interval_min` INT DEFAULT 60 comment '间隔(分钟)',
`enabled` VARCHAR(1) DEFAULT '1' comment '是否启用',
`last_run` VARCHAR(50) comment '上次运行',
`next_run` VARCHAR(50) comment '下次运行',
`retry_max` INT DEFAULT 3 comment '最大重试',
`retry_count` INT DEFAULT 0 comment '已重试次数'
,primary key(id)
)
engine=innodb default charset=utf8 comment '调度配置'
;
CREATE INDEX hotspot_schedule_source_idx ON hotspot_schedule(source_id);
-- ./hotspot_fetch_log (抓取日志)
drop table if exists hotspot_fetch_log;
CREATE TABLE hotspot_fetch_log
(
`id` VARCHAR(32) comment 'id',
`source_id` VARCHAR(32) comment '关联来源ID',
`start_time` VARCHAR(50) comment '开始时间',
`end_time` VARCHAR(50) comment '结束时间',
`duration_ms` INT DEFAULT 0 comment '耗时(毫秒)',
`status` VARCHAR(20) comment '状态: success/failed/partial',
`items_total` INT DEFAULT 0 comment '抓取总数',
`items_new` INT DEFAULT 0 comment '新增数量',
`items_duplicate` INT DEFAULT 0 comment '重复数量',
`error_msg` TEXT comment '错误信息',
`response_code` INT comment 'HTTP状态码',
`response_size_bytes` INT DEFAULT 0 comment '响应大小'
,primary key(id)
)
engine=innodb default charset=utf8 comment '抓取日志'
;
CREATE INDEX hotspot_fetch_log_source_idx ON hotspot_fetch_log(source_id);
CREATE INDEX hotspot_fetch_log_status_idx ON hotspot_fetch_log(status);
-- ./hotspot_item (热点条目)
drop table if exists hotspot_item;
CREATE TABLE hotspot_item
(
`id` VARCHAR(32) comment 'id',
`source_id` VARCHAR(32) comment '来源ID',
`title` VARCHAR(500) comment '标题',
`url` VARCHAR(2000) comment '原文链接',
`summary` TEXT comment '摘要',
`content` TEXT comment '正文',
`heat_score` DOUBLE(10,2) DEFAULT 0 comment '热度分数',
`heat_velocity` DOUBLE(10,2) DEFAULT 0 comment '热度加速度',
`publish_time` VARCHAR(50) comment '发布时间',
`first_seen` VARCHAR(50) comment '首次发现',
`last_updated` VARCHAR(50) comment '最后更新',
`status` VARCHAR(20) DEFAULT 'emerging' comment '状态: emerging/rising/hot/cooling/expired',
`category` VARCHAR(100) comment '分类',
`tags` VARCHAR(500) comment '标签',
`engagement_count` INT DEFAULT 0 comment '互动数',
`comment_count` INT DEFAULT 0 comment '评论数',
`share_count` INT DEFAULT 0 comment '转发数',
`sentiment` VARCHAR(20) DEFAULT 'neutral' comment '情感: positive/negative/neutral',
`is_verified` VARCHAR(1) DEFAULT '0' comment '是否已验证',
`duplicate_of` VARCHAR(32) comment '重复于(另一热点ID)'
,primary key(id)
)
engine=innodb default charset=utf8 comment '热点条目'
;
CREATE INDEX hotspot_item_source_idx ON hotspot_item(source_id);
CREATE INDEX hotspot_item_status_idx ON hotspot_item(status);
CREATE INDEX hotspot_item_score_idx ON hotspot_item(heat_score);
-- ./hotspot_analysis (五维分析)
drop table if exists hotspot_analysis;
CREATE TABLE hotspot_analysis
(
`id` VARCHAR(32) comment 'id',
`item_id` VARCHAR(32) comment '关联热点ID',
`dimension` VARCHAR(50) comment '维度: time/heat/content/propagation/audience',
`score` DOUBLE(10,2) DEFAULT 0 comment '维度得分(0-100)',
`analysis_data` TEXT comment '分析数据JSON',
`analyzed_at` VARCHAR(50) comment '分析时间'
,primary key(id)
)
engine=innodb default charset=utf8 comment '五维分析'
;
CREATE INDEX hotspot_analysis_item_idx ON hotspot_analysis(item_id);
-- ./hotspot_alert (预警规则)
drop table if exists hotspot_alert;
CREATE TABLE hotspot_alert
(
`id` VARCHAR(32) comment 'id',
`name` VARCHAR(200) comment '规则名称',
`source_id` VARCHAR(32) comment '来源ID(空=全局)',
`condition_type` VARCHAR(50) comment '条件: heat_threshold/velocity/sentiment/status_change',
`condition_value` VARCHAR(500) comment '条件值 JSON',
`enabled` VARCHAR(1) DEFAULT '1' comment '是否启用',
`notify_method` VARCHAR(50) comment '通知方式: email/webhook/sms',
`notify_target` VARCHAR(500) comment '通知目标',
`last_triggered` VARCHAR(50) comment '上次触发时间'
,primary key(id)
)
engine=innodb default charset=utf8 comment '预警规则'
;

View File

@ -1,43 +0,0 @@
{
"summary": [
{
"name": "org_roles",
"title": "机构角色",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "orgid",
"title": "机构编码",
"type": "str",
"length": 32
},
{
"name": "roleid",
"title": "角色编码",
"type": "str",
"length": 32
},
{
"name": "del_flg",
"title": "删除标志",
"type": "str",
"length": 1,
"default": "0"
},
{
"name": "create_at",
"title": "创建时间戳",
"type": "timestamp"
}
]
}

View File

@ -1,127 +0,0 @@
{
"summary": [
{
"name": "organization",
"title": "机构",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "机构编码",
"type": "str",
"length": 32
},
{
"name": "orgname",
"title": "机构名称",
"type": "str",
"length": 100
},
{
"name": "alias_name",
"title": "机构别名",
"type": "str",
"length": 100
},
{
"name": "contactor",
"title": "联系人",
"type": "str",
"length": 32
},
{
"name": "contactor_phone",
"title": "联系人电话",
"type": "str",
"length": 100
},
{
"name": "province_id",
"title": "所在省id",
"type": "str",
"length": 32
},
{
"name": "city_id",
"title": "所在城市id",
"type": "str",
"length": 32
},
{
"name": "distinct_id",
"title": "所在地区id",
"type": "str",
"length": 32
},
{
"name": "emailaddress",
"title": "邮箱",
"type": "str",
"length": 256
},
{
"name": "address",
"title": "地址",
"type": "str",
"length": 400
},
{
"name": "main_business",
"title": "主营业务描述",
"type": "str",
"length": 1000
},
{
"name": "orgcode",
"title": "组织结构代码",
"type": "str",
"length": 100
},
{
"name": "license_img",
"title": "营业执照",
"type": "str",
"length": 400
},
{
"name": "id_img",
"title": "身份证",
"type": "str",
"length": 400
},
{
"name": "parentid",
"title": "父机构id",
"type": "str",
"length": 32
},
{
"name": "org_type",
"title": "机构类型",
"type": "str",
"length": 32
},
{
"name": "accountid",
"title": "账号",
"type": "str",
"length": 32
},
{
"name": "del_flg",
"title": "删除标志",
"type": "str",
"length": 1,
"default": "0"
},
{
"name": "create_at",
"title": "创建时间戳",
"type": "timestamp"
}
]
}

View File

@ -1,40 +0,0 @@
{
"summary": [
{
"name": "orgtypes",
"title": "机构拥有角色",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "orgid",
"title": "机构id",
"type": "str",
"length": 32
},
{
"name": "orgtypeid",
"title": "机构类型",
"type": "str",
"length": 100
}
],
"codes": [
{
"field": "orgtypeid",
"table": "appcodes_kv",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='org_type'"
}
]
}

View File

@ -1,77 +0,0 @@
{
"summary": [
{
"name": "permission",
"title": "权限",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "权限id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "名称",
"type": "str",
"length": 255
},
{
"name": "description",
"title": "描述",
"type": "str",
"length": 255
},
{
"name": "ptype",
"title": "类型",
"type": "str",
"length": 20
},
{
"name": "parentid",
"title": "父权限id",
"type": "str",
"length": 32
},
{
"name": "path",
"title": "路径",
"type": "str",
"length": 255
},
{
"name": "title",
"title": "标题",
"type": "str",
"length": 255
},
{
"name": "icon",
"title": "图标",
"type": "str",
"length": 255
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "index",
"idxfields": [
"ptype"
]
},
{
"name": "idx2",
"idxtype": "index",
"idxfields": [
"parentid"
]
}
]
}

View File

@ -1,57 +0,0 @@
{
"summary": [
{
"name": "role",
"title": " 角色",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "角色id",
"type": "str",
"length": 32
},
{
"name": "orgtypeid",
"title": "机构类型",
"type": "str",
"length": 32,
"default": "0"
},
{
"name": "role",
"title": "角色",
"type": "str",
"length": 100
},
{
"name": "rolelabel",
"title": "角色名称",
"type": "str",
"length": 100
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "unique",
"idxfields": [
"orgtypeid",
" role"
]
}
],
"codes": [
{
"field": "orgtypeid",
"table": "appcodes_kw",
"valuefield": "k",
"textfield": "v",
"cond": "parentid='org_type'"
}
]
}

View File

@ -1,31 +0,0 @@
{
"summary": [
{
"name": "rolepermission",
"title": "角色权限表",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "roleid",
"title": "角色id",
"type": "str",
"length": 32
},
{
"name": "permid",
"title": "权限id",
"type": "str",
"length": 32
}
]
}

View File

@ -1,91 +0,0 @@
{
"summary": [
{
"name": "token_usgae",
"title": "token使用表",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "customerid",
"title": "客户id",
"type": "str",
"length": 32
},
{
"name": "userid",
"title": "用户id",
"type": "str",
"length": 32
},
{
"name": "callname",
"title": "调用名",
"type": "str",
"length": 100
},
{
"name": "modelinstanceid",
"title": "模型实例id",
"type": "str",
"length": 255
},
{
"name": "u_date",
"title": "使用日期",
"type": "date",
"length": 255
},
{
"name": "u_time",
"title": "使用时间",
"type": "timestamp",
"length": 32
},
{
"name": "input_usage",
"title": "输入token数",
"type": "long"
},
{
"name": "output_usage",
"title": "输出token数",
"type": "long"
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "index",
"idxfields": [
"userid"
]
},
{
"name": "idx2",
"idxtype": "index",
"idxfields": [
"customerid",
"userid",
"modelinstanceid"
]
},
{
"name": "idx3",
"idxtype": "index",
"idxfields": [
"customerid",
"modelinstanceid"
]
}
]
}

View File

@ -1,94 +0,0 @@
{
"summary": [
{
"name": "userapikey",
"title": "用户api密码表",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "providerid",
"title": "供应商id",
"type": "str",
"length": 200
},
{
"name": "ownerid",
"title": "属主id",
"type": "str",
"length": 32,
"default": "0"
},
{
"name": "apikey",
"title": "api密钥",
"type": "str",
"length": 4000,
"default": "0"
},
{
"name": "secretkey",
"title": "附属密钥",
"type": "str",
"length": 4000
},
{
"name": "rfname",
"title": "函数名",
"type": "str",
"length": 400
},
{
"name": "apiuser",
"title": "api用户",
"type": "str",
"length": 100
},
{
"name": "apipasswd",
"title": "api密码",
"type": "str",
"length": 32
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "unique",
"idxfields": [
"providerid",
"customerid"
]
},
{
"name": "idx2",
"idxtype": "index",
"idxfields": [
"customerid"
]
}
],
"codes": [
{
"field": "providerid",
"table": "organization",
"valuefield": "id",
"textfield": "orgname"
},
{
"field": "ownerid",
"table": "organization",
"valuefield": "id",
"textfield": "orgname"
}
]
}

View File

@ -1,43 +0,0 @@
{
"summary": [
{
"name": "userdepartment",
"title": "用户部门表",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "userid",
"title": "用户id",
"type": "str",
"length": 32
},
{
"name": "depid",
"title": "部门id",
"type": "str",
"length": 32
},
{
"name": "del_flg",
"title": "删除标志",
"type": "str",
"length": 1,
"default": "0"
},
{
"name": "create_at",
"title": "创建时间戳",
"type": "timestamp"
}
]
}

View File

@ -1,45 +0,0 @@
{
"summary": [
{
"name": "userrole",
"title": "用户角色",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "用户id",
"type": "str",
"length": 32
},
{
"name": "userid",
"title": "用户id",
"type": "str",
"length": 32
},
{
"name": "roleid",
"title": "角色id",
"type": "str",
"length": 32
}
],
"codes": [
{
"field": "userid",
"table": "users",
"valuefield": "id",
"textfield": "username"
},
{
"field": "roleid",
"table": "role",
"valuefield": "id",
"textfield": "role"
}
]
}

View File

@ -1,90 +0,0 @@
{
"summary": [
{
"name": "users",
"title": "用户",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "用户id",
"type": "str",
"length": 32
},
{
"name": "username",
"title": "用户名",
"type": "str",
"length": 255
},
{
"name": "name",
"title": "姓名",
"type": "str",
"length": 255
},
{
"name": "password",
"title": "密码",
"type": "str",
"length": 255
},
{
"name": "email",
"title": "邮件地址",
"type": "str",
"length": 255
},
{
"name": "orgid",
"title": "所属机构",
"type": "str",
"length": 32
},
{
"name": "nick_name",
"title": "显示名",
"type": "str",
"length": 255
},
{
"name": "address",
"title": "地址",
"type": "str",
"length": 255
},
{
"name": "mobile",
"title": "手机",
"type": "str",
"length": 255
},
{
"name": "user_status",
"title": "用户状态",
"type": "str",
"length": 1,
"default": "0"
}
],
"indexes": [
{
"name": "idx1",
"idxtype": "index",
"idxfields": [
"orgid"
]
},
{
"name": "idx2",
"idxtype": "unique",
"idxfields": [
"username"
]
}
]
}

View File

@ -1,51 +0,0 @@
{
"summary": [
{
"name": "xterm",
"title": "终端",
"primary": [
"id"
]
}
],
"fields": [
{
"name": "id",
"title": "id",
"type": "str",
"length": 32
},
{
"name": "name",
"title": "终端名称",
"type": "str",
"length": 400
},
{
"name": "hostid",
"title": "描述",
"type": "str",
"length": 500
},
{
"name": "ownerid",
"title": "属主id",
"type": "str",
"length": 32
},
{
"name": "cmd",
"title": "命令",
"type": "str",
"length": 2000
}
],
"codes": [
{
"field": "hostid",
"table": "hostdev",
"valuefield": "id",
"textfield": "name"
}
]
}

View File

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDLwRhu06ULipoH
eO89TdCMUiGsafCqzbLlCVDxRcHXLZV4fiNQAwVLonYHZnlNq/kYzJbsXWyqz+FF
RanbD47JSPlMPGZOoYZ2ANVLQIk8OD9RfWjuDcw/0RtjmiaPnqgRZluNU7gvWYEF
+JBFTHiGUKdopuR5rVctq37b64azB6XsGRmQfvmuoG2bW/SIngnI1ReBR9W3Jhf6
lFG3EaW6VaW12JbgbHGC+UwjzlzQYJgeaKOyCLXvo6fGnqZ1dgQy/Fs5YmGX6emT
VO6t+Sgh1ipJeWl3192g+ntLzkokjtjsUw1UVXkPMCOsuo8tVN7upgK+ubDtMv5P
pPxAWYuzAgMBAAECggEAFgFE0r9KbVcq2xC9VwkUM1CxcKNBCdP3nz26Kfx8epvi
hHtW8/lc3+DBT3uf29AYBwzIEJSRu6wsv474+6llTylxkcFaKTbPmedCzILr71Qs
c8VlXi72S+luRFEDG3KpOGEuFQghdaz8aWPWrO1H0ksGnB+eFY1aGMVoiMwZ0DQb
asXW52rbuS/fpC5cg3ydsz6icDHyb/J1Zqp/UeHTL36Wl6pg+CDcKeYIWJ4tb//F
IGW4xvN3s49HqhtYK0VUNTP3dyabyLb9VQFLuAEJpdjZHQgzeqgHugRv1RVGzIls
SX2lRJz2e13W6Zp/TNtBKYfOaNLsHG4O4wawpkvmzQKBgQDiYvVLe+HwRgEIZciB
q6Jo9E8D3BCar3Wl6AFyNqePI32XaYazJwbXt4Ir9VRExFAL0gFfe8BWlk3ZJSvl
I6orE9Wc0J5/qHGasim4Jhs8YQhBj3sEo964RCgM88Aj5aQAsgQ0LtM3u9kcwju/
c5mXEYyzwBrodbPm6Tz8ZTFOJQKBgQDmaD8nlYkJPP4zgTSvKCZnWBuCa35mn7TV
ZqD0mUNzdE3ySClVORxV3AxBOQaDV8cJFqGWz3NfSBtzthUe/NpUI2IDWYFNp2SO
2eNcV0Oiq9m1LXiGZfO4AMui+0iALm2e+ArVqjewVc5QsPiuY4aztci1IcPH0jJi
Dm2CRuKu9wKBgDIa5uGLDKmqRMZACM2yWCLUl7xp837ZALf0joVh1VoX588gOwDh
zWDnK7dg+AK0VGcZVtZ0RFCluZsq3/k6GIqqPCgWAE6O0H4Fmrg4LuUBMNuZzwdq
4Xt1Ekwzkr4fMFo7DDUke/kk6Vu1HZY1FrRZ3QNXrFzw2B1uV+Ig33XFAoGAHWM4
gu0AwIvmBF27gYfGdjH3uEfLpH1ETF+9sdUGlGhGNNvdYcBaC914Nq12VjRQ76jS
TXECTyncToLv6LbphgfJTZIR+vyZx9qktDdxKgNvTjuRftrsHhED6DLSyX6ifr82
apA+cCBRo1sfLOcG3E8YXXoEBa2avYUHlLFD4nsCgYB/7t/ZukC100AInglfUW68
QXSNZTm7hk7N3mdZ83KQ5FarihdNWOAixy/0I0KMgr8QDDzDj8rlcODl0hLlyJta
0D3nb94Kzq86TFjX3t9vSfXJnGzIqhFY63QEegOcGuALGH3fp6GQUV7rUty831q/
XbjVeIOQP4Rbda60fSDAYg==
-----END PRIVATE KEY-----

View File

@ -1,50 +0,0 @@
import asyncio
from sqlor.dbpools import DBPools
from appPublic.jsonConfig import getConfig
from ahserver.globalEnv import password_encode
async def reset_superuser_password():
config = getConfig('.')
db = DBPools(config.databases)
# 直接使用sage数据库从配置看只有一个sage数据库
# rbac模块的表应该也在sage数据库中
dbname = 'sage'
new_password = 'admin123'
encoded_password = password_encode(new_password)
async with db.sqlorContext(dbname) as sor:
# 先检查superuser是否存在
users = await sor.R('users', {'username': 'superuser'})
if not users:
print('superuser用户不存在')
return False
user = users[0]
print(f'找到用户: id={user.id}, username={user.username}')
# 更新密码
ns = {
'id': user.id,
'password': encoded_password
}
await sor.U('users', ns)
print(f'密码已更新为新密码: {new_password}')
# 验证更新 - 使用sqlExe直接查询
verify_sql = "select username from users where username='superuser' and password=${password}$"
verify_result = await sor.sqlExe(verify_sql, {'password': encoded_password})
if verify_result:
print('密码验证成功')
else:
print('密码验证失败')
return True
if __name__ == '__main__':
success = asyncio.get_event_loop().run_until_complete(reset_superuser_password())
if success:
print('superuser密码重置完成')
else:
print('密码重置失败')

View File

@ -1,16 +0,0 @@
[Unit]
Wants=systemd-networkd.service
[Service]
User=hermesai
Group=hermesai
Type=forking
WorkingDirectory=/home/hermesai/repos/sage
ExecStart=/home/hermesai/repos/sage/start.sh
ExecStop=/home/hermesai/repos/sage/stop.sh
StandardOutput=append:/var/log/sage/sage.log
StandardError=append:/var/log/sage/sage.log
SyslogIdentifier=sage
[Install]
WantedBy=multi-user.target

View File

@ -1,49 +0,0 @@
#!/bin/bash
# Deploy sage shell files to production wwwroot
# Usage: bash ~/sage/script/deploy_shell.sh
#
# This script copies index.ui and global_menu.ui from the git repo
# to the production wwwroot directory (which is gitignored).
set -e
SAGE_DIR="${SAGE_HOME:-$HOME/sage}"
SAGE_WWWROOT="$SAGE_DIR/wwwroot"
SAGE_REPO="$HOME/repos/sage/wwwroot"
echo "Deploying sage shell files..."
echo "Source: $SAGE_REPO"
echo "Target: $SAGE_WWWROOT"
echo ""
# Ensure wwwroot exists
mkdir -p "$SAGE_WWWROOT"
# Copy index.ui
if [ -f "$SAGE_REPO/index.ui" ]; then
cp "$SAGE_REPO/index.ui" "$SAGE_WWWROOT/index.ui"
echo "✓ index.ui (Shell layout with sidebar)"
else
echo "✗ index.ui not found in $SAGE_REPO"
exit 1
fi
# Copy global_menu.ui
if [ -f "$SAGE_REPO/global_menu.ui" ]; then
cp "$SAGE_REPO/global_menu.ui" "$SAGE_WWWROOT/global_menu.ui"
echo "✓ global_menu.ui (Global navigation menu)"
else
echo "✗ global_menu.ui not found in $SAGE_REPO"
exit 1
fi
# Remove old symlinks if exist
rm -f "$SAGE_WWWROOT/dashboard_for_sage" 2>/dev/null || true
echo ""
echo "Deployed to $SAGE_WWWROOT/"
echo ""
echo "Next steps:"
echo " 1. cd ~/repos/dashboard_for_sage && git pull"
echo " 2. cd ~/repos/bricks && git pull && bash build.sh"
echo " 3. cd ~/sage && ./stop.sh && ./start.sh"

View File

@ -1,118 +0,0 @@
#!/usr/bin/env python3
"""
合并所有模块的i18n到wwwroot/i18n目录
用法: python3 script/merge_i18n.py
"""
import os
import json
from pathlib import Path
from collections import OrderedDict
def parse_msg_txt(filepath):
"""解析msg.txt文件返回字典"""
result = OrderedDict()
if not os.path.exists(filepath):
return result
with open(filepath, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if ':' in line:
key, value = line.split(':', 1)
result[key.strip()] = value.strip()
return result
def write_msg_txt(data, filepath):
"""写入msg.txt文件"""
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'w', encoding='utf-8') as f:
for key, value in data.items():
f.write(f"{key}: {value}\n")
def write_i18n_json(data, filepath):
"""写入i18n.json文件"""
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def get_modules_from_lnwww():
"""从lnwww.sh读取模块列表"""
lnwww_path = Path(__file__).parent.parent / 'wwwroot' / 'lnwww.sh'
if not lnwww_path.exists():
print(f"警告: {lnwww_path} 不存在")
return []
modules = []
with open(lnwww_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line.startswith('for m in'):
# "for m in xxx yyy zzz" -> "xxx yyy zzz"
parts = line.split('for m in ', 1)[1].strip().split()
modules = [p for p in parts if p != 'do']
break
return modules
def merge_i18n():
"""主函数合并i18n"""
sage_root = Path(__file__).parent.parent
wwwroot_i18n = sage_root / 'wwwroot' / 'i18n'
base_i18n = sage_root / 'i18n'
# 获取模块列表
modules = get_modules_from_lnwww()
print(f"发现模块: {', '.join(modules)}")
# 语言列表
languages = ['zh', 'en', 'jp', 'ko']
for lang in languages:
print(f"\n处理语言: {lang}")
# 从基础i18n开始
merged = OrderedDict()
base_msg = base_i18n / lang / 'msg.txt'
if base_msg.exists():
merged.update(parse_msg_txt(base_msg))
print(f" ✓ 加载基础i18n: {len(merged)}")
# 合并每个模块的i18n
for module in modules:
# 模块可能在 ~/py/<module>/i18n 或 ~/repos/<module>/i18n
module_i18n_paths = [
Path.home() / 'py' / module / 'i18n' / lang / 'msg.txt',
Path.home() / 'repos' / module / 'i18n' / lang / 'msg.txt',
]
for msg_path in module_i18n_paths:
if msg_path.exists():
before = len(merged)
merged.update(parse_msg_txt(msg_path))
added = len(merged) - before
print(f"{module}: +{added} 条 (共 {len(merged)} 条)")
break
# 写入结果
out_msg = wwwroot_i18n / lang / 'msg.txt'
out_json = wwwroot_i18n / lang / 'i18n.json'
write_msg_txt(merged, out_msg)
write_i18n_json(merged, out_json)
print(f" → 写入 {out_msg}")
print(f" → 写入 {out_json}")
print("\n✓ 合并完成")
if __name__ == '__main__':
merge_i18n()

View File

@ -1,29 +0,0 @@
# Demucs 任务状态查询
# GET /demucs/api/demucs-status?task_id=xxx
task_id = params_kw.task_id
if not task_id:
return {"error": "task_id is required"}
env = request._run_ns
longtasks = env.longtasks
if not longtasks:
return {"error": "longtasks not available"}
task = await longtasks.get_redis_task(task_id)
if not task or not task.get("created_at"):
return {"task_id": task_id, "status": "not_found"}
status = task.get("status", "unknown")
result = {"task_id": task_id, "status": status}
if status == "SUCCEEDED":
data = task.get("result", {})
result["vocals_url"] = data.get("vocals_path", "")
result["accompaniment_url"] = data.get("accompaniment_path", "")
result["duration"] = data.get("duration", 0)
# worker 须在 result 中包含 usage 字段
result["usage"] = data.get("usage", {"audio_seconds": data.get("duration", 0)})
elif status == "FAILED":
result["error"] = task.get("error", str(task.get("result", "")))
return result

View File

@ -1,9 +0,0 @@
# Patch for /data/ymq/demucs-service/workers/separate.py
# In run_separate_full(), ensure the return dict includes:
# "usage": {"audio_seconds": duration}
# Find the return statement in run_separate_full and add usage field.
# The function currently returns something like:
# return {"vocals_path": ..., "accompaniment_path": ..., "duration": ...}
#
# Add: "usage": {"audio_seconds": result.get("duration", 0)}

View File

@ -1,96 +0,0 @@
-- ============================================================
-- 豆包大模型接入: 火山方舟 ARK API
--
-- 模型:
-- 1. doubao-2.1-pro — 豆包大模型2.1 Pro (文本对话)
-- 2. doubao-seedream-5.0 — 豆包图像创作模型5.0 (文生图)
-- 3. doubao-speech-2.0 — 豆包语音识别模型2.0 (语音识别)
--
-- Provider: 豆包 (Cy-zrc4DgLIFuA0KMQzlw)
-- Upapp: huoshanfangzhou (火山方舟, baseurl: https://ark.cn-beijing.volces.com/api/v3)
-- ============================================================
-- ===================== Part 1: llm =====================
INSERT INTO llm (id,name,model,description,iconid,upappid,providerid,ownerid,enabled_date,expired_date,min_balance,status) VALUES
('llm_doubao_21_pro','doubao-2.1-pro','doubao-seed-2-1-pro-260628','豆包大模型2.1 Pro — 260628版本256K上下文文本对话',NULL,'huoshanfangzhou','Cy-zrc4DgLIFuA0KMQzlw','0','2025-01-01','2099-12-31',0.00,'published'),
('llm_doubao_seedream_5','doubao-seedream-5.0','doubao-seedream-5-0-260128','豆包图像创作模型5.0 — 260128版本文生图',NULL,'huoshanfangzhou','Cy-zrc4DgLIFuA0KMQzlw','0','2025-01-01','2099-12-31',0.00,'published'),
('llm_doubao_speech_2','doubao-speech-2.0','doubao-speech-2.0','豆包语音识别模型2.0 — 语音转文字',NULL,'huoshanfangzhou','Cy-zrc4DgLIFuA0KMQzlw','0','2025-01-01','2099-12-31',0.00,'published')
ON DUPLICATE KEY UPDATE model=VALUES(model), description=VALUES(description);
-- ===================== Part 2: llm_api_map =====================
INSERT INTO llm_api_map (id,llmid,llmcatelogid,apiname,query_apiname,query_period,ppid,isdefaultcatelog) VALUES
-- 豆包2.1 Pro → 文本对话 (t2t)
('map_doubao_21_pro','llm_doubao_21_pro','t2t','doubao-chat',NULL,NULL,'pp_doubao_21_pro','1'),
-- 豆包图像5.0 → 文生图 (t2i)
('map_doubao_seedream_5','llm_doubao_seedream_5','t2i','doubao-image',NULL,NULL,'pp_doubao_seedream_5','1'),
-- 豆包语音2.0 → 语音识别 (asr)
('map_doubao_speech_2','llm_doubao_speech_2','asr','doubao-asr',NULL,NULL,'pp_doubao_speech_2','1')
ON DUPLICATE KEY UPDATE apiname=VALUES(apiname), ppid=VALUES(ppid);
-- ===================== Part 3: uapi =====================
-- 3a. 文本对话 (OpenAI-compatible chat) — sync
INSERT INTO uapi (id,name,title,description,need_auth,stream,path,httpmethod,chunk_match,headers,params,data,response,ioid,callbackurl,upappid) VALUES
('uapi_doubao_chat','doubao-chat','豆包大模型对话','豆包2.1 Pro文本对话','0','sync','/chat/completions','POST',NULL,'{"Content-Type":"application/json"}',NULL,
'{%if stream==True%}"stream_options":{"include_usage":true},"stream":true,{%endif%}
"messages":[
{%if sys_prompt%}{"role":"system","content":{{json.dumps(sys_prompt,ensure_ascii=False)}}},{%endif%}
{"role":"user","content":[{%if image_file%}{"type":"image_url","image_url":"{{b64media2url(request,image_file)}}"},{%endif%}{%if video_file%}{"type":"video_url","video_url":"{{b64media2url(request,video_file)}}"},{%endif%}{%if audio_file%}{"type":"audio_url","audio_url":"{{b64media2url(request,audio_file)}}"},{%endif%}{"type":"text","text":{{json.dumps(prompt,ensure_ascii=False)}}}]}
],
"model":"{{model}}"',
'{"id":"{{id}}","object":"chat.completion","created":{{created}},"model":"{{model}}","choices":{{json.dumps(choices,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}',
NULL,NULL,'huoshanfangzhou')
ON DUPLICATE KEY UPDATE data=VALUES(data), response=VALUES(response);
-- 3b. 图像生成 (async, ARK contents/generations) — async
INSERT INTO uapi (id,name,title,description,need_auth,stream,path,httpmethod,chunk_match,headers,params,data,response,ioid,callbackurl,upappid) VALUES
('uapi_doubao_image','doubao-image','豆包图像创作','豆包Seedream5.0图像生成','0','async','/contents/generations/tasks','POST',NULL,'{"Content-Type":"application/json"}',NULL,
'{"model":"{{model}}","content":[{"type":"text","text":{{json.dumps(prompt,ensure_ascii=False)}}}],"size":"{{size or \"1024x1024\"}}"}',
'{"taskid":"{{id}}","taskstatus":"PENDING","status":"PENDING"}',
NULL,NULL,'huoshanfangzhou')
ON DUPLICATE KEY UPDATE data=VALUES(data), response=VALUES(response);
-- 3c. 语音识别 (sync, ARK audio/transcriptions) — sync
INSERT INTO uapi (id,name,title,description,need_auth,stream,path,httpmethod,chunk_match,headers,params,data,response,ioid,callbackurl,upappid) VALUES
('uapi_doubao_asr','doubao-asr','豆包语音识别','豆包Speech2.0语音转文字','0','sync','/audio/transcriptions','POST',NULL,'{"Content-Type":"multipart/form-data"}',NULL,
'{"model":"{{model}}"{%if audio_file%},"file":"{{b64media2url(request,audio_file)}}"{%endif%}{%if language%},"language":"{{language}}"{%endif%}}',
'{"text":"{{text}}"{%if segments%},"segments":{{json.dumps(segments,ensure_ascii=False)}}{%endif%}{%if usage%},"usage":{{json.dumps(usage,ensure_ascii=False)}}{%endif%}}',
NULL,NULL,'huoshanfangzhou')
ON DUPLICATE KEY UPDATE data=VALUES(data), response=VALUES(response);
-- ===================== Part 3b: uapiio (输入输出字段定义) =====================
INSERT INTO uapiio (id,name,description,input_fields) VALUES
('doubao_chat_io','豆包大模型对话','文本对话输入输出','{"prompt":{"type":"string","required":true,"description":"用户输入文本"},"sys_prompt":{"type":"string","required":false,"description":"系统提示词"},"image_file":{"type":"string","required":false,"description":"图像URL(多模态)"},"max_tokens":{"type":"integer","required":false,"default":1024,"description":"最大输出token数"}}'),
('doubao_image_io','豆包图像创作','文生图输入输出','{"prompt":{"type":"string","required":true,"description":"图像描述文本"},"size":{"type":"string","required":false,"default":"1024x1024","description":"图像尺寸"},"n":{"type":"integer","required":false,"default":1,"description":"生成数量"}}'),
('doubao_asr_io','豆包语音识别','语音转文字输入输出','{"audio_file":{"type":"string","required":true,"description":"音频文件URL"},"language":{"type":"string","required":false,"default":"zh","description":"语言代码"}}')
ON DUPLICATE KEY UPDATE description=VALUES(description),input_fields=VALUES(input_fields);
-- Link uapi to uapiio
UPDATE uapi SET ioid='doubao_chat_io' WHERE id='uapi_doubao_chat';
UPDATE uapi SET ioid='doubao_image_io' WHERE id='uapi_doubao_image';
UPDATE uapi SET ioid='doubao_asr_io' WHERE id='uapi_doubao_asr';
-- ===================== Part 4: pricing_program =====================
INSERT INTO pricing_program (id,name,ownerid,providerid,pricing_belong,description) VALUES
('pp_doubao_21_pro','豆包大模型2.1 Pro',NULL,'Cy-zrc4DgLIFuA0KMQzlw',NULL,'文本对话·按token计费'),
('pp_doubao_seedream_5','豆包图像创作5.0',NULL,'Cy-zrc4DgLIFuA0KMQzlw',NULL,'文生图·按张计费'),
('pp_doubao_speech_2','豆包语音识别2.0',NULL,'Cy-zrc4DgLIFuA0KMQzlw',NULL,'语音识别·按秒计费')
ON DUPLICATE KEY UPDATE name=VALUES(name);
-- ===================== Part 5: pricing_program_timing =====================
INSERT INTO pricing_program_timing (id,ppid,name,pricing_data,enabled_date,expired_date) VALUES
-- 文本对话: 按1K tokens计费
('pt_doubao_21_pro','pp_doubao_21_pro','豆包2.1 Pro定价',
'unit_values:\n completion_tokens: 1000\n prompt_tokens: 1000\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: completion_tokens\n unit_prices: 0.001\n unit: 1K tokens\n- price_factors: prompt_tokens\n unit_prices: 0.0005\n unit: 1K tokens',
'2025-01-01','9999-12-31'),
-- 图像生成: 按张计费
('pt_doubao_seedream_5','pp_doubao_seedream_5','豆包Seedream5.0定价',
'unit_values:\n image_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: image_count\n unit_prices: 0.02\n unit: image_count',
'2025-01-01','9999-12-31'),
-- 语音识别: 按秒计费
('pt_doubao_speech_2','pp_doubao_speech_2','豆包Speech2.0定价',
'unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.004\n unit: audio_seconds',
'2025-01-01','9999-12-31')
ON DUPLICATE KEY UPDATE ppid=VALUES(ppid), pricing_data=VALUES(pricing_data);

View File

@ -1,101 +0,0 @@
-- ============================================================
-- 腾讯混元大模型接入: Hunyuan via tokenhub.tencentmaas.com
--
-- 模型:
-- 1. hy3 — 混元 Hy3 (旗舰对话模型)
-- 2. hy-vision-2.0-instruct — HY-Vision 2.0 (视觉理解)
-- 3. hy-image-3.0-plus — HY Image V3.0 (文生图)
-- 4. hy-video-1.5 — HY Video 1.5 (文/图生视频)
--
-- 定价来源: 腾讯官方文档
-- Provider: 腾讯 (wNME9nrITooowlmCuR_XB)
-- Upapp: hunyun (5QXZ-AMP0K0NrcpZiTomA, baseurl: https://tokenhub.tencentmaas.com/v1)
-- ============================================================
-- ===================== Part 1: llm =====================
INSERT INTO llm (id,name,model,description,iconid,upappid,providerid,ownerid,enabled_date,expired_date,min_balance,status) VALUES
('llm_hunyuan_hy3','hy3','hy3','混元 Hy3 — 旗舰对话模型295B参数128K上下文',NULL,'5QXZ-AMP0K0NrcpZiTomA','wNME9nrITooowlmCuR_XB','0','2025-01-01','2099-12-31',0.00,'published'),
('llm_hunyuan_vision2','hy-vision-2.0-instruct','hy-vision-2.0-instruct','HY-Vision 2.0 — 视觉理解406B参数',NULL,'5QXZ-AMP0K0NrcpZiTomA','wNME9nrITooowlmCuR_XB','0','2025-01-01','2099-12-31',0.00,'published'),
('llm_hunyuan_image3','hy-image-3.0-plus','hy-image-v3.0','HY Image V3.0 — 文生图',NULL,'5QXZ-AMP0K0NrcpZiTomA','wNME9nrITooowlmCuR_XB','0','2025-01-01','2099-12-31',0.00,'published'),
('llm_hunyuan_video','hy-video-1.5','hy-video-1.5','HY Video 1.5 — 文/图生视频',NULL,'5QXZ-AMP0K0NrcpZiTomA','wNME9nrITooowlmCuR_XB','0','2025-01-01','2099-12-31',0.00,'published')
ON DUPLICATE KEY UPDATE model=VALUES(model), description=VALUES(description);
-- ===================== Part 2: llm_api_map =====================
INSERT INTO llm_api_map (id,llmid,llmcatelogid,apiname,query_apiname,query_period,ppid,isdefaultcatelog) VALUES
('map_hunyuan_hy3','llm_hunyuan_hy3','t2t','t2t',NULL,NULL,'pp_hunyuan_hy3','1'),
('map_hunyuan_vision2','llm_hunyuan_vision2','vision','ti2t',NULL,NULL,'pp_hunyuan_vision2','1'),
('map_hunyuan_image3','llm_hunyuan_image3','t2i','hunyuan-image-tokenhub','hunyuan-image-query','5','pp_hunyuan_image3','1'),
('map_hunyuan_video','llm_hunyuan_video','t2v','hunyuan-video-submit','hunyuan-video-query','5','pp_hunyuan_video','1')
ON DUPLICATE KEY UPDATE apiname=VALUES(apiname), query_apiname=VALUES(query_apiname), query_period=VALUES(query_period), ppid=VALUES(ppid);
-- ===================== Part 3: uapiio =====================
INSERT INTO uapiio (id,name,description,input_fields) VALUES
('hunyuan_chat_io','混元文本对话','文本对话','[{"name":"prompt","label":"用户输入","uitype":"text","required":true},{"name":"sys_prompt","label":"系统提示词","uitype":"text","required":false},{"name":"image_file","label":"图像URL","uitype":"image","required":false},{"name":"max_tokens","label":"最大输出Token","uitype":"number","required":false,"default":1024},{"name":"stream","label":"流式输出","uitype":"switch","required":false}]'),
('hunyuan_vision_io','混元视觉理解','视觉理解','[{"name":"prompt","label":"用户输入","uitype":"text","required":true},{"name":"image_file","label":"图像URL","uitype":"image","required":true},{"name":"sys_prompt","label":"系统提示词","uitype":"text","required":false},{"name":"max_tokens","label":"最大输出Token","uitype":"number","required":false,"default":1024}]'),
('hunyuan_image_io','混元图像生成','文生图(3.0)','[{"name":"prompt","label":"文本描述","uitype":"text","required":true},{"name":"image_file","label":"参考图URL","uitype":"image","required":false},{"name":"resolution","label":"分辨率","uitype":"text","required":false,"default":"1024:1024"},{"name":"seed","label":"随机种子","uitype":"number","required":false},{"name":"logo_add","label":"水印开关","uitype":"switch","required":false,"default":1},{"name":"revise","label":"Prompt改写","uitype":"switch","required":false,"default":1}]'),
('hunyuan_video_io','混元生视频','文/图生视频','[{"name":"prompt","label":"视频描述","uitype":"text","required":true},{"name":"image_file","label":"输入图像(图生视频)","uitype":"image","required":false},{"name":"resolution","label":"分辨率","uitype":"text","required":false,"default":"720P"}]')
ON DUPLICATE KEY UPDATE description=VALUES(description),input_fields=VALUES(input_fields);
UPDATE uapi SET ioid='hunyuan_chat_io' WHERE id='AP29-fYCll4l-byxm3DHN' AND upappid='5QXZ-AMP0K0NrcpZiTomA';
UPDATE uapi SET ioid='hunyuan_vision_io' WHERE id='qStjXm_Meu0nBjiRzdPew' AND upappid='5QXZ-AMP0K0NrcpZiTomA';
-- ===================== Part 4: image uapi (tokenhub, async + query) =====================
INSERT INTO uapi (id,name,title,description,need_auth,stream,path,httpmethod,headers,data,response,ioid,upappid) VALUES
('uapi_hn_img_submit','hunyuan-image-tokenhub','混元生图3.0','异步提交','1','async','/api/image/submit','POST',
'{"Content-Type":"application/json"}',
'{"model":"hy-image-v3.0","prompt":"{{prompt}}"{%if image_file%},"images":["{{image_file}}"]{%endif%}{%if resolution%},"resolution":"{{resolution}}"{%endif%}{%if seed%},"seed":{{seed}}{%endif%}{%if logo_add%},"logo_add":{{logo_add}}{%endif%}{%if revise%},"revise":{{revise}}{%endif%}}',
'{"taskid":"{{id}}","taskstatus":"{{status}}","status":"{{status}}"}',
'hunyuan_image_io','5QXZ-AMP0K0NrcpZiTomA')
ON DUPLICATE KEY UPDATE data=VALUES(data),response=VALUES(response),path=VALUES(path);
INSERT INTO uapi (id,name,title,description,need_auth,stream,path,httpmethod,headers,data,response,ioid,upappid) VALUES
('uapi_hn_img_query','hunyuan-image-query','混元生图3.0查询','任务查询','1','sync','/api/image/query','POST',
'{"Content-Type":"application/json"}',
'{"model":"hy-image-v3.0","id":"{{taskid}}"}',
'{"taskid":"{{id}}","taskstatus":"{{status}}","status":"{{status}}"{%if data%},"data":{{json.dumps(data,ensure_ascii=False)}}{%endif%}}',
'hunyuan_image_io','5QXZ-AMP0K0NrcpZiTomA')
ON DUPLICATE KEY UPDATE data=VALUES(data),response=VALUES(response),path=VALUES(path);
-- ===================== Part 5: video uapi (tokenhub, async + query) =====================
INSERT INTO uapi (id,name,title,description,need_auth,stream,path,httpmethod,headers,data,response,ioid,upappid) VALUES
('uapi_hn_vid_submit','hunyuan-video-submit','混元生视频','异步提交','1','async','/api/video/submit','POST',
'{"Content-Type":"application/json"}',
'{"model":"hy-video-1.5","prompt":"{{prompt}}"{%if image_file%},"images":["{{image_file}}"]{%endif%}{%if resolution%},"resolution":"{{resolution}}"{%endif%}}',
'{"taskid":"{{id}}","taskstatus":"{{status}}","status":"{{status}}"}',
'hunyuan_video_io','5QXZ-AMP0K0NrcpZiTomA')
ON DUPLICATE KEY UPDATE data=VALUES(data),response=VALUES(response),path=VALUES(path);
INSERT INTO uapi (id,name,title,description,need_auth,stream,path,httpmethod,headers,data,response,ioid,upappid) VALUES
('uapi_hn_vid_query','hunyuan-video-query','混元生视频查询','任务查询','1','sync','/api/video/query','POST',
'{"Content-Type":"application/json"}',
'{"model":"hy-video-1.5","id":"{{taskid}}"}',
'{"taskid":"{{id}}","taskstatus":"{{status}}","status":"{{status}}"{%if data%},"data":{{json.dumps(data,ensure_ascii=False)}}{%endif%}}',
'hunyuan_video_io','5QXZ-AMP0K0NrcpZiTomA')
ON DUPLICATE KEY UPDATE data=VALUES(data),response=VALUES(response),path=VALUES(path);
-- ===================== Part 6: pricing_program =====================
INSERT INTO pricing_program (id,name,ownerid,providerid,pricing_belong,description) VALUES
('pp_hunyuan_hy3','混元Hy3旗舰对话',NULL,'wNME9nrITooowlmCuR_XB',NULL,'输入1元/百万,输出4元/百万'),
('pp_hunyuan_vision2','HY-Vision 2.0视觉',NULL,'wNME9nrITooowlmCuR_XB',NULL,'输入7.5元/百万,输出17.5元/百万'),
('pp_hunyuan_image3','HY Image V3.0',NULL,'wNME9nrITooowlmCuR_XB',NULL,'0.2元/张'),
('pp_hunyuan_video','HY Video 1.5',NULL,'wNME9nrITooowlmCuR_XB',NULL,'1.5元/次(1.0元/积分×1.5积分)')
ON DUPLICATE KEY UPDATE name=VALUES(name);
-- ===================== Part 7: pricing_program_timing =====================
INSERT INTO pricing_program_timing (id,ppid,name,pricing_data,enabled_date,expired_date) VALUES
('pt_hunyuan_hy3','pp_hunyuan_hy3','混元Hy3',
'unit_values:\n completion_tokens: 1000\n prompt_tokens: 1000\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: completion_tokens\n unit_prices: 0.004\n unit: 1K tokens\n- price_factors: prompt_tokens\n unit_prices: 0.001\n unit: 1K tokens',
'2025-01-01','9999-12-31'),
('pt_hunyuan_vision2','pp_hunyuan_vision2','HY-Vision 2.0',
'unit_values:\n completion_tokens: 1000\n prompt_tokens: 1000\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: completion_tokens\n unit_prices: 0.0175\n unit: 1K tokens\n- price_factors: prompt_tokens\n unit_prices: 0.0075\n unit: 1K tokens',
'2025-01-01','9999-12-31'),
('pt_hunyuan_image3','pp_hunyuan_image3','HY Image V3.0',
'unit_values:\n image_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: image_count\n unit_prices: 0.2\n unit: image_count',
'2025-01-01','9999-12-31'),
('pt_hunyuan_video','pp_hunyuan_video','HY-Video 1.5',
'unit_values:\n video_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: video_count\n unit_prices: 1.5\n unit: video_count',
'2025-01-01','9999-12-31')
ON DUPLICATE KEY UPDATE ppid=VALUES(ppid), pricing_data=VALUES(pricing_data);

View File

@ -1,31 +0,0 @@
server {
listen 10443;
server_name ktv.opencomputing.net;
root /var/www/html;
client_max_body_size 20g;
proxy_buffering off;
ssl_certificate /etc/letsencrypt/live/opencomputing.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/opencomputing.net/privkey.pem;
add_header Access-Control-Allow-Origin *;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-real-ip $remote_addr;
proxy_send_timeout 600s;
proxy_read_timeout 600s;
location /asr/ { proxy_pass http://localhost:9925/; }
location /demucs/ { proxy_pass http://localhost:9083/; }
location /face/ { proxy_pass http://localhost:9091/; }
location /subtitle/ { proxy_pass http://localhost:9080/; }
location /merge/ { proxy_pass http://localhost:9080/; }
location /songrate/ { proxy_pass http://localhost:8901/; }
location /synth/ { proxy_pass http://localhost:9084/; }
location /realesrgan/ { proxy_pass http://localhost:9082/; }
location /rvc/ { proxy_pass http://localhost:9085/; }
location /video-eval/ { proxy_pass http://localhost:8902/; }
}

File diff suppressed because one or more lines are too long

View File

@ -1,69 +0,0 @@
-- KTV产线网关: 14端点
INSERT INTO sage.upapp (id,name,baseurl,ownerid) VALUES ('ktv-gateway','KTV产线网关','https://ktv.opencomputing.net:10443','0') ON DUPLICATE KEY UPDATE baseurl=VALUES(baseurl);
-- llm (model=功能名, name=ky-model)
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_asr_transcribe','ky-asr-transcribe','asr-transcribe','KTV语音识别','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_demucs_separate','ky-demucs-separate','demucs-separate','KTV音频分离','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_face_detect','ky-face-detect','face-detect','KTV人脸检测','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_face_recognize','ky-face-recognize','face-recognize','KTV人脸识别','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_face_compare','ky-face-compare','face-compare','KTV人脸比对','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_subtitle_render','ky-subtitle-render','subtitle-render','KTV字幕渲染','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_merge_video','ky-merge-video','merge-video','KTV视频合并','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_songrate_evaluate','ky-songrate-evaluate','songrate-evaluate','KTV歌曲评分','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_synth_generate','ky-synth-generate','synth-generate','KTV音乐合成','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_synth_status','ky-synth-status','synth-status','KTV合成状态','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_realesrgan_upscale','ky-realesrgan-upscale','realesrgan-upscale','KTV超分辨率','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_realesrgan_status','ky-realesrgan-status','realesrgan-status','KTV超分状态','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_rvc_convert','ky-rvc-convert','rvc-convert','KTV声音转换','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
INSERT INTO sage.llm (id,name,model,description,providerid,ownerid,upappid,min_balance,enabled_date,expired_date,status) VALUES ('llm_ktv_video_eval_evaluate','ky-video-eval-evaluate','video-eval-evaluate','KTV视频评估','FZoJv7EUEdKL3pUt0BQ5S','0','ktv-gateway',0,'2025-01-01','2099-12-31','published');
-- uapi (path=/{servicename}/api/{apiname})
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_asr_transcribe','asr-transcribe','KTV语音识别','KTV语音识别','/asr/api/asr-transcribe','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_demucs_separate','demucs-separate','KTV音频分离','KTV音频分离','/demucs/api/demucs-separate','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_face_detect','face-detect','KTV人脸检测','KTV人脸检测','/face/api/face-detect','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_face_recognize','face-recognize','KTV人脸识别','KTV人脸识别','/face/api/face-recognize','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_face_compare','face-compare','KTV人脸比对','KTV人脸比对','/face/api/face-compare','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_subtitle_render','subtitle-render','KTV字幕渲染','KTV字幕渲染','/subtitle/api/subtitle-render','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_merge_video','merge-video','KTV视频合并','KTV视频合并','/merge/api/merge-video','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_songrate_evaluate','songrate-evaluate','KTV歌曲评分','KTV歌曲评分','/songrate/api/songrate-evaluate','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_synth_generate','synth-generate','KTV音乐合成','KTV音乐合成','/synth/api/synth-generate','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_synth_status','synth-status','KTV合成状态','KTV合成状态','/synth/api/synth-status','GET','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_realesrgan_upscale','realesrgan-upscale','KTV超分辨率','KTV超分辨率','/realesrgan/api/realesrgan-upscale','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_realesrgan_status','realesrgan-status','KTV超分状态','KTV超分状态','/realesrgan/api/realesrgan-status','GET','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_rvc_convert','rvc-convert','KTV声音转换','KTV声音转换','/rvc/api/rvc-convert','POST','ktv-gateway');
INSERT INTO sage.uapi (id,name,title,description,path,httpmethod,upappid) VALUES ('uapi_ktv_video_eval_evaluate','video-eval-evaluate','KTV视频评估','KTV视频评估','/video-eval/api/video-eval-evaluate','POST','ktv-gateway');
-- llm_api_map
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_asr_transcribe','llm_ktv_asr_transcribe','ktv_pipeline','asr-transcribe','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_demucs_separate','llm_ktv_demucs_separate','ktv_pipeline','demucs-separate','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_face_detect','llm_ktv_face_detect','ktv_pipeline','face-detect','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_face_recognize','llm_ktv_face_recognize','ktv_pipeline','face-recognize','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_face_compare','llm_ktv_face_compare','ktv_pipeline','face-compare','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_subtitle_render','llm_ktv_subtitle_render','ktv_pipeline','subtitle-render','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_merge_video','llm_ktv_merge_video','ktv_pipeline','merge-video','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_songrate_evaluate','llm_ktv_songrate_evaluate','ktv_pipeline','songrate-evaluate','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_synth_generate','llm_ktv_synth_generate','ktv_pipeline','synth-generate','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_synth_status','llm_ktv_synth_status','ktv_pipeline','synth-status','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_realesrgan_upscale','llm_ktv_realesrgan_upscale','ktv_pipeline','realesrgan-upscale','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_realesrgan_status','llm_ktv_realesrgan_status','ktv_pipeline','realesrgan-status','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_rvc_convert','llm_ktv_rvc_convert','ktv_pipeline','rvc-convert','1');
INSERT INTO sage.llm_api_map (id,llmid,llmcatelogid,apiname,isdefaultcatelog) VALUES ('map_ktv_video_eval_evaluate','llm_ktv_video_eval_evaluate','ktv_pipeline','video-eval-evaluate','1');
-- pricing_program
INSERT INTO sage.pricing_program (id,providerid,name) VALUES ('pp_ktv','FZoJv7EUEdKL3pUt0BQ5S','KTV产线计费') ON DUPLICATE KEY UPDATE providerid=VALUES(providerid);
-- pricing_program_timing (0.01元/次)
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_asr_transcribe','pp_ktv','KTV语音识别','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_demucs_separate','pp_ktv','KTV音频分离','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_face_detect','pp_ktv','KTV人脸检测','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_face_recognize','pp_ktv','KTV人脸识别','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_face_compare','pp_ktv','KTV人脸比对','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_subtitle_render','pp_ktv','KTV字幕渲染','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_merge_video','pp_ktv','KTV视频合并','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_songrate_evaluate','pp_ktv','KTV歌曲评分','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_synth_generate','pp_ktv','KTV音乐合成','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_synth_status','pp_ktv','KTV合成状态','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_realesrgan_upscale','pp_ktv','KTV超分辨率','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_realesrgan_status','pp_ktv','KTV超分状态','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_rvc_convert','pp_ktv','KTV声音转换','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');
INSERT INTO sage.pricing_program_timing (id,ppid,name,pricing_data) VALUES ('pt_ktv_video_eval_evaluate','pp_ktv','KTV视频评估','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次');

View File

@ -1,381 +0,0 @@
-- ============================================================
-- KTV服务 uapi/uapiio 补全迁移 Part 1
-- 输入字段使用 _file 命名规范(与 Sage image/video/audio 统一)
-- ============================================================
-- ASR语音识别
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_asr_transcribe_io', 'KTV语音识别', '上传音频文件,返回识别文本和时间戳',
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"},"language":{"type":"string","required":false,"default":"zh","description":"语言代码"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- Demucs音频分离
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_demucs_separate_io', 'KTV音频分离', '分离人声和伴奏',
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 人脸检测
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_face_detect_io', 'KTV人脸检测', '检测图像中的人脸位置',
'{"image_file":{"type":"string","required":true,"description":"图像URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 人脸识别
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_face_recognize_io', 'KTV人脸识别', '识别人脸身份',
'{"image_file":{"type":"string","required":true,"description":"图像URL"},"face_id":{"type":"string","required":false,"description":"人脸ID"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 人脸比对
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_face_compare_io', 'KTV人脸比对', '比较两张人脸的相似度',
'{"image_file1":{"type":"string","required":true,"description":"图像1 URL"},"image_file2":{"type":"string","required":true,"description":"图像2 URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 字幕渲染
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_subtitle_render_io', 'KTV字幕渲染', '将歌词时间轴渲染为ASS字幕文件',
'{"lyrics_json":{"type":"string","required":true,"description":"歌词时间轴JSON"},"width":{"type":"integer","required":false,"default":1920,"description":"视频宽度"},"height":{"type":"integer","required":false,"default":1080,"description":"视频高度"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 视频合并
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_merge_video_io', 'KTV视频合并', '合并视频、音频和字幕',
'{"video_file":{"type":"string","required":false,"description":"视频URL"},"audio_file":{"type":"string","required":false,"description":"音频URL"},"subtitle_file":{"type":"string","required":false,"description":"ASS字幕URL"},"output_format":{"type":"string","required":false,"default":"mp4","description":"输出格式"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 歌曲评分
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_songrate_evaluate_io', 'KTV歌曲评分', 'AI评估歌曲质量',
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"},"scene":{"type":"string","required":false,"default":"pop","description":"场景类型"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 合成状态查询
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_synth_status_io', 'KTV合成状态', '查询音乐合成任务状态',
'{"task_id":{"type":"string","required":true,"description":"任务ID"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 超分辨率(异步)
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_realesrgan_upscale_io', 'KTV超分辨率', '图像/视频超分辨率(异步任务)',
'{"image_file":{"type":"string","required":true,"description":"图像URL"},"scale":{"type":"integer","required":false,"default":2,"description":"放大倍数"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 超分状态查询
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_realesrgan_status_io', 'KTV超分状态', '查询超分任务状态',
'{"task_id":{"type":"string","required":true,"description":"任务ID"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- RVC声音转换
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_rvc_convert_io', 'KTV声音转换', '声音克隆/变声',
'{"audio_file":{"type":"string","required":true,"description":"输入音频URL"},"voice_model":{"type":"string","required":true,"description":"目标声音模型名"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 视频评估
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_video_eval_evaluate_io', 'KTV视频评估', '评估视频质量',
'{"video_file":{"type":"string","required":true,"description":"视频URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- ============================================================
-- KTV服务 uapi 补全 Part 2
-- data使用_file命名; response用{%if error%}容错透传GPU响应
-- async: synth-generate(5s轮询), realesrgan-upscale(3s轮询)
-- ============================================================
-- 1. ASR语音识别 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"audio_file":"{{audio_file}}"{%if language%},"language":"{{language}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","text":"{{text}}","segments":{{json.dumps(segments,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_asr_transcribe_io' WHERE id='uapi_ktv_asr_transcribe';
-- 2. Demucs音频分离 (async)
UPDATE uapi SET stream='async',headers='{"Content-Type":"application/json"}',
data='{"audio_path":"{{audio_file}}"{%if task_type%},"task_type":"{{task_type}}"{%endif%}}',
response='{"taskid":"{{task_id}}","taskstatus":"PENDING","status":"PENDING"}',
ioid='ktv_demucs_separate_io' WHERE id='uapi_ktv_demucs_separate';
-- 3. 人脸检测 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"image_file":"{{image_file}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","faces":{{json.dumps(faces,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_face_detect_io' WHERE id='uapi_ktv_face_detect';
-- 4. 人脸识别 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"image_file":"{{image_file}}"{%if face_id%},"face_id":"{{face_id}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","matches":{{json.dumps(matches,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_face_recognize_io' WHERE id='uapi_ktv_face_recognize';
-- 5. 人脸比对 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"image_file1":"{{image_file1}}","image_file2":"{{image_file2}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","similarity":{{similarity}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_face_compare_io' WHERE id='uapi_ktv_face_compare';
-- 6. 字幕渲染 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"lyrics_json":{{lyrics_json}}{%if width%},"width":{{width}}{%endif%}{%if height%},"height":{{height}}{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","ass_url":"{{ass_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_subtitle_render_io' WHERE id='uapi_ktv_subtitle_render';
-- 7. 视频合并 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{%set c=joiner(",")%}{{%if video_file%}{{c()}}"video_file":"{{video_file}}"{%endif%}{%if audio_file%}{{c()}}"audio_file":"{{audio_file}}"{%endif%}{%if subtitle_file%}{{c()}}"subtitle_file":"{{subtitle_file}}"{%endif%}{%if output_format%}{{c()}}"output_format":"{{output_format}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","output_url":"{{output_url}}","duration":{{duration}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_merge_video_io' WHERE id='uapi_ktv_merge_video';
-- 8. 歌曲评分 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"audio_file":"{{audio_file}}"{%if scene%},"scene":"{{scene}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","score":{{score}},"details":{{json.dumps(details,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_songrate_evaluate_io' WHERE id='uapi_ktv_songrate_evaluate';
-- 9. 合成状态查询 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"task_id":"{{task_id}}"}',
response='{%if error%}{"error":"{{error}}"}{%elif status=="SUCCEEDED"%}{"taskstatus":"SUCCEEDED","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%elif status=="FAILED"%}{"taskstatus":"FAILED","error":"{{error}}"}{%else%}{"taskstatus":"PENDING"}{%endif%}',
ioid='ktv_synth_status_io' WHERE id='uapi_ktv_synth_status';
-- 11. 超分辨率 (async提交)
UPDATE uapi SET stream='async',headers='{"Content-Type":"application/json"}',
data='{"image_file":"{{image_file}}"{%if scale%},"scale":{{scale}}{%endif%}}',
response='{"taskid":"{{task_id}}","taskstatus":"PENDING"}',
ioid='ktv_realesrgan_upscale_io' WHERE id='uapi_ktv_realesrgan_upscale';
-- 12. 超分状态查询 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data=NULL,
response='{"status":"{{status}}","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}',
ioid='ktv_realesrgan_status_io' WHERE id='uapi_ktv_realesrgan_status';
-- 13. RVC声音转换 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"audio_file":"{{audio_file}}","voice_model":"{{voice_model}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_rvc_convert_io' WHERE id='uapi_ktv_rvc_convert';
-- 14. 视频评估 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"video_file":"{{video_file}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","score":{{score}},"details":{{json.dumps(details,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_video_eval_evaluate_io' WHERE id='uapi_ktv_video_eval_evaluate';
-- async query_apiname
UPDATE llm_api_map SET query_apiname='realesrgan-status',query_period=5 WHERE llmid='llm_ktv_realesrgan_upscale';
-- ppid (v1/models 过滤要求 ppid IS NOT NULL)
UPDATE llm_api_map SET ppid='pp_ktv' WHERE llmid LIKE 'llm_ktv%' AND ppid IS NULL;
-- upappkey (API调用鉴权必需)
INSERT INTO upappkey (id,upappid,ownerid,apikey,orgid)
SELECT 'ktv_gateway_key','ktv-gateway','UiEi7hKqAmU1-jqQEVhZe','','0'
WHERE NOT EXISTS (SELECT 1 FROM upappkey WHERE upappid='ktv-gateway');
-- ============================================================
-- KTV Pipeline v1 API RBAC 权限配置
-- 新增 /v1/pipeline/submit 端点权限
-- ============================================================
-- 权限路径(供 load_path.py 或不直接支持的模块参考)
-- 目录级
-- /llmage/v1/pipeline logined
-- /llmage/v1/pipeline/submit logined
-- 文件级
-- /llmage/v1/pipeline/submit/index.dspy logined
-- ============================================================
-- Customer 角色权限API调用者需要
-- ============================================================
INSERT INTO permission (id, path, name)
SELECT REPLACE(UUID(), '-', ''), '/llmage/v1/pipeline/submit/index.dspy', 'KTV流水线提交'
WHERE NOT EXISTS (
SELECT 1 FROM permission WHERE path = '/llmage/v1/pipeline/submit/index.dspy'
);
-- 为 customer.admin 和 customer.user 角色授予权限
-- 注意:以下语句依赖 set_role_perm.py 或等效的角色-权限关联表
-- 如果用的是直接 role_permission 表:
INSERT IGNORE INTO role_permission (role_id, permission_id)
SELECT r.id, p.id
FROM role r, permission p
WHERE r.name IN ('customer.admin', 'customer.user')
AND p.path = '/llmage/v1/pipeline/submit/index.dspy';
-- ============================================================
-- 管理角色权限
-- ============================================================
INSERT IGNORE INTO role_permission (role_id, permission_id)
SELECT r.id, p.id
FROM role r, permission p
WHERE r.name IN ('owner.superuser', 'owner.admin', 'reseller.admin', 'reseller.operator')
AND p.path = '/llmage/v1/pipeline/submit/index.dspy';
-- ============================================================
-- KTV服务 定价修复 Part 4
-- 每个模型独立ppid + 按量计费(price_factors=字段名)
-- ============================================================
-- 1. 创建独立ppid每模型一个
INSERT INTO pricing_program (id,providerid,name) VALUES
('pp_ktv_asr','FZoJv7EUEdKL3pUt0BQ5S','KTV-语音识别'),
('pp_ktv_demucs','FZoJv7EUEdKL3pUt0BQ5S','KTV-音频分离'),
('pp_ktv_face_detect','FZoJv7EUEdKL3pUt0BQ5S','KTV-人脸检测'),
('pp_ktv_face_recognize','FZoJv7EUEdKL3pUt0BQ5S','KTV-人脸识别'),
('pp_ktv_face_compare','FZoJv7EUEdKL3pUt0BQ5S','KTV-人脸比对'),
('pp_ktv_subtitle','FZoJv7EUEdKL3pUt0BQ5S','KTV-字幕渲染'),
('pp_ktv_merge','FZoJv7EUEdKL3pUt0BQ5S','KTV-视频合并'),
('pp_ktv_songrate','FZoJv7EUEdKL3pUt0BQ5S','KTV-歌曲评分'),
('pp_ktv_synth_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-合成状态'),
('pp_ktv_realesrgan','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分辨率'),
('pp_ktv_realesrgan_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分状态'),
('pp_ktv_rvc','FZoJv7EUEdKL3pUt0BQ5S','KTV-声音转换'),
('pp_ktv_video_eval','FZoJv7EUEdKL3pUt0BQ5S','KTV-视频评估')
ON DUPLICATE KEY UPDATE providerid=VALUES(providerid);
-- 2. 迁移 pricing_program_timing 到新 ppid
UPDATE pricing_program_timing SET ppid='pp_ktv_asr' WHERE id='pt_ktv_asr_transcribe';
UPDATE pricing_program_timing SET ppid='pp_ktv_demucs' WHERE id='pt_ktv_demucs_separate';
UPDATE pricing_program_timing SET ppid='pp_ktv_face_detect' WHERE id='pt_ktv_face_detect';
UPDATE pricing_program_timing SET ppid='pp_ktv_face_recognize' WHERE id='pt_ktv_face_recognize';
UPDATE pricing_program_timing SET ppid='pp_ktv_face_compare' WHERE id='pt_ktv_face_compare';
UPDATE pricing_program_timing SET ppid='pp_ktv_subtitle' WHERE id='pt_ktv_subtitle_render';
UPDATE pricing_program_timing SET ppid='pp_ktv_merge' WHERE id='pt_ktv_merge_video';
UPDATE pricing_program_timing SET ppid='pp_ktv_songrate' WHERE id='pt_ktv_songrate_evaluate';
UPDATE pricing_program_timing SET ppid='pp_ktv_synth_status' WHERE id='pt_ktv_synth_status';
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan' WHERE id='pt_ktv_realesrgan_upscale';
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan_status' WHERE id='pt_ktv_realesrgan_status';
UPDATE pricing_program_timing SET ppid='pp_ktv_rvc' WHERE id='pt_ktv_rvc_convert';
UPDATE pricing_program_timing SET ppid='pp_ktv_video_eval' WHERE id='pt_ktv_video_eval_evaluate';
-- 3. 更新 pricing_data YAMLprice_factors=字段名(按量计费)
-- asr: audio_seconds × 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.01\n unit: audio_seconds' WHERE id='pt_ktv_asr_transcribe';
-- demucs: audio_seconds × 0.02
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.02\n unit: audio_seconds' WHERE id='pt_ktv_demucs_separate';
-- face-detect: detect_count × 0.10
UPDATE pricing_program_timing SET pricing_data='unit_values:\n detect_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: detect_count\n unit_prices: 0.10\n unit: detect_count' WHERE id='pt_ktv_face_detect';
-- face-recognize: recognize_count × 0.10
UPDATE pricing_program_timing SET pricing_data='unit_values:\n recognize_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: recognize_count\n unit_prices: 0.10\n unit: recognize_count' WHERE id='pt_ktv_face_recognize';
-- face-compare: compare_count × 0.10
UPDATE pricing_program_timing SET pricing_data='unit_values:\n compare_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: compare_count\n unit_prices: 0.10\n unit: compare_count' WHERE id='pt_ktv_face_compare';
-- subtitle: subtitle_count × 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n subtitle_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: subtitle_count\n unit_prices: 0.01\n unit: subtitle_count' WHERE id='pt_ktv_subtitle_render';
-- merge: output_seconds × 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n output_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: output_seconds\n unit_prices: 0.01\n unit: output_seconds' WHERE id='pt_ktv_merge_video';
-- songrate: audio_seconds × 0.005
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.005\n unit: audio_seconds' WHERE id='pt_ktv_songrate_evaluate';
-- synth-generate: audio_seconds × 0.20
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.20\n unit: audio_seconds' WHERE id='pt_ktv_synth_generate';
-- synth-status: flat 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次' WHERE id='pt_ktv_synth_status';
-- realesrgan-upscale: image_count × 0.50
UPDATE pricing_program_timing SET pricing_data='unit_values:\n image_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: image_count\n unit_prices: 0.50\n unit: image_count' WHERE id='pt_ktv_realesrgan_upscale';
-- realesrgan-status: flat 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次' WHERE id='pt_ktv_realesrgan_status';
-- rvc: audio_seconds × 0.15
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.15\n unit: audio_seconds' WHERE id='pt_ktv_rvc_convert';
-- video-eval: video_seconds × 0.05
UPDATE pricing_program_timing SET pricing_data='unit_values:\n video_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: video_seconds\n unit_prices: 0.05\n unit: video_seconds' WHERE id='pt_ktv_video_eval_evaluate';
-- 4. 更新 llm_api_map 指向独立 ppid
UPDATE llm_api_map SET ppid='pp_ktv_asr' WHERE llmid='llm_ktv_asr_transcribe';
UPDATE llm_api_map SET ppid='pp_ktv_demucs' WHERE llmid='llm_ktv_demucs_separate';
UPDATE llm_api_map SET ppid='pp_ktv_face_detect' WHERE llmid='llm_ktv_face_detect';
UPDATE llm_api_map SET ppid='pp_ktv_face_recognize' WHERE llmid='llm_ktv_face_recognize';
UPDATE llm_api_map SET ppid='pp_ktv_face_compare' WHERE llmid='llm_ktv_face_compare';
UPDATE llm_api_map SET ppid='pp_ktv_subtitle' WHERE llmid='llm_ktv_subtitle_render';
UPDATE llm_api_map SET ppid='pp_ktv_merge' WHERE llmid='llm_ktv_merge_video';
UPDATE llm_api_map SET ppid='pp_ktv_songrate' WHERE llmid='llm_ktv_songrate_evaluate';
UPDATE llm_api_map SET ppid='pp_ktv_synth_status' WHERE llmid='llm_ktv_synth_status';
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan' WHERE llmid='llm_ktv_realesrgan_upscale';
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan_status' WHERE llmid='llm_ktv_realesrgan_status';
UPDATE llm_api_map SET ppid='pp_ktv_rvc' WHERE llmid='llm_ktv_rvc_convert';
UPDATE llm_api_map SET ppid='pp_ktv_video_eval' WHERE llmid='llm_ktv_video_eval_evaluate';
-- 修复 pricing_program 字符集不一致(生产环境 utf8mb4_general_ci vs organization utf8mb4_unicode_ci
ALTER TABLE pricing_program MODIFY ownerid VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE pricing_program MODIFY providerid VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- ============================================================
-- KTV服务 数据模板修复 Part 5
-- 匹配GPU实际参数名 + demucs async改造
-- ============================================================
-- asr: audio_file → audio_path
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if language%},"language":"{{language}}"{%endif%}}' WHERE id='uapi_ktv_asr_transcribe';
-- demucs: audio_file → audio_path
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if task_type%},"task_type":"{{task_type}}"{%endif%}}' WHERE id='uapi_ktv_demucs_separate';
-- face-detect: image_file → images list
UPDATE uapi SET data='{"images":["{{image_file}}"]}' WHERE id='uapi_ktv_face_detect';
-- face-recognize: image_file → images list
UPDATE uapi SET data='{"images":["{{image_file}}"]{%if face_id%},"face_id":"{{face_id}}"{%endif%}}' WHERE id='uapi_ktv_face_recognize';
-- face-compare: image_file1→embedding1, image_file2→embedding2
UPDATE uapi SET data='{"embedding1":"{{image_file1}}","embedding2":"{{image_file2}}"}' WHERE id='uapi_ktv_face_compare';
-- subtitle: lyrics_json → lyrics
UPDATE uapi SET data='{"lyrics":{{lyrics_json}}{%if width%},"width":{{width}}{%endif%}{%if height%},"height":{{height}}{%endif%}}' WHERE id='uapi_ktv_subtitle_render';
-- merge: video_file→video_url, audio_file→audio_path
UPDATE uapi SET data='{%set c=joiner(",")%}{{%if video_file%}{{c()}}"video_url":"{{video_file}}"{%endif%}{%if audio_file%}{{c()}}"audio_path":"{{audio_file}}"{%endif%}{%if subtitle_file%}{{c()}}"subtitle_url":"{{subtitle_file}}"{%endif%}{%if output_format%}{{c()}}"output_format":"{{output_format}}"{%endif%}}' WHERE id='uapi_ktv_merge_video';
-- songrate: audio_file→audio_path
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if scene%},"scene":"{{scene}}"{%endif%}}' WHERE id='uapi_ktv_songrate_evaluate';
-- synth-status: GET, params in query string, no body
UPDATE uapi SET httpmethod='GET', data=NULL, path='/synth/api/synth-status?task_id={{taskid}}' WHERE id='uapi_ktv_synth_status';
-- realesrgan-upscale: image_file→image_url
UPDATE uapi SET data='{"image_url":"{{image_file}}"{%if scale%},"scale":{{scale}}{%endif%}}' WHERE id='uapi_ktv_realesrgan_upscale';
-- realesrgan-status: GET, params in query string, no body
UPDATE uapi SET httpmethod='GET', data=NULL, path='/realesrgan/api/realesrgan-status?task_id={{taskid}}' WHERE id='uapi_ktv_realesrgan_status';
-- rvc: audio_file→audio_path, voice_model→model
UPDATE uapi SET data='{"audio_path":"{{audio_file}}","model":"{{voice_model}}"}' WHERE id='uapi_ktv_rvc_convert';
-- video-eval: video_file→video_url
UPDATE uapi SET data='{"video_url":"{{video_file}}"}' WHERE id='uapi_ktv_video_eval_evaluate';
-- ============================================================
-- demucs async 改造: status 查询端点 + query_apiname
-- ============================================================
INSERT INTO uapi (id,name,title,description,path,httpmethod,upappid,stream,headers,data,response,ioid)
VALUES ('uapi_ktv_demucs_status','demucs-status','Demucs Status',
'Query demucs task','/demucs/api/demucs-status?task_id={{taskid}}','GET',
'ktv-gateway','sync','{"Content-Type":"application/json"}',NULL,
'{"status":"{{status}}","vocals_url":"{{vocals_url}}","accompaniment_url":"{{accompaniment_url}}","duration":{{duration}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}',
'ktv_demucs_separate_io')
ON DUPLICATE KEY UPDATE response=VALUES(response);
UPDATE llm_api_map SET query_apiname='demucs-status',query_period=5 WHERE llmid='llm_ktv_demucs_separate';
-- ============================================================
-- 补充缺失的 pricing_program_timing 记录
-- ============================================================
INSERT INTO pricing_program_timing (id,ppid,name,pricing_data,enabled_date,expired_date) VALUES
('pt_ktv_face_compare','pp_ktv_face_compare','KTV人脸比对','unit_values:\n compare_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: compare_count\n unit_prices: 0.10\n unit: compare_count','2025-01-01','9999-12-31'),
('pt_ktv_synth_status','pp_ktv_synth_status','KTV合成状态','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次','2025-01-01','9999-12-31'),
('pt_ktv_realesrgan_status','pp_ktv_realesrgan_status','KTV超分状态','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次','2025-01-01','9999-12-31')
ON DUPLICATE KEY UPDATE ppid=VALUES(ppid), pricing_data=VALUES(pricing_data);

View File

@ -1,82 +0,0 @@
-- ============================================================
-- KTV服务 uapi/uapiio 补全迁移 Part 1
-- 输入字段使用 _file 命名规范(与 Sage image/video/audio 统一)
-- ============================================================
-- ASR语音识别
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_asr_transcribe_io', 'KTV语音识别', '上传音频文件,返回识别文本和时间戳',
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"},"language":{"type":"string","required":false,"default":"zh","description":"语言代码"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- Demucs音频分离
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_demucs_separate_io', 'KTV音频分离', '分离人声和伴奏',
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 人脸检测
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_face_detect_io', 'KTV人脸检测', '检测图像中的人脸位置',
'{"image_file":{"type":"string","required":true,"description":"图像URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 人脸识别
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_face_recognize_io', 'KTV人脸识别', '识别人脸身份',
'{"image_file":{"type":"string","required":true,"description":"图像URL"},"face_id":{"type":"string","required":false,"description":"人脸ID"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 人脸比对
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_face_compare_io', 'KTV人脸比对', '比较两张人脸的相似度',
'{"image_file1":{"type":"string","required":true,"description":"图像1 URL"},"image_file2":{"type":"string","required":true,"description":"图像2 URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 字幕渲染
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_subtitle_render_io', 'KTV字幕渲染', '将歌词时间轴渲染为ASS字幕文件',
'{"lyrics_json":{"type":"string","required":true,"description":"歌词时间轴JSON"},"width":{"type":"integer","required":false,"default":1920,"description":"视频宽度"},"height":{"type":"integer","required":false,"default":1080,"description":"视频高度"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 视频合并
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_merge_video_io', 'KTV视频合并', '合并视频、音频和字幕',
'{"video_file":{"type":"string","required":false,"description":"视频URL"},"audio_file":{"type":"string","required":false,"description":"音频URL"},"subtitle_file":{"type":"string","required":false,"description":"ASS字幕URL"},"output_format":{"type":"string","required":false,"default":"mp4","description":"输出格式"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 歌曲评分
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_songrate_evaluate_io', 'KTV歌曲评分', 'AI评估歌曲质量',
'{"audio_file":{"type":"string","required":true,"description":"音频文件URL"},"scene":{"type":"string","required":false,"default":"pop","description":"场景类型"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 合成状态查询
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_synth_status_io', 'KTV合成状态', '查询音乐合成任务状态',
'{"task_id":{"type":"string","required":true,"description":"任务ID"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 超分辨率(异步)
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_realesrgan_upscale_io', 'KTV超分辨率', '图像/视频超分辨率(异步任务)',
'{"image_file":{"type":"string","required":true,"description":"图像URL"},"scale":{"type":"integer","required":false,"default":2,"description":"放大倍数"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 超分状态查询
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_realesrgan_status_io', 'KTV超分状态', '查询超分任务状态',
'{"task_id":{"type":"string","required":true,"description":"任务ID"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- RVC声音转换
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_rvc_convert_io', 'KTV声音转换', '声音克隆/变声',
'{"audio_file":{"type":"string","required":true,"description":"输入音频URL"},"voice_model":{"type":"string","required":true,"description":"目标声音模型名"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);
-- 视频评估
INSERT INTO uapiio (id, name, description, input_fields) VALUES (
'ktv_video_eval_evaluate_io', 'KTV视频评估', '评估视频质量',
'{"video_file":{"type":"string","required":true,"description":"视频URL"}}'
) ON DUPLICATE KEY UPDATE description=VALUES(description), input_fields=VALUES(input_fields);

View File

@ -1,94 +0,0 @@
-- ============================================================
-- KTV服务 uapi 补全 Part 2
-- data使用_file命名; response用{%if error%}容错透传GPU响应
-- async: synth-generate(5s轮询), realesrgan-upscale(3s轮询)
-- ============================================================
-- 1. ASR语音识别 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"audio_file":"{{audio_file}}"{%if language%},"language":"{{language}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","text":"{{text}}","segments":{{json.dumps(segments,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_asr_transcribe_io' WHERE id='uapi_ktv_asr_transcribe';
-- 2. Demucs音频分离 (async)
UPDATE uapi SET stream='async',headers='{"Content-Type":"application/json"}',
data='{"audio_path":"{{audio_file}}"{%if task_type%},"task_type":"{{task_type}}"{%endif%}}',
response='{"taskid":"{{task_id}}","taskstatus":"PENDING","status":"PENDING"}',
ioid='ktv_demucs_separate_io' WHERE id='uapi_ktv_demucs_separate';
-- 3. 人脸检测 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"image_file":"{{image_file}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","faces":{{json.dumps(faces,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_face_detect_io' WHERE id='uapi_ktv_face_detect';
-- 4. 人脸识别 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"image_file":"{{image_file}}"{%if face_id%},"face_id":"{{face_id}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","matches":{{json.dumps(matches,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_face_recognize_io' WHERE id='uapi_ktv_face_recognize';
-- 5. 人脸比对 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"image_file1":"{{image_file1}}","image_file2":"{{image_file2}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","similarity":{{similarity}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_face_compare_io' WHERE id='uapi_ktv_face_compare';
-- 6. 字幕渲染 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"lyrics_json":{{lyrics_json}}{%if width%},"width":{{width}}{%endif%}{%if height%},"height":{{height}}{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","ass_url":"{{ass_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_subtitle_render_io' WHERE id='uapi_ktv_subtitle_render';
-- 7. 视频合并 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{%set c=joiner(",")%}{{%if video_file%}{{c()}}"video_file":"{{video_file}}"{%endif%}{%if audio_file%}{{c()}}"audio_file":"{{audio_file}}"{%endif%}{%if subtitle_file%}{{c()}}"subtitle_file":"{{subtitle_file}}"{%endif%}{%if output_format%}{{c()}}"output_format":"{{output_format}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","output_url":"{{output_url}}","duration":{{duration}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_merge_video_io' WHERE id='uapi_ktv_merge_video';
-- 8. 歌曲评分 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"audio_file":"{{audio_file}}"{%if scene%},"scene":"{{scene}}"{%endif%}}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","score":{{score}},"details":{{json.dumps(details,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_songrate_evaluate_io' WHERE id='uapi_ktv_songrate_evaluate';
-- 9. 合成状态查询 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"task_id":"{{task_id}}"}',
response='{%if error%}{"error":"{{error}}"}{%elif status=="SUCCEEDED"%}{"taskstatus":"SUCCEEDED","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%elif status=="FAILED"%}{"taskstatus":"FAILED","error":"{{error}}"}{%else%}{"taskstatus":"PENDING"}{%endif%}',
ioid='ktv_synth_status_io' WHERE id='uapi_ktv_synth_status';
-- 11. 超分辨率 (async提交)
UPDATE uapi SET stream='async',headers='{"Content-Type":"application/json"}',
data='{"image_file":"{{image_file}}"{%if scale%},"scale":{{scale}}{%endif%}}',
response='{"taskid":"{{task_id}}","taskstatus":"PENDING"}',
ioid='ktv_realesrgan_upscale_io' WHERE id='uapi_ktv_realesrgan_upscale';
-- 12. 超分状态查询 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data=NULL,
response='{"status":"{{status}}","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}',
ioid='ktv_realesrgan_status_io' WHERE id='uapi_ktv_realesrgan_status';
-- 13. RVC声音转换 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"audio_file":"{{audio_file}}","voice_model":"{{voice_model}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","output_url":"{{output_url}}","usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_rvc_convert_io' WHERE id='uapi_ktv_rvc_convert';
-- 14. 视频评估 (sync)
UPDATE uapi SET stream='sync',headers='{"Content-Type":"application/json"}',
data='{"video_file":"{{video_file}}"}',
response='{%if error%}{"error":"{{error}}"}{%else%}{"status":"{{status}}","score":{{score}},"details":{{json.dumps(details,ensure_ascii=False)}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}{%endif%}',
ioid='ktv_video_eval_evaluate_io' WHERE id='uapi_ktv_video_eval_evaluate';
-- async query_apiname
UPDATE llm_api_map SET query_apiname='realesrgan-status',query_period=5 WHERE llmid='llm_ktv_realesrgan_upscale';
-- ppid (v1/models 过滤要求 ppid IS NOT NULL)
UPDATE llm_api_map SET ppid='pp_ktv' WHERE llmid LIKE 'llm_ktv%' AND ppid IS NULL;
-- upappkey (API调用鉴权必需)
INSERT INTO upappkey (id,upappid,ownerid,apikey,orgid)
SELECT 'ktv_gateway_key','ktv-gateway','UiEi7hKqAmU1-jqQEVhZe','','0'
WHERE NOT EXISTS (SELECT 1 FROM upappkey WHERE upappid='ktv-gateway');

View File

@ -1,38 +0,0 @@
-- ============================================================
-- KTV Pipeline v1 API RBAC 权限配置
-- 新增 /v1/pipeline/submit 端点权限
-- ============================================================
-- 权限路径(供 load_path.py 或不直接支持的模块参考)
-- 目录级
-- /llmage/v1/pipeline logined
-- /llmage/v1/pipeline/submit logined
-- 文件级
-- /llmage/v1/pipeline/submit/index.dspy logined
-- ============================================================
-- Customer 角色权限API调用者需要
-- ============================================================
INSERT INTO permission (id, path, name)
SELECT REPLACE(UUID(), '-', ''), '/llmage/v1/pipeline/submit/index.dspy', 'KTV流水线提交'
WHERE NOT EXISTS (
SELECT 1 FROM permission WHERE path = '/llmage/v1/pipeline/submit/index.dspy'
);
-- 为 customer.admin 和 customer.user 角色授予权限
-- 注意:以下语句依赖 set_role_perm.py 或等效的角色-权限关联表
-- 如果用的是直接 role_permission 表:
INSERT IGNORE INTO role_permission (role_id, permission_id)
SELECT r.id, p.id
FROM role r, permission p
WHERE r.name IN ('customer.admin', 'customer.user')
AND p.path = '/llmage/v1/pipeline/submit/index.dspy';
-- ============================================================
-- 管理角色权限
-- ============================================================
INSERT IGNORE INTO role_permission (role_id, permission_id)
SELECT r.id, p.id
FROM role r, permission p
WHERE r.name IN ('owner.superuser', 'owner.admin', 'reseller.admin', 'reseller.operator')
AND p.path = '/llmage/v1/pipeline/submit/index.dspy';

View File

@ -1,101 +0,0 @@
-- ============================================================
-- KTV服务 定价修复 Part 4
-- 每个模型独立ppid + 按量计费(price_factors=字段名)
-- ============================================================
-- 1. 创建独立ppid每模型一个
INSERT INTO pricing_program (id,providerid,name) VALUES
('pp_ktv_asr','FZoJv7EUEdKL3pUt0BQ5S','KTV-语音识别'),
('pp_ktv_demucs','FZoJv7EUEdKL3pUt0BQ5S','KTV-音频分离'),
('pp_ktv_face_detect','FZoJv7EUEdKL3pUt0BQ5S','KTV-人脸检测'),
('pp_ktv_face_recognize','FZoJv7EUEdKL3pUt0BQ5S','KTV-人脸识别'),
('pp_ktv_face_compare','FZoJv7EUEdKL3pUt0BQ5S','KTV-人脸比对'),
('pp_ktv_subtitle','FZoJv7EUEdKL3pUt0BQ5S','KTV-字幕渲染'),
('pp_ktv_merge','FZoJv7EUEdKL3pUt0BQ5S','KTV-视频合并'),
('pp_ktv_songrate','FZoJv7EUEdKL3pUt0BQ5S','KTV-歌曲评分'),
('pp_ktv_synth_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-合成状态'),
('pp_ktv_realesrgan','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分辨率'),
('pp_ktv_realesrgan_status','FZoJv7EUEdKL3pUt0BQ5S','KTV-超分状态'),
('pp_ktv_rvc','FZoJv7EUEdKL3pUt0BQ5S','KTV-声音转换'),
('pp_ktv_video_eval','FZoJv7EUEdKL3pUt0BQ5S','KTV-视频评估')
ON DUPLICATE KEY UPDATE providerid=VALUES(providerid);
-- 2. 迁移 pricing_program_timing 到新 ppid
UPDATE pricing_program_timing SET ppid='pp_ktv_asr' WHERE id='pt_ktv_asr_transcribe';
UPDATE pricing_program_timing SET ppid='pp_ktv_demucs' WHERE id='pt_ktv_demucs_separate';
UPDATE pricing_program_timing SET ppid='pp_ktv_face_detect' WHERE id='pt_ktv_face_detect';
UPDATE pricing_program_timing SET ppid='pp_ktv_face_recognize' WHERE id='pt_ktv_face_recognize';
UPDATE pricing_program_timing SET ppid='pp_ktv_face_compare' WHERE id='pt_ktv_face_compare';
UPDATE pricing_program_timing SET ppid='pp_ktv_subtitle' WHERE id='pt_ktv_subtitle_render';
UPDATE pricing_program_timing SET ppid='pp_ktv_merge' WHERE id='pt_ktv_merge_video';
UPDATE pricing_program_timing SET ppid='pp_ktv_songrate' WHERE id='pt_ktv_songrate_evaluate';
UPDATE pricing_program_timing SET ppid='pp_ktv_synth_status' WHERE id='pt_ktv_synth_status';
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan' WHERE id='pt_ktv_realesrgan_upscale';
UPDATE pricing_program_timing SET ppid='pp_ktv_realesrgan_status' WHERE id='pt_ktv_realesrgan_status';
UPDATE pricing_program_timing SET ppid='pp_ktv_rvc' WHERE id='pt_ktv_rvc_convert';
UPDATE pricing_program_timing SET ppid='pp_ktv_video_eval' WHERE id='pt_ktv_video_eval_evaluate';
-- 3. 更新 pricing_data YAMLprice_factors=字段名(按量计费)
-- asr: audio_seconds × 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.01\n unit: audio_seconds' WHERE id='pt_ktv_asr_transcribe';
-- demucs: audio_seconds × 0.02
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.02\n unit: audio_seconds' WHERE id='pt_ktv_demucs_separate';
-- face-detect: detect_count × 0.10
UPDATE pricing_program_timing SET pricing_data='unit_values:\n detect_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: detect_count\n unit_prices: 0.10\n unit: detect_count' WHERE id='pt_ktv_face_detect';
-- face-recognize: recognize_count × 0.10
UPDATE pricing_program_timing SET pricing_data='unit_values:\n recognize_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: recognize_count\n unit_prices: 0.10\n unit: recognize_count' WHERE id='pt_ktv_face_recognize';
-- face-compare: compare_count × 0.10
UPDATE pricing_program_timing SET pricing_data='unit_values:\n compare_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: compare_count\n unit_prices: 0.10\n unit: compare_count' WHERE id='pt_ktv_face_compare';
-- subtitle: subtitle_count × 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n subtitle_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: subtitle_count\n unit_prices: 0.01\n unit: subtitle_count' WHERE id='pt_ktv_subtitle_render';
-- merge: output_seconds × 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n output_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: output_seconds\n unit_prices: 0.01\n unit: output_seconds' WHERE id='pt_ktv_merge_video';
-- songrate: audio_seconds × 0.005
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.005\n unit: audio_seconds' WHERE id='pt_ktv_songrate_evaluate';
-- synth-generate: audio_seconds × 0.20
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.20\n unit: audio_seconds' WHERE id='pt_ktv_synth_generate';
-- synth-status: flat 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次' WHERE id='pt_ktv_synth_status';
-- realesrgan-upscale: image_count × 0.50
UPDATE pricing_program_timing SET pricing_data='unit_values:\n image_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: image_count\n unit_prices: 0.50\n unit: image_count' WHERE id='pt_ktv_realesrgan_upscale';
-- realesrgan-status: flat 0.01
UPDATE pricing_program_timing SET pricing_data='unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次' WHERE id='pt_ktv_realesrgan_status';
-- rvc: audio_seconds × 0.15
UPDATE pricing_program_timing SET pricing_data='unit_values:\n audio_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: audio_seconds\n unit_prices: 0.15\n unit: audio_seconds' WHERE id='pt_ktv_rvc_convert';
-- video-eval: video_seconds × 0.05
UPDATE pricing_program_timing SET pricing_data='unit_values:\n video_seconds: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: video_seconds\n unit_prices: 0.05\n unit: video_seconds' WHERE id='pt_ktv_video_eval_evaluate';
-- 4. 更新 llm_api_map 指向独立 ppid
UPDATE llm_api_map SET ppid='pp_ktv_asr' WHERE llmid='llm_ktv_asr_transcribe';
UPDATE llm_api_map SET ppid='pp_ktv_demucs' WHERE llmid='llm_ktv_demucs_separate';
UPDATE llm_api_map SET ppid='pp_ktv_face_detect' WHERE llmid='llm_ktv_face_detect';
UPDATE llm_api_map SET ppid='pp_ktv_face_recognize' WHERE llmid='llm_ktv_face_recognize';
UPDATE llm_api_map SET ppid='pp_ktv_face_compare' WHERE llmid='llm_ktv_face_compare';
UPDATE llm_api_map SET ppid='pp_ktv_subtitle' WHERE llmid='llm_ktv_subtitle_render';
UPDATE llm_api_map SET ppid='pp_ktv_merge' WHERE llmid='llm_ktv_merge_video';
UPDATE llm_api_map SET ppid='pp_ktv_songrate' WHERE llmid='llm_ktv_songrate_evaluate';
UPDATE llm_api_map SET ppid='pp_ktv_synth_status' WHERE llmid='llm_ktv_synth_status';
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan' WHERE llmid='llm_ktv_realesrgan_upscale';
UPDATE llm_api_map SET ppid='pp_ktv_realesrgan_status' WHERE llmid='llm_ktv_realesrgan_status';
UPDATE llm_api_map SET ppid='pp_ktv_rvc' WHERE llmid='llm_ktv_rvc_convert';
UPDATE llm_api_map SET ppid='pp_ktv_video_eval' WHERE llmid='llm_ktv_video_eval_evaluate';
-- 修复 pricing_program 字符集不一致(生产环境 utf8mb4_general_ci vs organization utf8mb4_unicode_ci
ALTER TABLE pricing_program MODIFY ownerid VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE pricing_program MODIFY providerid VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -1,66 +0,0 @@
-- ============================================================
-- KTV服务 数据模板修复 Part 5
-- 匹配GPU实际参数名 + demucs async改造
-- ============================================================
-- asr: audio_file → audio_path
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if language%},"language":"{{language}}"{%endif%}}' WHERE id='uapi_ktv_asr_transcribe';
-- demucs: audio_file → audio_path
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if task_type%},"task_type":"{{task_type}}"{%endif%}}' WHERE id='uapi_ktv_demucs_separate';
-- face-detect: image_file → images list
UPDATE uapi SET data='{"images":["{{image_file}}"]}' WHERE id='uapi_ktv_face_detect';
-- face-recognize: image_file → images list
UPDATE uapi SET data='{"images":["{{image_file}}"]{%if face_id%},"face_id":"{{face_id}}"{%endif%}}' WHERE id='uapi_ktv_face_recognize';
-- face-compare: image_file1→embedding1, image_file2→embedding2
UPDATE uapi SET data='{"embedding1":"{{image_file1}}","embedding2":"{{image_file2}}"}' WHERE id='uapi_ktv_face_compare';
-- subtitle: lyrics_json → lyrics
UPDATE uapi SET data='{"lyrics":{{lyrics_json}}{%if width%},"width":{{width}}{%endif%}{%if height%},"height":{{height}}{%endif%}}' WHERE id='uapi_ktv_subtitle_render';
-- merge: video_file→video_url, audio_file→audio_path
UPDATE uapi SET data='{%set c=joiner(",")%}{{%if video_file%}{{c()}}"video_url":"{{video_file}}"{%endif%}{%if audio_file%}{{c()}}"audio_path":"{{audio_file}}"{%endif%}{%if subtitle_file%}{{c()}}"subtitle_url":"{{subtitle_file}}"{%endif%}{%if output_format%}{{c()}}"output_format":"{{output_format}}"{%endif%}}' WHERE id='uapi_ktv_merge_video';
-- songrate: audio_file→audio_path
UPDATE uapi SET data='{"audio_path":"{{audio_file}}"{%if scene%},"scene":"{{scene}}"{%endif%}}' WHERE id='uapi_ktv_songrate_evaluate';
-- synth-status: GET, params in query string, no body
UPDATE uapi SET httpmethod='GET', data=NULL, path='/synth/api/synth-status?task_id={{taskid}}' WHERE id='uapi_ktv_synth_status';
-- realesrgan-upscale: image_file→image_url
UPDATE uapi SET data='{"image_url":"{{image_file}}"{%if scale%},"scale":{{scale}}{%endif%}}' WHERE id='uapi_ktv_realesrgan_upscale';
-- realesrgan-status: GET, params in query string, no body
UPDATE uapi SET httpmethod='GET', data=NULL, path='/realesrgan/api/realesrgan-status?task_id={{taskid}}' WHERE id='uapi_ktv_realesrgan_status';
-- rvc: audio_file→audio_path, voice_model→model
UPDATE uapi SET data='{"audio_path":"{{audio_file}}","model":"{{voice_model}}"}' WHERE id='uapi_ktv_rvc_convert';
-- video-eval: video_file→video_url
UPDATE uapi SET data='{"video_url":"{{video_file}}"}' WHERE id='uapi_ktv_video_eval_evaluate';
-- ============================================================
-- demucs async 改造: status 查询端点 + query_apiname
-- ============================================================
INSERT INTO uapi (id,name,title,description,path,httpmethod,upappid,stream,headers,data,response,ioid)
VALUES ('uapi_ktv_demucs_status','demucs-status','Demucs Status',
'Query demucs task','/demucs/api/demucs-status?task_id={{taskid}}','GET',
'ktv-gateway','sync','{"Content-Type":"application/json"}',NULL,
'{"status":"{{status}}","vocals_url":"{{vocals_url}}","accompaniment_url":"{{accompaniment_url}}","duration":{{duration}},"usage":{{json.dumps(usage,ensure_ascii=False)}}}',
'ktv_demucs_separate_io')
ON DUPLICATE KEY UPDATE response=VALUES(response);
UPDATE llm_api_map SET query_apiname='demucs-status',query_period=5 WHERE llmid='llm_ktv_demucs_separate';
-- ============================================================
-- 补充缺失的 pricing_program_timing 记录
-- ============================================================
INSERT INTO pricing_program_timing (id,ppid,name,pricing_data,enabled_date,expired_date) VALUES
('pt_ktv_face_compare','pp_ktv_face_compare','KTV人脸比对','unit_values:\n compare_count: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: compare_count\n unit_prices: 0.10\n unit: compare_count','2025-01-01','9999-12-31'),
('pt_ktv_synth_status','pp_ktv_synth_status','KTV合成状态','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次','2025-01-01','9999-12-31'),
('pt_ktv_realesrgan_status','pp_ktv_realesrgan_status','KTV超分状态','unit_values:\n 次: 1\nfields:\n price_factors:\n type: string\n role: factor\n label: 计价因子\n unit_prices:\n type: float\n role: factor\n label: 单位定价\n unit:\n type: string\n role: factor\n label: 计价单位\npricings:\n- price_factors: flat\n unit_prices: 0.01\n unit: 次','2025-01-01','9999-12-31')
ON DUPLICATE KEY UPDATE ppid=VALUES(ppid), pricing_data=VALUES(pricing_data);

View File

@ -1,21 +0,0 @@
-- ============================================================
-- HappyHorse + image model name 修复
-- upstream aliyun 不认识中文模型名,需用英文 model identifier
-- ============================================================
-- t2v (HappyHorse 文生视频)
UPDATE uapi SET data = REPLACE(data, '"model": "{{model}}"', '"model": "happyhorse-1.0-t2v"')
WHERE name='t2v' AND upappid='tongyi-wan';
-- wan2.7-image-pro
UPDATE uapi SET data = REPLACE(data, '"model": "{{model}}"', '"model": "wan2.7-image-pro"')
WHERE name='wan2.7-image-sync' AND upappid='tongyi-wan';
-- ============================================================
-- ASR 修复: data JSON格式 + async + status端点
-- ============================================================
UPDATE uapi SET stream='async',
data='{"audio_path":"{{audio_file}}"{%if language%},"language":"{{language}}"{%endif%}}',
response='{"taskid":"{{task_id}}","taskstatus":"PENDING","status":"PENDING"}'
WHERE id='uapi_ktv_asr_transcribe';

View File

@ -1,30 +0,0 @@
#!/bin/bash
set -e
cd "$(dirname "$0")"
COUNT=0
set_perm() {
python set_role_perm.py "$1" "$2" > /dev/null 2>&1
COUNT=$((COUNT + 1))
}
echo ">>> Setting core paths to any role..."
# Core UI files
for p in "/index.ui" "/top.ui" "/center.ui" "/bottom.ui"; do
set_perm "any" "$p"
done
# bricks/* - all files and subdirectories
while IFS= read -r file; do
rel="${file#/home/hermesai/repos/sage/wwwroot}"
set_perm "any" "$rel"
done < <(find wwwroot/bricks -type f 2>/dev/null)
# public/* - all files and subdirectories
while IFS= read -r file; do
rel="${file#/home/hermesai/repos/sage/wwwroot}"
set_perm "any" "$rel"
done < <(find wwwroot/public -type f 2>/dev/null)
echo "Done. Set ${COUNT} paths to any."

View File

@ -1,4 +1,3 @@
import os
import sys import sys
import asyncio import asyncio
from sqlor.dbpools import DBPools from sqlor.dbpools import DBPools
@ -35,8 +34,7 @@ async def main():
role = sys.argv[1] role = sys.argv[1]
path = sys.argv[2] path = sys.argv[2]
dbname = os.environ.get('SAGE_RBAC_DB', 'sage') async with db.sqlorContext('sage') as sor:
async with db.sqlorContext(dbname) as sor:
perms = None perms = None
if '%' in path: if '%' in path:
perms = await sor.sqlExe("select * from permission where path like ${path}$", {'path': path}) perms = await sor.sqlExe("select * from permission where path like ${path}$", {'path': path})

149
start.sh Executable file
View File

@ -0,0 +1,149 @@
#!/bin/bash
# Sage Web Application Start Script
# 多进程支持: 端口复用 + 独立后台程序
#
# 架构说明:
# 1. 独立后台程序 (bin/*.py) - 每个只启动一次,避免重复
# 2. Sage Web Workers - 根据CPU核心数启动多个worker使用端口复用
set -e
# 切换到脚本所在目录
cd "$(dirname "$0")"
# 本地开发环境变量(占位值,生产环境由系统配置)
export ALIPAY_PUB="$(pwd)/alipay_pub.pem"
export ALIPAY_PRIV="$(pwd)/alipay_priv.pem"
export BAIDU_SMS_ACCESS_KEY="dev-placeholder"
export BAIDU_SMS_ACCESS_KEY_SECRET="dev-placeholder"
export BAIDU_SMS_HOST="smsv3.bj.baidubce.com"
export BAIDU_SMS_SIGNATURE_ID="dev-placeholder"
# 配置
WORKDIR="$(pwd)"
PYTHON="./py3/bin/python"
APP_ENTRY="app/sage.py"
PIDFILE="$WORKDIR/sage.pid"
LOGDIR="$WORKDIR/logs"
BINPIDFILE="$WORKDIR/sage_backend.pid"
# 确保logs目录存在
mkdir -p "$LOGDIR"
# 检查Python是否存在
if [ ! -f "$PYTHON" ]; then
echo "错误: 找不到Python解释器 $PYTHON"
echo "请确保已安装虚拟环境: ./py3/bin/python"
exit 1
fi
# 检查应用入口文件是否存在
if [ ! -f "$APP_ENTRY" ]; then
echo "错误: 找不到应用入口文件 $APP_ENTRY"
exit 1
fi
# 检查Redis是否运行session存储依赖
if command -v redis-cli &> /dev/null; then
if ! redis-cli ping &> /dev/null; then
echo "Redis未运行正在启动Redis..."
redis-server --daemonize yes
sleep 1
if redis-cli ping &> /dev/null; then
echo "Redis启动成功"
else
echo "警告: Redis启动失败登录功能可能无法正常工作"
fi
else
echo "Redis运行正常"
fi
fi
echo "========================================="
echo "启动 Sage Web Application"
echo "工作目录: $WORKDIR"
echo "Python: $PYTHON"
echo "========================================="
# 获取端口
PORT=9180
if command -v python3 &> /dev/null; then
PORT=$($PYTHON -c "
import json
try:
with open('$WORKDIR/conf/config.json') as f:
config = json.load(f)
print(config.get('website', {}).get('port', 9180))
except Exception as e:
print(9180)
" 2>/dev/null || echo 9180)
fi
# =========================================
# 步骤 1: 启动独立后台程序
# =========================================
echo ""
echo "--- 启动独立后台程序 ---"
# 清空后台程序 PID 文件
> "$BINPIDFILE"
# 1.1 启动 LLM 后台计费程序
if [ -f "$WORKDIR/bin/backend_accounting.py" ]; then
LOGFILE="$LOGDIR/backend_accounting.log"
echo ">>> 启动 backend_accounting ..."
nohup $PYTHON "$WORKDIR/bin/backend_accounting.py" > "$LOGFILE" 2>&1 &
PID=$!
echo "backend_accounting:$PID" >> "$BINPIDFILE"
sleep 0.5
if kill -0 $PID 2>/dev/null; then
echo " -> backend_accounting PID: $PID (成功)"
else
echo " -> 警告: backend_accounting 启动失败,查看 $LOGFILE"
fi
fi
# =========================================
# 步骤 2: 启动 Sage Web Workers (端口复用)
# =========================================
echo ""
echo "--- 启动 Sage Web Workers (端口复用) ---"
# 获取 CPU 核心数,决定启动多少 Worker
WORKERS=$(nproc)
echo "检测到 ${WORKERS} 个 CPU 核心,准备启动 ${WORKERS} 个 worker 进程..."
echo "所有 worker 共享端口 ${PORT} (SO_REUSEPORT)"
# 清空 Worker PID 文件
> "$PIDFILE"
# 循环启动 Worker
for (( i=0; i<WORKERS; i++ ))
do
LOGFILE="$LOGDIR/sage_worker_${i}.log"
echo ">>> 启动 Worker $((i+1))/${WORKERS} on port $PORT ..."
# 启动服务 - 所有worker使用相同端口依赖ahserver的SO_REUSEPORT支持
nohup $PYTHON $APP_ENTRY --workdir "$WORKDIR" --port $PORT > "$LOGFILE" 2>&1 &
APP_PID=$!
# 保存 PID
echo "$APP_PID" >> "$PIDFILE"
# 短暂等待以检查是否立即崩溃
sleep 1
if kill -0 $APP_PID 2>/dev/null; then
echo " -> Worker PID: $APP_PID (成功)"
else
echo " -> 错误: Worker 启动失败,请查看 $LOGFILE"
fi
done
echo ""
echo "========================================="
echo "所有服务已启动"
echo "Worker PID 文件: $PIDFILE"
echo "Backend PID 文件: $BINPIDFILE"
echo "访问地址: http://localhost:${PORT}"
echo "========================================="

115
stop.sh Executable file
View File

@ -0,0 +1,115 @@
#!/bin/bash
# Sage Web Application Stop Script
# 停止所有 Web Workers 和独立后台程序
set -e
# 切换到脚本所在目录
cd "$(dirname "$0")"
WORKDIR="$(pwd)"
PIDFILE="$WORKDIR/sage.pid"
BINPIDFILE="$WORKDIR/sage_backend.pid"
echo "========================================="
echo "停止 Sage Web Application"
echo "========================================="
# =========================================
# 步骤 1: 停止 Web Workers
# =========================================
echo ""
echo "--- 停止 Web Workers ---"
if [ -f "$PIDFILE" ]; then
echo "读取 Worker PID 文件..."
while IFS= read -r pid || [ -n "$pid" ]; do
pid=$(echo "$pid" | tr -d '[:space:]')
[ -z "$pid" ] && continue
if kill -0 "$pid" 2>/dev/null; then
echo "正在停止 Worker (PID: $pid) ..."
kill "$pid" 2>/dev/null || true
else
echo "Worker (PID: $pid) 已不在运行"
fi
done < "$PIDFILE"
# 等待进程退出
echo "等待服务关闭..."
for i in $(seq 1 10); do
all_stopped=true
while IFS= read -r pid || [ -n "$pid" ]; do
pid=$(echo "$pid" | tr -d '[:space:]')
[ -z "$pid" ] && continue
if kill -0 "$pid" 2>/dev/null; then
all_stopped=false
break
fi
done < "$PIDFILE"
if $all_stopped; then
echo "所有 Worker 已停止 (用时 ${i}s)"
break
fi
sleep 1
done
# 强制杀死仍在运行的进程
while IFS= read -r pid || [ -n "$pid" ]; do
pid=$(echo "$pid" | tr -d '[:space:]')
[ -z "$pid" ] && continue
if kill -0 "$pid" 2>/dev/null; then
echo "强制停止 Worker (PID: $pid)"
kill -9 "$pid" 2>/dev/null || true
fi
done < "$PIDFILE"
# 清理 PID 文件
rm -f "$PIDFILE"
else
echo "未找到 Worker PID 文件 ($PIDFILE)"
fi
# =========================================
# 步骤 2: 停止独立后台程序
# =========================================
echo ""
echo "--- 停止独立后台程序 ---"
if [ -f "$BINPIDFILE" ]; then
echo "读取后台程序 PID 文件..."
while IFS= read -r line || [ -n "$line" ]; do
line=$(echo "$line" | tr -d '[:space:]')
[ -z "$line" ] && continue
# 格式: name:pid
name="${line%%:*}"
pid="${line##*:}"
if kill -0 "$pid" 2>/dev/null; then
echo "正在停止 $name (PID: $pid) ..."
kill "$pid" 2>/dev/null || true
sleep 1
if kill -0 "$pid" 2>/dev/null; then
echo "强制停止 $name (PID: $pid)"
kill -9 "$pid" 2>/dev/null || true
fi
echo " -> $name 已停止"
else
echo "$name (PID: $pid) 已不在运行"
fi
done < "$BINPIDFILE"
# 清理 PID 文件
rm -f "$BINPIDFILE"
else
echo "未找到后台程序 PID 文件 ($BINPIDFILE)"
fi
echo ""
echo "========================================="
echo "所有服务已停止"
echo "========================================="

View File

@ -1,17 +0,0 @@
import json
from appPublic.registerfunction import RegisterFunction
from appPublic.log import debug
rf = RegisterFunction()
funcs = list(rf.registKW.keys())
debug(f'check_rf: Registered functions: {funcs}')
# Try to call password directly
pw_func = rf.get('password')
debug(f'check_rf: password function = {pw_func}')
result = {
'functions': funcs,
'has_password': pw_func is not None
}
return json.dumps(result, ensure_ascii=False)

View File

@ -1,8 +0,0 @@
{% set lang = params_kw._lang or 'zh' %}
{
"widgettype": "ApiDoc",
"options": {
"md_url": "{{entire_url('/docs/api_doc_' + lang + '.md')}}",
"height": "100%"
}
}

View File

@ -1,142 +0,0 @@
# Yuanjing API Documentation
---
## LLM API
Base url: `https://token.opencomputing.cn/llmage/v1`
All endpoints require Bearer Token authentication.
---
## POST /v1/chat/completions
Text generation endpoint, OpenAI-compatible.
### Required Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `model` | string | Model name, e.g. `"qwen3-max"` |
| `messages` or `prompt` | array / string | Conversation messages or text prompt |
### Optional Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `catelogid` | string | Catalog type ID, default `"t2t"`, Chinese names supported |
| `stream` | boolean | Enable streaming output |
| `off_peak` | boolean | Use off-peak pricing |
| `transno` | string | Transaction ID (auto-generated if omitted) |
### Example Request
```json
{
"model": "qwen3-max",
"messages": [
{"role": "user", "content": "Hello"}
],
"stream": false
}
```
```bash
# Non-streaming
curl -X POST 'https://token.opencomputing.cn/llmage/v1/chat/completions' \\n -H 'Authorization: Bearer ***' \\n -H 'Content-Type: application/json' \\n -d '{\\n \"model\": \"qwen3-max\",\\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello, introduce yourself\"}],\\n \"stream\": false\\n }'
# Streaming
curl -X POST 'https://token.opencomputing.cn/llmage/v1/chat/completions' \\n -H 'Authorization: Bearer ***' \\n -H 'Content-Type: application/json' \\n -d '{\\n \"model\": \"qwen3-max\",\\n \"messages\": [{\"role\": \"user\", \"content\": \"Write a poem about spring\"}],\\n \"stream\": true\\n }'
```
### Response Format
**Non-streaming:**
```json
{
"id": "luid_xxx",
"object": "chat.completion",
"model": "qwen3-max",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "Hi there!"},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15}
}
```
**Streaming (SSE):**
```
data: {"choices": [{"delta": {"content": "Hi"}, "index": 0}]}
data: {"choices": [{"delta": {"content": " there!"}, "index": 0}]}
data: [DONE]
```
### Error Responses
| Status | Description |
|--------|-------------|
| 400 | Missing required parameters or model not found |
| 403 | Not authenticated |
| 429 | Insufficient account balance |
---
## POST /v1/video/generations
Video generation endpoint.
### Required Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `model` | string | Model name, e.g. `"keling-2.1"` |
| `catelogid` | string | Catalog type: `"t2v"` / `"i2v"` / `"r2v"` |
| `prompt` | string | Generation prompt |
### Optional Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `image_url` | string | Reference image URL for I2V |
| `duration` | string | Video duration, e.g. `"5s"` |
| `resolution` | string | Resolution, e.g. `"1080p"` |
| `n` | integer | Number of generations |
| `transno` | string | Transaction ID |
### Example Request
```json
{
"model": "keling-2.1",
"catelogid": "t2v",
"prompt": "A beautiful sunset over the ocean",
"duration": "5s",
"resolution": "1080p"
}
```
### Response Format
Video generation is typically async:
```json
{
"id": "luid_xxx",
"object": "video.generation",
"model": "keling-2.1",
"status": "submitted",
"taskid": "task_xxx",
"created": 1716912000
}
```
Query task status via `/v1/tasks?taskid=xxx`.
---
For detailed model-specific parameters (Vidu, Seedance, Wan, Kling, Hailuo, HappyHorse), see the [Chinese documentation](/docs/api_doc_zh.md).

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +0,0 @@
dbname = get_module_dbname('llmage')
db = DBPools()
async with db.sqlorContext(dbname) as sor:
# Create table
sql = """
CREATE TABLE IF NOT EXISTS llm_catalog_rel (
id VARCHAR(32) NOT NULL PRIMARY KEY,
llmid VARCHAR(32) NOT NULL,
llmcatelogid VARCHAR(32) NOT NULL,
INDEX idx_llm (llmid),
INDEX idx_catelog (llmcatelogid)
)
"""
try:
await sor.sqlExe(sql, {})
print("Table llm_catalog_rel created or exists.")
except Exception as e:
print(f"Create table error: {e}")
# Migrate data
sql = "select id, llmcatelogid from llm where llmcatelogid is not null and llmcatelogid != ''"
rows = await sor.sqlExe(sql, {})
print(f"Found {len(rows)} records to migrate.")
for r in rows:
data = {
'llmid': r['id'],
'llmcatelogid': r['llmcatelogid']
}
try:
await sor.C('llm_catalog_rel', data)
except Exception as e:
print(f"Insert error: {e}")
print("Migration complete.")
# Drop column
try:
await sor.sqlExe("alter table llm drop column llmcatelogid", {})
print("Column llmcatelogid dropped.")
except Exception as e:
print(f"Drop column error: {e}")
return {'status': 'ok'}

View File

@ -1,10 +1,4 @@
{
"widgettype": "VBox",
"options": {
"cheight": 40,
"width": "100%"
},
"subwidgets": [
{ {
"widgettype":"Tabular", "widgettype":"Tabular",
"options":{ "options":{
@ -333,6 +327,4 @@
"cache_limit":5 "cache_limit":5
} }
}
]
} }

View File

@ -1,13 +0,0 @@
# 多租户域名路由:解析当前请求域名对应的租户/分销商
env = request._run_ns
host = request.headers.get('X-Forwarded-Host') or request.host
host = host.split(':')[0]
try:
rec = await env.get_domain_by_host(request, host)
except Exception as e:
return json.dumps({'success': False, 'domain': host, 'error': str(e)}, ensure_ascii=False)
if rec:
result = {'success': True, 'domain': host, 'resellerid': rec.resellerid, 'orgid': rec.orgid}
else:
result = {'success': False, 'domain': host, 'error': 'Domain not found'}
return json.dumps(result, ensure_ascii=False)

View File

@ -1,432 +0,0 @@
{% set roles = get_user_roles(get_user()) %}
{% set role_str = roles|join(',') %}
{% set is_customer = 'customer.' in role_str %}
{% set is_customer_admin = 'customer.admin' in roles %}
{% set is_superuser = 'owner.superuser' in roles %}
{% set is_reseller_operator = 'reseller.operator' in roles %}
{% set is_any_admin = '.admin' in role_str %}
{
"widgettype": "Menu",
"id": "global_nav_menu",
"options": {
"width": "100%",
"height": "100%",
"items": [
{% if is_customer %}
{
"name": "dashboard",
"label": "仪表盘",
"icon": "{{entire_url('/imgs/dashboard.svg')}}",
"url": "{{entire_url('/sage_datamart/index.ui')}}",
"target": "app.sage_main_content"
}
,{
"name": "model_plaza",
"label": "模型广场",
"icon": "{{entire_url('/imgs/cubes.svg')}}",
"url": "{{entire_url('/llmage/model_plaza.ui')}}",
"target": "app.sage_main_content"
}
,{
"name": "reallife_asset",
"label": "真人素材",
"icon": "{{entire_url('/imgs/user-circle.svg')}}",
"url": "{{entire_url('/reallife_asset/index.ui')}}",
"target": "app.sage_main_content"
}
,{
"name": "llm_api",
"label": "大模型API调用",
"icon": "{{entire_url('/imgs/rocket.svg')}}",
"url": "{{entire_url('/docs/api_doc.ui')}}",
"target": "app.sage_main_content"
}
{% if is_customer_admin %}
,{
"name": "users",
"label": "用户管理",
"icon": "{{entire_url('/imgs/users.svg')}}",
"url": "{{entire_url('/rbac/users')}}",
"target": "app.sage_main_content"
}
,{
"name": "accounting_center",
"label": "账务中心",
"icon": "{{entire_url('/imgs/coins.svg')}}",
"items": [
{
"name": "my_accounts",
"label": "余额与充值",
"url": "{{entire_url('/accounting/myaccounts.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "credit_overview",
"label": "信用额度",
"url": "{{entire_url('/accounting/credit_limit/credit_overview.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "billing_query",
"label": "账单查询",
"url": "{{entire_url('/accounting/billing.ui')}}",
"target": "app.sage_main_content"
}
]
}
{% endif %}
{% else %}
{
"name": "dashboard",
"label": "仪表盘",
"icon": "{{entire_url('/imgs/dashboard.svg')}}",
"url": "{{entire_url('/sage_datamart/index.ui')}}",
"target": "app.sage_main_content"
}
,{
"name": "llm_api",
"label": "大模型API调用",
"icon": "{{entire_url('/imgs/rocket.svg')}}",
"url": "{{entire_url('/docs/api_doc.ui')}}",
"target": "app.sage_main_content"
}
,{
"name": "llmage",
"label": "模型管理",
"icon": "{{entire_url('/imgs/cubes.svg')}}",
"items": [
{
"name": "llmusage",
"label": "模型用量",
"url": "{{entire_url('/llmage/llmusage')}}",
"target": "app.sage_main_content"
},
{
"name": "catelog",
"label": "模型类型",
"url": "{{entire_url('/llmage/llmcatelog_list')}}",
"target": "app.sage_main_content"
},
{
"name": "model_plaza",
"label": "模型广场",
"url": "{{entire_url('/llmage/model_plaza.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "llm",
"label": "模型",
"url": "{{entire_url('/llmage/llm')}}",
"target": "app.sage_main_content"
},
{
"name": "failed_accounting",
"label": "记账失败记录",
"url": "{{entire_url('/llmage/failed_accounting.ui')}}",
"target": "app.sage_main_content"
}
]
}
,{
"name": "pricing",
"label": "定价管理",
"icon": "{{entire_url('/imgs/coins.svg')}}",
"url": "{{entire_url('/pricing/pricing_program')}}",
"target": "app.sage_main_content"
}
,{
"name": "discount",
"label": "折扣管理",
"icon": "{{entire_url('/imgs/percent.svg')}}",
"items": [
{
"name": "discount_list",
"label": "折扣方案",
"url": "{{entire_url('/discount/discount_list/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "discount_detail_list",
"label": "折扣产品明细",
"url": "{{entire_url('/discount/discount_detail_list/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "discount_marketing_list",
"label": "营销方案",
"url": "{{entire_url('/discount/discount_marketing_list/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "discount_promo_code_list",
"label": "促销码",
"url": "{{entire_url('/discount/discount_promo_code_list/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "discount_customer_bind_list",
"label": "客户归属",
"url": "{{entire_url('/discount/discount_customer_bind_list/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "free_customer_assign",
"label": "自由客户分配",
"url": "{{entire_url('/discount/free_customer_assign/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "customer_reassign",
"label": "客户再分配",
"url": "{{entire_url('/discount/customer_reassign/index.ui')}}",
"target": "app.sage_main_content"
}
]
}
,{
"name": "accounting_center",
"label": "账务中心",
"icon": "{{entire_url('/imgs/coins.svg')}}",
"items": [
{
"name": "acc_config",
"label": "账务配置",
"items": [
{
"name": "subject_manage",
"label": "科目设置",
"url": "{{entire_url('/accounting/subject/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "account_config",
"label": "账务设置",
"url": "{{entire_url('/accounting/account_config/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "accounting_config",
"label": "会计分录配置",
"url": "{{entire_url('/accounting/accounting_config/index.ui')}}",
"target": "app.sage_main_content"
}
]
},
{
"name": "acc_process",
"label": "财务处理",
"items": [
{
"name": "credit_limit_manage",
"label": "客户信用额度",
"url": "{{entire_url('/accounting/credit_limit/credit_manage.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "proxy_recharge",
"label": "代客充值",
"url": "{{entire_url('/accounting/proxy_recharge.ui')}}",
"target": "app.sage_main_content"
}
]
},
{
"name": "reseller_settle",
"label": "分销商结算",
"items": [
{
"name": "reseller_reconcile",
"label": "分销商对账",
"url": "{{entire_url('/supplychain/reseller_reconcile.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "reseller_detail_reconcile",
"label": "明细对账",
"url": "{{entire_url('/supplychain/reseller_detail_reconcile.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "reseller_settlement",
"label": "分销商结算",
"url": "{{entire_url('/supplychain/reseller_settlement.ui')}}",
"target": "app.sage_main_content"
}
]
},
{
"name": "provider_finance",
"label": "供应商财务",
"items": [
{
"name": "provider_recharge",
"label": "供应商充值",
"url": "{{entire_url('/supplychain/provider_recharge.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "provider_reconcile",
"label": "供应商对账",
"url": "{{entire_url('/supplychain/provider_reconcile.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "provider_detail_reconcile",
"label": "供应商明细对账",
"url": "{{entire_url('/supplychain/provider_detail_reconcile.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "provider_settlement",
"label": "供应商结算",
"url": "{{entire_url('/supplychain/provider_settlement.ui')}}",
"target": "app.sage_main_content"
}
]
}
]
}
,{
"name": "supply_chain",
"label": "供应链管理",
"icon": "{{entire_url('/imgs/truck.svg')}}",
"items": [
{
"name": "provider",
"label": "供应商管理",
"url": "{{entire_url('/supplychain/suppliers_list')}}",
"target": "app.sage_main_content"
},
{
"name": "reseller",
"label": "分销商管理",
"url": "{{entire_url('/supplychain/sub_distributors_list')}}",
"target": "app.sage_main_content"
}
]
}
,{
"name": "product_management",
"label": "产品管理",
"icon": "{{entire_url('/imgs/cubes.svg')}}",
"items": [
{
"name": "category",
"label": "产品类别管理",
"url": "{{entire_url('/product_management/product_category_tree')}}",
"target": "app.sage_main_content"
},
{
"name": "product",
"label": "产品管理",
"url": "{{entire_url('/product_management/product_list')}}",
"target": "app.sage_main_content"
}
]
}
,{
"name": "uapi",
"label": "上位系统管理",
"icon": "{{entire_url('/imgs/server.svg')}}",
"items": [
{
"name": "upapp",
"label": "上位系统",
"url": "{{entire_url('/uapi/upapp/index.ui')}}",
"target": "app.sage_main_content"
},
{
"name": "uapiio",
"label": "数据IO",
"url": "{{entire_url('/uapi/uapiio/index.ui')}}",
"target": "app.sage_main_content"
}
]
}
{% endif %}
{% if is_any_admin %}
,{
"name": "users",
"label": "用户管理",
"icon": "{{entire_url('/imgs/users.svg')}}",
"url": "{{entire_url('/rbac/users')}}",
"target": "app.sage_main_content"
}
{% endif %}
{% if is_reseller_operator or is_superuser %}
,{
"name": "tenant_manage",
"label": "租户管理",
"icon": "{{entire_url('/imgs/globe.svg')}}",
"url": "{{entire_url('/tenant/')}}",
"target": "app.sage_main_content"
}
{% endif %}
{% if is_superuser %}
,{
"name": "system_permission",
"label": "系统权限管理",
"icon": "{{entire_url('/imgs/key.svg')}}",
"items": [
{
"name": "role",
"label": "角色管理",
"url": "{{entire_url('/rbac/role')}}",
"target": "app.sage_main_content"
},
{
"name": "permission",
"label": "权限管理",
"url": "{{entire_url('/rbac/permission')}}",
"target": "app.sage_main_content"
},
{
"name": "rolepermission",
"label": "角色权限管理",
"url": "{{entire_url('/rbac/rolepermission')}}",
"target": "app.sage_main_content"
}
]
}
,{
"name": "sys_config",
"label": "基础配置",
"icon": "{{entire_url('/imgs/setting.svg')}}",
"children": [
{
"name": "appcodes",
"label": "编码管理",
"url": "{{entire_url('/appbase/appcodes')}}",
"target": "app.sage_main_content"
},
{
"name": "svgicon",
"label": "图标管理",
"url": "{{entire_url('/appbase/svgicon')}}",
"target": "app.sage_main_content"
},
{
"name": "currency",
"label": "币种管理",
"url": "{{entire_url('/accounting/currency_list')}}",
"target": "app.sage_main_content"
},
{
"name": "exchange_rate",
"label": "汇率管理",
"url": "{{entire_url('/accounting/exchange_rate_list')}}",
"target": "app.sage_main_content"
}
]
}{% endif %}
,{
"name": "apikey_manage",
"label": "API Key管理",
"icon": "{{entire_url('/imgs/key.svg')}}",
"url": "{{entire_url('/dapi/downapp/')}}",
"target": "app.sage_main_content"
}
],
"menuitem_css": "menuitem"
}
}

79
wwwroot/i18n/en/i18n.json Normal file
View File

@ -0,0 +1,79 @@
{
"en":"Engish",
"zh":"中文",
"jp":"日本语",
"ko":"韩语",
"启用日期": "Enabled date",
"失效日期": "Expired date",
"大语言模型": "LLMS",
"体验": "Experience",
"3D生成": "3D generate",
"AI搜索": "AI search",
"图像理解": "Visual understanding",
"密码": "Password",
"数字人": "Digital human",
"文图生视频": "Text image to video",
"文本分类": "Text classification",
"文生图": "Text to graghic",
"文生文": "Text to Text",
"文生语音": "Text to Speech",
"语言翻译": "Language transation",
"语音识别": "Audio Speech Recognize",
"音乐生成": "Music generate",
"充值": "Recharge",
"地址": "Address",
"帐务": "Accounting",
"平台运营": "Platform Business",
"我": "Me",
"我的角色": "My roles",
"手机": "Cell Phone",
"用户": "User",
"用户名": "User name",
"用户状态": "User Status",
"用户角色": "User roles",
"签退": "Logout",
"邮件地址": "Mail address",
"重置密码": "Reset password",
"主页": "home",
"模型广场": "llms",
"私有知识库": "my rags",
"关于我们": "About us",
"用户功能": "User functions",
"© 2024 版权所有, 开元云(北京)科技有限公司": "©2024 Open Computing AI",
"上位系统": "Up Application",
"下位系统": "Down Application",
"下位系统apikey": "Down App key",
"下位系统接口": "Down API",
"产品管理": "Product Mgr",
"供应协议": "Supply Agreement",
"供应商模型列表": "Llms by Supplier",
"元境平台": "YuanJing Platform",
"分销协议": "Distribution Agreement",
"套餐管理": "Package Mgr",
"套餐选择": "Package Options",
"定价管理": "Pricing Mgr",
"定价类型": "Pricing type",
"定价项目": "Pricing program",
"我的知识库": "My Rags",
"接口输入输出": "API input",
"接口集": "API set",
"服务目录": "Service catelog",
"服务管理": "Service Mgr",
"服务选择": "Service Options",
"服务配置": "Service Config",
"模型": "LLM maintain",
"模型列表": "LLM list",
"模型用量": "Llm Usage",
"模型管理": "LLm Mgr",
"模型类型": "Llm type",
"添加供应商": "Add supplier",
"爬取配置": "Crawle config",
"用户管理": "User Mgr",
"知识库加持大模型": "Rags based LLM",
"知识库管理": "Rags Mgr",
"知识获取": "Knowledge acquistion",
"网上知识源": "Knowledge resource on network",
"设备组": "Device group",
"配置": "Configuration",
"进入主菜单": "call main menu"
}

View File

@ -0,0 +1,2 @@
{
}

View File

@ -0,0 +1,2 @@
{
}

View File

@ -10,7 +10,6 @@ return [
{ {
"value":"jp", "value":"jp",
"text":"日本语" "text":"日本语"
}, },
{ {
"value":"ko", "value":"ko",

View File

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<line x1="2" y1="12" x2="22" y2="12"/>
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>
</svg>

Before

Width:  |  Height:  |  Size: 347 B

View File

@ -1,5 +1,4 @@
{ {
"id":"language", "id":"language",
"widgettype":"Text", "widgettype":"Text",
"options":{ "options":{

View File

@ -1,7 +1,5 @@
{ {
"widgettype":"Menu", "widgettype":"Menu",
"options":{ "options":{
"cwidth":11, "cwidth":11,
"target":"app", "target":"app",

21
wwwroot/i18n/zh/i18n.json Normal file
View File

@ -0,0 +1,21 @@
{
"Destroy this window":"销毁窗口",
"fullscreen this window":"全屏",
"minimize this window":"最小化",
"change UI language":"改变界面语言",
"Add record":"增加记录",
"add new record":"增加新记录",
"update selected record":"修改选定记录",
"clone selected record":"克隆选定记录",
"delete selected record":"删除选定记录",
"show all the closed window": "显示所有最小化的窗口",
"Submit":"提交",
"You need login to use llm":"请先登录",
"Not enrogh balance to use llm":"您余额不足以运行此模型",
"Cancel":"放弃",
"Reset":"重置",
"zh":"中文",
"en":"English",
"jp":"日本语",
"ko":"韩语"
}

View File

@ -1,14 +0,0 @@
import json
import os
lang = params.get('lang', 'zh')
i18n_dir = os.path.join(os.path.dirname(__file__), 'i18n', lang)
i18n_file = os.path.join(i18n_dir, 'i18n.json')
if os.path.exists(i18n_file):
with open(i18n_file, 'r', encoding='utf-8') as f:
msgs = json.load(f)
else:
msgs = {}
return json.dumps(msgs, ensure_ascii=False)

Some files were not shown because too many files have changed in this diff Show More