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)