From 6c2ccda2c73e4c6fe2890c6ebcf2b0b789df22cb Mon Sep 17 00:00:00 2001 From: yumoqing Date: Fri, 26 Jun 2026 17:55:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dllmusage=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E8=84=9A=E6=9C=AC500=E9=94=99=E8=AF=AF=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96CRUD=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将llmusage_ioinfo_display.ui和llmusage_usages_display.ui从Jinja模板改为.dspy脚本 - 在utils.py中添加get_llmusage_by_id和read_ioinfo_content两个函数 - 重写get_llmusage.dspy,避免sqlPaging子查询包装,分离count和data查询 - 为llmusage表添加use_time索引提升排序性能 - 更新load_path.py和json/llmusage.json引用新的.dspy文件 --- json/llmusage.json | 4 +-- llmage/utils.py | 26 ++++++++++++++ models/llmusage.json | 9 ++++- scripts/load_path.py | 4 +-- wwwroot/llmusage_ioinfo_display.dspy | 48 +++++++++++++++++++++++++ wwwroot/llmusage_ioinfo_display.ui | 35 ------------------- wwwroot/llmusage_usages_display.dspy | 52 ++++++++++++++++++++++++++++ wwwroot/llmusage_usages_display.ui | 35 ------------------- 8 files changed, 138 insertions(+), 75 deletions(-) create mode 100644 wwwroot/llmusage_ioinfo_display.dspy delete mode 100644 wwwroot/llmusage_ioinfo_display.ui create mode 100644 wwwroot/llmusage_usages_display.dspy delete mode 100644 wwwroot/llmusage_usages_display.ui diff --git a/json/llmusage.json b/json/llmusage.json index 8e409d0..3aabe13 100644 --- a/json/llmusage.json +++ b/json/llmusage.json @@ -31,7 +31,7 @@ "height": "70%" }, "options": { - "url": "{{entire_url('../llmusage_usages_display.ui')}}?id=${id}$" + "url": "{{entire_url('../llmusage_usages_display.dspy')}}?id=${id}$" } }, { @@ -45,7 +45,7 @@ "height": "70%" }, "options": { - "url": "{{entire_url('../llmusage_ioinfo_display.ui')}}?id=${id}$" + "url": "{{entire_url('../llmusage_ioinfo_display.dspy')}}?id=${id}$" } } ], diff --git a/llmage/utils.py b/llmage/utils.py index 2df9400..e2f6d3d 100644 --- a/llmage/utils.py +++ b/llmage/utils.py @@ -149,6 +149,32 @@ async def write_llmio(luid, io_dic): webpath = await fs.save(name, s, userid='llmio') return webpath +async def get_llmusage_by_id(usage_id): + """从数据库获取 llmusage 记录""" + env = ServerEnv() + async with get_sor_context(env, 'llmage') as sor: + sql = "select id, llmid, ioinfo, usages from llmusage where id = ${id}$" + recs = await sor.sqlExe(sql, {'id': usage_id}) + if recs and len(recs) > 0: + return dict(recs[0]) + return None + + +async def read_ioinfo_content(ioinfo_webpath): + """从 FileStorage 读取交互信息文件内容""" + if not ioinfo_webpath: + return None + try: + fs = FileStorage() + real_path = fs.realPath(ioinfo_webpath) + async with aiofiles.open(real_path, 'rb') as f: + bin_data = await f.read() + return json.loads(bin_data.decode('utf-8')) + except Exception as e: + debug(f'read_ioinfo_content error: {e}') + return None + + async def llm_query_orders(userorgid, page, pagerows=80): env = ServerEnv() async with get_sor_context(env, 'llmage') as sor: diff --git a/models/llmusage.json b/models/llmusage.json index 0e88fee..799931b 100644 --- a/models/llmusage.json +++ b/models/llmusage.json @@ -151,6 +151,13 @@ "userorgid", "use_time" ] + }, + { + "name": "idx_llmusage_usetime", + "idxtype": "index", + "idxfields": [ + "use_time" + ] } ], "codes": [ @@ -193,4 +200,4 @@ "cond": "parentid='accounting_status'" } ] -} +} \ No newline at end of file diff --git a/scripts/load_path.py b/scripts/load_path.py index d8aa50e..c078ff4 100644 --- a/scripts/load_path.py +++ b/scripts/load_path.py @@ -155,8 +155,8 @@ PATHS_LOGINED = [ f"/{MOD}/llmusage/delete_llmusage.dspy", f"/{MOD}/llmusage/get_llmusage.dspy", f"/{MOD}/llmusage/update_llmusage.dspy", - f"/{MOD}/llmusage_usages_display.ui", - f"/{MOD}/llmusage_ioinfo_display.ui", + f"/{MOD}/llmusage_usages_display.dspy", + f"/{MOD}/llmusage_ioinfo_display.dspy", # CRUD 子目录 — llmusage_accounting_failed/ f"/{MOD}/llmusage_accounting_failed/index.ui", diff --git a/wwwroot/llmusage_ioinfo_display.dspy b/wwwroot/llmusage_ioinfo_display.dspy new file mode 100644 index 0000000..59436c1 --- /dev/null +++ b/wwwroot/llmusage_ioinfo_display.dspy @@ -0,0 +1,48 @@ +import json +from llmage.utils import get_llmusage_by_id, read_ioinfo_content + +usage_id = params_kw.get('id') +if not usage_id: + return {"widgettype": "Message", "options": {"message": "缺少 id 参数", "type": "error"}} + +record = await get_llmusage_by_id(usage_id) +if not record: + return {"widgettype": "Message", "options": {"message": "未找到记录", "type": "error"}} + +llmid = record.get('llmid', '') +ioinfo_webpath = record.get('ioinfo', '') + +ioinfo_content = await read_ioinfo_content(ioinfo_webpath) if ioinfo_webpath else None +ioinfo_text = json.dumps(ioinfo_content, ensure_ascii=False, indent=2) if ioinfo_content else "无交互内容" + +return { + "widgettype": "VScrollPanel", + "options": { + "width": "100%", + "height": "100%" + }, + "subwidgets": [ + { + "widgettype": "VBox", + "options": { + "width": "100%", + "padding": "16px", + "spacing": 12 + }, + "subwidgets": [ + { + "widgettype": "Title4", + "options": { + "text": f"Model: {llmid}" + } + }, + { + "widgettype": "Text", + "options": { + "text": ioinfo_text + } + } + ] + } + ] +} diff --git a/wwwroot/llmusage_ioinfo_display.ui b/wwwroot/llmusage_ioinfo_display.ui deleted file mode 100644 index 25ec9b3..0000000 --- a/wwwroot/llmusage_ioinfo_display.ui +++ /dev/null @@ -1,35 +0,0 @@ -{% set sor = db.sqlorContext() %} -{% set row = sor.execute_sql('select llmid, ioinfo from llmusage where id = ${id}$').first() %} -{% set ioinfo = row.ioinfo if row and row.ioinfo else '' %} -{% set model_id = row.llmid if row else '' %} -{ - "widgettype": "VScrollPanel", - "options": { - "width": "100%", - "height": "100%" - }, - "subwidgets": [ - { - "widgettype": "VBox", - "options": { - "width": "100%", - "padding": "16px", - "spacing": 12 - }, - "subwidgets": [ - { - "widgettype": "Title4", - "options": { - "text": "Model: {{ model_id }}" - } - }, - { - "widgettype": "Text", - "options": { - "text": {{ ioinfo | tojson }} - } - } - ] - } - ] -} diff --git a/wwwroot/llmusage_usages_display.dspy b/wwwroot/llmusage_usages_display.dspy new file mode 100644 index 0000000..aaafb04 --- /dev/null +++ b/wwwroot/llmusage_usages_display.dspy @@ -0,0 +1,52 @@ +import json +from llmage.utils import get_llmusage_by_id + +usage_id = params_kw.get('id') +if not usage_id: + return {"widgettype": "Message", "options": {"message": "缺少 id 参数", "type": "error"}} + +record = await get_llmusage_by_id(usage_id) +if not record: + return {"widgettype": "Message", "options": {"message": "未找到记录", "type": "error"}} + +llmid = record.get('llmid', '') +usages_raw = record.get('usages', '') + +try: + usages_obj = json.loads(usages_raw) if isinstance(usages_raw, str) else usages_raw +except (json.JSONDecodeError, TypeError): + usages_obj = usages_raw + +usages_text = json.dumps(usages_obj, ensure_ascii=False, indent=2) if usages_obj else "无使用信息" + +return { + "widgettype": "VScrollPanel", + "options": { + "width": "100%", + "height": "100%" + }, + "subwidgets": [ + { + "widgettype": "VBox", + "options": { + "width": "100%", + "padding": "16px", + "spacing": 12 + }, + "subwidgets": [ + { + "widgettype": "Title4", + "options": { + "text": f"Model: {llmid}" + } + }, + { + "widgettype": "Text", + "options": { + "text": usages_text + } + } + ] + } + ] +} diff --git a/wwwroot/llmusage_usages_display.ui b/wwwroot/llmusage_usages_display.ui deleted file mode 100644 index ee7a112..0000000 --- a/wwwroot/llmusage_usages_display.ui +++ /dev/null @@ -1,35 +0,0 @@ -{% set sor = db.sqlorContext() %} -{% set row = sor.execute_sql('select llmid, usages from llmusage where id = ${id}$').first() %} -{% set usages = row.usages if row and row.usages else '' %} -{% set model_id = row.llmid if row else '' %} -{ - "widgettype": "VScrollPanel", - "options": { - "width": "100%", - "height": "100%" - }, - "subwidgets": [ - { - "widgettype": "VBox", - "options": { - "width": "100%", - "padding": "16px", - "spacing": 12 - }, - "subwidgets": [ - { - "widgettype": "Title4", - "options": { - "text": "Model: {{ model_id }}" - } - }, - { - "widgettype": "Text", - "options": { - "text": {{ usages | tojson }} - } - } - ] - } - ] -}