feat(web): 成员端同构三页与日志详情,管理端轻量筛选
成员视图改管理端壳(总览/调用日志/支付参数),行内详情弹窗含原始数据; 成员日志含错误行;共享时间范围。管理端成员/支付筛选;支付仅留类型筛选。
This commit is contained in:
@@ -65,6 +65,7 @@ export const logItem = z.object({
|
||||
is_stream: z.boolean(),
|
||||
billing_source: z.string().nullable(),
|
||||
subscription_id: z.number().int().nullable(),
|
||||
raw: z.record(z.string(), z.unknown()).optional(),
|
||||
});
|
||||
|
||||
export const logPage = z.object({
|
||||
|
||||
@@ -37,6 +37,8 @@ export interface LogItem {
|
||||
is_stream: boolean;
|
||||
billing_source: BillingSource | null;
|
||||
subscription_id: number | null;
|
||||
/** 完整落库行(上游字段原貌)——「原始数据」视图 */
|
||||
raw?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface KeyItem {
|
||||
|
||||
@@ -597,20 +597,39 @@ export function createRepos(db: Db) {
|
||||
);
|
||||
},
|
||||
|
||||
/** 成员视图明细分页(恒 type=2) */
|
||||
/** 成员视图明细分页(可 type 筛;默认全类型) */
|
||||
async listMemberPage(params: {
|
||||
member_id: number;
|
||||
from: Date;
|
||||
to: Date;
|
||||
page: number;
|
||||
page_size: number;
|
||||
api_key_id?: number;
|
||||
billing_source?: string | "none";
|
||||
subscription_id?: number;
|
||||
type?: number | "error";
|
||||
}) {
|
||||
const conds = [
|
||||
eq(apiKeys.member_id, params.member_id),
|
||||
gte(usageLogs.created_at, params.from),
|
||||
lt(usageLogs.created_at, params.to),
|
||||
eq(usageLogs.type, 2),
|
||||
];
|
||||
if (params.type === "error") {
|
||||
conds.push(ne(usageLogs.type, 2));
|
||||
} else if (typeof params.type === "number") {
|
||||
conds.push(eq(usageLogs.type, params.type));
|
||||
}
|
||||
if (params.api_key_id != null) {
|
||||
conds.push(eq(usageLogs.api_key_id, params.api_key_id));
|
||||
}
|
||||
if (params.billing_source === "none") {
|
||||
conds.push(isNull(usageLogs.billing_source));
|
||||
} else if (params.billing_source) {
|
||||
conds.push(eq(usageLogs.billing_source, params.billing_source));
|
||||
}
|
||||
if (params.subscription_id != null) {
|
||||
conds.push(eq(usageLogs.subscription_id, params.subscription_id));
|
||||
}
|
||||
const totalRows = await db
|
||||
.select({ n: count() })
|
||||
.from(usageLogs)
|
||||
@@ -621,6 +640,7 @@ export function createRepos(db: Db) {
|
||||
.select({
|
||||
id: usageLogs.id,
|
||||
api_key_id: usageLogs.api_key_id,
|
||||
dedupe_key: usageLogs.dedupe_key,
|
||||
created_at: usageLogs.created_at,
|
||||
token_name: apiKeys.token_name,
|
||||
model_name: usageLogs.model_name,
|
||||
@@ -633,6 +653,16 @@ export function createRepos(db: Db) {
|
||||
is_stream: usageLogs.is_stream,
|
||||
billing_source: usageLogs.billing_source,
|
||||
subscription_id: usageLogs.subscription_id,
|
||||
user_id: usageLogs.user_id,
|
||||
username: usageLogs.username,
|
||||
channel: usageLogs.channel,
|
||||
channel_name: usageLogs.channel_name,
|
||||
token_id: usageLogs.token_id,
|
||||
group_name: usageLogs.group_name,
|
||||
ip: usageLogs.ip,
|
||||
request_id: usageLogs.request_id,
|
||||
upstream_request_id: usageLogs.upstream_request_id,
|
||||
other: usageLogs.other,
|
||||
log_synced_at: apiKeys.log_synced_at,
|
||||
})
|
||||
.from(usageLogs)
|
||||
|
||||
Reference in New Issue
Block a user