llmage/wwwroot/api/failed_accounting_list.dspy
yumoqing a6efef56e9 perf: 记账失败列表优化
- 去掉跨库JOIN,改用内存批量ID映射
- 不查failed_reason大TEXT字段
- handled状态直接后台转文本,前端不依赖data映射
2026-06-26 17:08:58 +08:00

133 lines
3.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

result = {'success': False, 'rows': [], 'total': 0, 'page': 1, 'page_size': 50}
try:
llmage_db = get_module_dbname('llmage')
sage_db = get_module_dbname('sage')
db = DBPools()
filters = {}
if params_kw.get('userorgid'):
filters['userorgid'] = params_kw.get('userorgid')
if params_kw.get('llmid'):
filters['llmid'] = params_kw.get('llmid')
if params_kw.get('handled') is not None and params_kw.get('handled') != '':
filters['handled'] = params_kw.get('handled')
if params_kw.get('start_date'):
filters['start_date'] = params_kw.get('start_date')
if params_kw.get('end_date'):
filters['end_date'] = params_kw.get('end_date')
try:
page = int(params_kw.get('page', 1))
except (ValueError, TypeError):
page = 1
if page < 1:
page = 1
page_size = int(params_kw.get('rows', params_kw.get('page_size', 20)))
async with db.sqlorContext(llmage_db) as sor:
conditions = []
ns = {}
if filters.get('userorgid'):
conditions.append("userorgid=${userorgid}$")
ns['userorgid'] = filters['userorgid']
if filters.get('llmid'):
conditions.append("llmid=${llmid}$")
ns['llmid'] = filters['llmid']
if filters.get('handled') is not None:
conditions.append("handled=${handled}$")
ns['handled'] = filters['handled']
if filters.get('start_date'):
conditions.append("use_date>=${start_date}$")
ns['start_date'] = filters['start_date']
if filters.get('end_date'):
conditions.append("use_date<=${end_date}$")
ns['end_date'] = filters['end_date']
where = ""
if conditions:
where = "WHERE " + " AND ".join(conditions)
# 不查 failed_reason大 TEXT只查列表需要的字段
sql = f"""
SELECT id, llmusageid, llmid, userid, userorgid, use_date, use_time,
amount, cost, failed_time, retry_count, handled
FROM llmusage_accounting_failed
{where}
ORDER BY failed_time DESC
"""
count_sql = f"""
SELECT count(*) as cnt
FROM llmusage_accounting_failed
{where}
"""
count_recs = await sor.sqlExe(count_sql, ns)
total = count_recs[0].cnt if count_recs else 0
offset = (page - 1) * page_size
query_sql = sql + f" LIMIT {page_size} OFFSET {offset}"
recs = await sor.sqlExe(query_sql, ns)
if recs:
# 收集所有需要转换的 ID
llm_ids = list(set(r.llmid for r in recs if r.llmid))
user_ids = list(set(r.userid for r in recs if r.userid))
org_ids = list(set(r.userorgid for r in recs if r.userorgid))
# 批量查询映射(内存中完成)
llm_map = {}
if llm_ids:
llm_recs = await sor.sqlExe(
"SELECT id, name FROM llm WHERE id IN ${ids}$",
{'ids': tuple(llm_ids)}
)
if llm_recs:
llm_map = {r.id: r.name for r in llm_recs}
user_map = {}
if user_ids:
async with db.sqlorContext(sage_db) as sage_sor:
user_recs = await sage_sor.sqlExe(
"SELECT id, username FROM users WHERE id IN ${ids}$",
{'ids': tuple(user_ids)}
)
if user_recs:
user_map = {r.id: r.username for r in user_recs}
org_map = {}
if org_ids:
async with db.sqlorContext(sage_db) as sage_sor:
org_recs = await sage_sor.sqlExe(
"SELECT id, orgname FROM organization WHERE id IN ${ids}$",
{'ids': tuple(org_ids)}
)
if org_recs:
org_map = {r.id: r.orgname for r in org_recs}
# 转换
handled_map = {'0': '未处理', '1': '已处理'}
rows = []
for r in recs:
d = dict(r)
d['llmid_text'] = llm_map.get(r.llmid, r.llmid)
d['userid_text'] = user_map.get(r.userid, r.userid)
d['userorgid_text'] = org_map.get(r.userorgid, r.userorgid)
d['handled_text'] = handled_map.get(r.handled, r.handled)
rows.append(d)
result['rows'] = rows
result['total'] = total
result['page'] = page
result['page_size'] = page_size
result['success'] = True
else:
result['success'] = True
except Exception as e:
result['error'] = str(e)
debug(f'failed_accounting_list error: {format_exc()}')
return json.dumps(result, ensure_ascii=False, default=str)