feat(admin): 优化后台运维与任务管理

完善平台、基准模型、定价规则和实时负载的紧凑查询与滚动展示,并固定关键操作列。

新增管理员任务记录、批量计费结算和用户组限流、额度及模型权限维护能力,同时补充任务脱敏、查询索引与 OpenAPI 契约。

验证:pnpm openapi、Go 全量测试、pnpm lint、pnpm test、pnpm build、gofmt 与差异格式检查均通过。
This commit is contained in:
2026-07-25 01:32:49 +08:00
parent b29d539d49
commit de10875439
38 changed files with 5015 additions and 425 deletions
+584
View File
@@ -3766,6 +3766,299 @@
}
}
},
"/api/admin/tasks": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "跨租户分页查询任务;请求、结果和执行快照中的常见敏感字段默认脱敏。",
"produces": [
"application/json"
],
"tags": [
"admin-tasks"
],
"summary": "管理员列出任务",
"parameters": [
{
"type": "string",
"description": "关键词,匹配任务、用户、租户、模型、平台和 API Key",
"name": "q",
"in": "query"
},
{
"type": "string",
"description": "网关租户 ID",
"name": "tenantId",
"in": "query"
},
{
"type": "string",
"description": "网关用户 ID",
"name": "userId",
"in": "query"
},
{
"type": "string",
"description": "用户组 ID",
"name": "userGroupId",
"in": "query"
},
{
"type": "string",
"description": "任务状态",
"name": "status",
"in": "query"
},
{
"type": "string",
"description": "执行平台 ID",
"name": "platformId",
"in": "query"
},
{
"type": "string",
"description": "调用或实际模型名称",
"name": "model",
"in": "query"
},
{
"type": "string",
"description": "模型类型",
"name": "modelType",
"in": "query"
},
{
"type": "string",
"description": "运行模式",
"name": "runMode",
"in": "query"
},
{
"type": "string",
"description": "计费状态",
"name": "billingStatus",
"in": "query"
},
{
"type": "string",
"description": "API Key ID、名称或前缀",
"name": "apiKey",
"in": "query"
},
{
"type": "string",
"description": "创建时间起点,支持 RFC3339 或日期格式",
"name": "createdFrom",
"in": "query"
},
{
"type": "string",
"description": "创建时间终点,支持 RFC3339 或日期格式",
"name": "createdTo",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "页码",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 50,
"description": "每页数量",
"name": "pageSize",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httpapi.AdminTaskListResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/tasks/{taskID}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回任意租户的任务详情;默认脱敏,sensitive=full 时返回完整存储内容。",
"produces": [
"application/json"
],
"tags": [
"admin-tasks"
],
"summary": "管理员获取任务详情",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "taskID",
"in": "path",
"required": true
},
{
"enum": [
"masked",
"full"
],
"type": "string",
"default": "masked",
"description": "敏感字段模式",
"name": "sensitive",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/store.AdminGatewayTask"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/tasks/{taskID}/param-preprocessing": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回任意租户任务的参数改写、校验或模板处理日志;默认脱敏。",
"produces": [
"application/json"
],
"tags": [
"admin-tasks"
],
"summary": "管理员获取任务参数预处理日志",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "taskID",
"in": "path",
"required": true
},
{
"enum": [
"masked",
"full"
],
"type": "string",
"default": "masked",
"description": "敏感字段模式",
"name": "sensitive",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httpapi.TaskParamPreprocessingLogListResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/tenants": {
"get": {
"security": [
@@ -9451,6 +9744,29 @@
}
}
},
"httpapi.AdminTaskListResponse": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/store.AdminGatewayTask"
}
},
"page": {
"type": "integer",
"example": 1
},
"pageSize": {
"type": "integer",
"example": 50
},
"total": {
"type": "integer",
"example": 42
}
}
},
"httpapi.AuditLogListResponse": {
"type": "object",
"properties": {
@@ -12334,6 +12650,274 @@
}
}
},
"store.AdminGatewayTask": {
"type": "object",
"properties": {
"adminContext": {
"$ref": "#/definitions/store.AdminTaskContext"
},
"apiKeyId": {
"type": "string"
},
"apiKeyName": {
"type": "string"
},
"apiKeyPrefix": {
"type": "string"
},
"asyncMode": {
"type": "boolean"
},
"attemptCount": {
"type": "integer"
},
"attempts": {
"type": "array",
"items": {
"$ref": "#/definitions/store.TaskAttempt"
}
},
"billingCurrency": {
"type": "string"
},
"billingSettledAt": {
"type": "string"
},
"billingStatus": {
"type": "string"
},
"billingSummary": {
"type": "object",
"additionalProperties": {}
},
"billingUpdatedAt": {
"type": "string"
},
"billingVersion": {
"type": "string"
},
"billings": {
"type": "array",
"items": {}
},
"cancellable": {
"type": "boolean"
},
"compatibilityProtocol": {
"type": "string"
},
"compatibilityPublicId": {
"type": "string"
},
"compatibilitySourceProtocol": {
"type": "string"
},
"compatibilitySubmitBody": {
"type": "object",
"additionalProperties": {}
},
"compatibilitySubmitHeaders": {
"type": "object",
"additionalProperties": {}
},
"compatibilitySubmitHttpStatus": {
"type": "integer"
},
"conversationId": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"error": {
"type": "string"
},
"errorCode": {
"type": "string"
},
"errorMessage": {
"type": "string"
},
"executionLeaseExpiresAt": {
"type": "string"
},
"externalTaskId": {
"type": "string"
},
"finalChargeAmount": {
"type": "number"
},
"finishedAt": {
"type": "string"
},
"gatewayTenantId": {
"type": "string"
},
"gatewayUserId": {
"type": "string"
},
"id": {
"type": "string"
},
"kind": {
"type": "string"
},
"message": {
"type": "string"
},
"metrics": {
"type": "object",
"additionalProperties": {}
},
"model": {
"type": "string"
},
"modelType": {
"type": "string"
},
"newMessageCount": {
"type": "integer"
},
"pricingSnapshot": {
"type": "object",
"additionalProperties": {}
},
"remoteTaskId": {
"type": "string"
},
"request": {
"type": "object",
"additionalProperties": {}
},
"requestFingerprint": {
"type": "string"
},
"requestId": {
"type": "string"
},
"requestedModel": {
"type": "string"
},
"reservationAmount": {
"type": "number"
},
"resolvedModel": {
"type": "string"
},
"responseDurationMs": {
"type": "integer"
},
"responseFinishedAt": {
"type": "string"
},
"responseStartedAt": {
"type": "string"
},
"result": {
"type": "object",
"additionalProperties": {}
},
"riverJobId": {
"type": "integer"
},
"runMode": {
"type": "string"
},
"status": {
"type": "string"
},
"submitted": {
"type": "boolean"
},
"tenantId": {
"type": "string"
},
"tenantKey": {
"type": "string"
},
"updatedAt": {
"type": "string"
},
"usage": {
"type": "object",
"additionalProperties": {}
},
"userGroupId": {
"type": "string"
},
"userGroupKey": {
"type": "string"
},
"userId": {
"type": "string"
},
"userSource": {
"type": "string"
}
}
},
"store.AdminTaskContext": {
"type": "object",
"properties": {
"latestPlatform": {
"$ref": "#/definitions/store.AdminTaskPlatformSummary"
},
"tenant": {
"$ref": "#/definitions/store.AdminTaskTenantSummary"
},
"user": {
"$ref": "#/definitions/store.AdminTaskUserSummary"
}
}
},
"store.AdminTaskPlatformSummary": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"provider": {
"type": "string"
}
}
},
"store.AdminTaskTenantSummary": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"tenantKey": {
"type": "string"
}
}
},
"store.AdminTaskUserSummary": {
"type": "object",
"properties": {
"displayName": {
"type": "string"
},
"email": {
"type": "string"
},
"id": {
"type": "string"
},
"source": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"store.AuditLog": {
"type": "object",
"properties": {
+388
View File
@@ -57,6 +57,22 @@ definitions:
$ref: '#/definitions/store.AccessRule'
type: array
type: object
httpapi.AdminTaskListResponse:
properties:
items:
items:
$ref: '#/definitions/store.AdminGatewayTask'
type: array
page:
example: 1
type: integer
pageSize:
example: 50
type: integer
total:
example: 42
type: integer
type: object
httpapi.AuditLogListResponse:
properties:
items:
@@ -2059,6 +2075,186 @@ definitions:
status:
type: string
type: object
store.AdminGatewayTask:
properties:
adminContext:
$ref: '#/definitions/store.AdminTaskContext'
apiKeyId:
type: string
apiKeyName:
type: string
apiKeyPrefix:
type: string
asyncMode:
type: boolean
attemptCount:
type: integer
attempts:
items:
$ref: '#/definitions/store.TaskAttempt'
type: array
billingCurrency:
type: string
billingSettledAt:
type: string
billingStatus:
type: string
billingSummary:
additionalProperties: {}
type: object
billingUpdatedAt:
type: string
billingVersion:
type: string
billings:
items: {}
type: array
cancellable:
type: boolean
compatibilityProtocol:
type: string
compatibilityPublicId:
type: string
compatibilitySourceProtocol:
type: string
compatibilitySubmitBody:
additionalProperties: {}
type: object
compatibilitySubmitHeaders:
additionalProperties: {}
type: object
compatibilitySubmitHttpStatus:
type: integer
conversationId:
type: string
createdAt:
type: string
error:
type: string
errorCode:
type: string
errorMessage:
type: string
executionLeaseExpiresAt:
type: string
externalTaskId:
type: string
finalChargeAmount:
type: number
finishedAt:
type: string
gatewayTenantId:
type: string
gatewayUserId:
type: string
id:
type: string
kind:
type: string
message:
type: string
metrics:
additionalProperties: {}
type: object
model:
type: string
modelType:
type: string
newMessageCount:
type: integer
pricingSnapshot:
additionalProperties: {}
type: object
remoteTaskId:
type: string
request:
additionalProperties: {}
type: object
requestFingerprint:
type: string
requestId:
type: string
requestedModel:
type: string
reservationAmount:
type: number
resolvedModel:
type: string
responseDurationMs:
type: integer
responseFinishedAt:
type: string
responseStartedAt:
type: string
result:
additionalProperties: {}
type: object
riverJobId:
type: integer
runMode:
type: string
status:
type: string
submitted:
type: boolean
tenantId:
type: string
tenantKey:
type: string
updatedAt:
type: string
usage:
additionalProperties: {}
type: object
userGroupId:
type: string
userGroupKey:
type: string
userId:
type: string
userSource:
type: string
type: object
store.AdminTaskContext:
properties:
latestPlatform:
$ref: '#/definitions/store.AdminTaskPlatformSummary'
tenant:
$ref: '#/definitions/store.AdminTaskTenantSummary'
user:
$ref: '#/definitions/store.AdminTaskUserSummary'
type: object
store.AdminTaskPlatformSummary:
properties:
id:
type: string
name:
type: string
provider:
type: string
type: object
store.AdminTaskTenantSummary:
properties:
id:
type: string
name:
type: string
tenantKey:
type: string
type: object
store.AdminTaskUserSummary:
properties:
displayName:
type: string
email:
type: string
id:
type: string
source:
type: string
username:
type: string
type: object
store.AuditLog:
properties:
action:
@@ -6201,6 +6397,198 @@ paths:
summary: 验证统一认证 Revision
tags:
- identity
/api/admin/tasks:
get:
description: 跨租户分页查询任务;请求、结果和执行快照中的常见敏感字段默认脱敏。
parameters:
- description: 关键词,匹配任务、用户、租户、模型、平台和 API Key
in: query
name: q
type: string
- description: 网关租户 ID
in: query
name: tenantId
type: string
- description: 网关用户 ID
in: query
name: userId
type: string
- description: 用户组 ID
in: query
name: userGroupId
type: string
- description: 任务状态
in: query
name: status
type: string
- description: 执行平台 ID
in: query
name: platformId
type: string
- description: 调用或实际模型名称
in: query
name: model
type: string
- description: 模型类型
in: query
name: modelType
type: string
- description: 运行模式
in: query
name: runMode
type: string
- description: 计费状态
in: query
name: billingStatus
type: string
- description: API Key ID、名称或前缀
in: query
name: apiKey
type: string
- description: 创建时间起点,支持 RFC3339 或日期格式
in: query
name: createdFrom
type: string
- description: 创建时间终点,支持 RFC3339 或日期格式
in: query
name: createdTo
type: string
- default: 1
description: 页码
in: query
name: page
type: integer
- default: 50
description: 每页数量
in: query
name: pageSize
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/httpapi.AdminTaskListResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 管理员列出任务
tags:
- admin-tasks
/api/admin/tasks/{taskID}:
get:
description: 返回任意租户的任务详情;默认脱敏,sensitive=full 时返回完整存储内容。
parameters:
- description: 任务 ID
in: path
name: taskID
required: true
type: string
- default: masked
description: 敏感字段模式
enum:
- masked
- full
in: query
name: sensitive
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/store.AdminGatewayTask'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"404":
description: Not Found
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 管理员获取任务详情
tags:
- admin-tasks
/api/admin/tasks/{taskID}/param-preprocessing:
get:
description: 返回任意租户任务的参数改写、校验或模板处理日志;默认脱敏。
parameters:
- description: 任务 ID
in: path
name: taskID
required: true
type: string
- default: masked
description: 敏感字段模式
enum:
- masked
- full
in: query
name: sensitive
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/httpapi.TaskParamPreprocessingLogListResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"404":
description: Not Found
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 管理员获取任务参数预处理日志
tags:
- admin-tasks
/api/admin/tenants:
get:
description: 管理端返回网关租户列表。