95d6bc2ae7
新增外部编辑器 OpenAPI 路由与 openapi.json 导出 新增账号级 API Key 表、鉴权、创建、列表和撤销链路 新增个人中心开发者 API Key 管理弹窗 补充前端契约、客户端方法、测试与项目文档
823 lines
21 KiB
JSON
823 lines
21 KiB
JSON
{
|
|
"openapi": "3.1.0",
|
|
"info": {
|
|
"title": "陶泥儿外部编辑器 OpenAPI",
|
|
"version": "1.0.0",
|
|
"description": "外部系统调用陶泥儿图片画布项目、画布布局保存和编辑器美术生图能力的 v1 契约。"
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "/",
|
|
"description": "当前部署环境"
|
|
}
|
|
],
|
|
"tags": [
|
|
{
|
|
"name": "Editor Projects",
|
|
"description": "图片画布项目"
|
|
},
|
|
{
|
|
"name": "Editor Canvas",
|
|
"description": "图片画布布局"
|
|
},
|
|
{
|
|
"name": "Editor Images",
|
|
"description": "编辑器美术生图"
|
|
},
|
|
{
|
|
"name": "API Keys",
|
|
"description": "登录态 API Key 管理接口,路径位于 /api/profile"
|
|
}
|
|
],
|
|
"paths": {
|
|
"/api/external/v1/openapi.json": {
|
|
"get": {
|
|
"tags": ["Editor Projects"],
|
|
"operationId": "getExternalOpenApiJson",
|
|
"summary": "读取外部 API OpenAPI JSON",
|
|
"security": [],
|
|
"responses": {
|
|
"200": {
|
|
"description": "OpenAPI 3.1 JSON",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/external/v1/editor/projects": {
|
|
"post": {
|
|
"tags": ["Editor Projects"],
|
|
"operationId": "createEditorProject",
|
|
"summary": "创建图片画布项目",
|
|
"security": [
|
|
{
|
|
"ExternalApiKey": []
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": false,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalEditorProjectCreateRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "已创建项目",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalEditorProjectResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/external/v1/editor/projects/{projectId}": {
|
|
"get": {
|
|
"tags": ["Editor Projects"],
|
|
"operationId": "getEditorProject",
|
|
"summary": "读取图片画布项目",
|
|
"security": [
|
|
{
|
|
"ExternalApiKey": []
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/ProjectId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "项目快照",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalEditorProjectResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/external/v1/editor/projects/{projectId}/canvas": {
|
|
"patch": {
|
|
"tags": ["Editor Canvas"],
|
|
"operationId": "saveEditorProjectCanvas",
|
|
"summary": "保存默认画布布局",
|
|
"security": [
|
|
{
|
|
"ExternalApiKey": []
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/ProjectId"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalEditorCanvasSaveRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "保存后的项目快照",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalEditorProjectResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"404": {
|
|
"$ref": "#/components/responses/NotFound"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/external/v1/editor/images/generations": {
|
|
"post": {
|
|
"tags": ["Editor Images"],
|
|
"operationId": "generateEditorImage",
|
|
"summary": "生成编辑器美术图片",
|
|
"security": [
|
|
{
|
|
"ExternalApiKey": []
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalEditorImageGenerationRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "生成结果与落库资源",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalEditorImageGenerationResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"$ref": "#/components/responses/BadRequest"
|
|
},
|
|
"401": {
|
|
"$ref": "#/components/responses/Unauthorized"
|
|
},
|
|
"403": {
|
|
"$ref": "#/components/responses/Forbidden"
|
|
},
|
|
"502": {
|
|
"$ref": "#/components/responses/UpstreamError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/profile/api-keys": {
|
|
"get": {
|
|
"tags": ["API Keys"],
|
|
"operationId": "listExternalApiKeys",
|
|
"summary": "列出当前登录账号的外部 API Key",
|
|
"description": "实际路径为 /api/profile/api-keys,使用登录态 Bearer JWT,不使用外部 API Key。",
|
|
"security": [
|
|
{
|
|
"UserAccessToken": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "API Key 列表",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalApiKeyListResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"tags": ["API Keys"],
|
|
"operationId": "createExternalApiKey",
|
|
"summary": "创建外部 API Key",
|
|
"description": "实际路径为 /api/profile/api-keys,明文 apiKey 只在本响应返回一次。",
|
|
"security": [
|
|
{
|
|
"UserAccessToken": []
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": false,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalApiKeyCreateRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "新建 API Key",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalApiKeyCreateResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/profile/api-keys/{keyId}": {
|
|
"delete": {
|
|
"tags": ["API Keys"],
|
|
"operationId": "revokeExternalApiKey",
|
|
"summary": "撤销外部 API Key",
|
|
"description": "实际路径为 /api/profile/api-keys/{keyId},使用登录态 Bearer JWT。",
|
|
"security": [
|
|
{
|
|
"UserAccessToken": []
|
|
}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "keyId",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "已撤销 API Key",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ExternalApiKeyResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"components": {
|
|
"securitySchemes": {
|
|
"ExternalApiKey": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"bearerFormat": "tnr_sk"
|
|
},
|
|
"UserAccessToken": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"bearerFormat": "JWT"
|
|
}
|
|
},
|
|
"parameters": {
|
|
"ProjectId": {
|
|
"name": "projectId",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"BadRequest": {
|
|
"description": "请求参数不合法",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ErrorResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"Unauthorized": {
|
|
"description": "未授权访问",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ErrorResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"Forbidden": {
|
|
"description": "禁止访问",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ErrorResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"NotFound": {
|
|
"description": "资源不存在",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ErrorResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"UpstreamError": {
|
|
"description": "上游生成服务失败",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ErrorResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"schemas": {
|
|
"ExternalEditorProjectCreateRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"title": {
|
|
"type": "string",
|
|
"maxLength": 80
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"ExternalEditorCanvasSaveRequest": {
|
|
"type": "object",
|
|
"required": ["viewport", "layers"],
|
|
"properties": {
|
|
"viewport": {
|
|
"$ref": "#/components/schemas/EditorCanvasViewport"
|
|
},
|
|
"layers": {
|
|
"type": "object",
|
|
"description": "画布图层 JSON,最大约 256KB。"
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"ExternalEditorImageGenerationRequest": {
|
|
"type": "object",
|
|
"required": ["prompt"],
|
|
"properties": {
|
|
"prompt": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"projectId": {
|
|
"type": "string"
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"description": "写入素材库时使用的素材名称。"
|
|
},
|
|
"size": {
|
|
"type": "string",
|
|
"enum": ["1024x1024", "1536x1024", "1024x1536", "2048x1152", "2048x2048"],
|
|
"default": "1024x1024"
|
|
},
|
|
"referenceImageSrcs": {
|
|
"type": "array",
|
|
"maxItems": 5,
|
|
"items": {
|
|
"type": "string",
|
|
"description": "图片 Data URL。"
|
|
}
|
|
},
|
|
"layers": {
|
|
"type": "object",
|
|
"description": "可选。带 projectId 时,生图完成后顺带保存画布图层 JSON。"
|
|
},
|
|
"viewport": {
|
|
"$ref": "#/components/schemas/EditorCanvasViewport"
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"ExternalEditorProjectResponse": {
|
|
"type": "object",
|
|
"required": ["project"],
|
|
"properties": {
|
|
"project": {
|
|
"$ref": "#/components/schemas/EditorProject"
|
|
}
|
|
}
|
|
},
|
|
"ExternalEditorImageGenerationResponse": {
|
|
"type": "object",
|
|
"required": [
|
|
"imageSrc",
|
|
"width",
|
|
"height",
|
|
"prompt",
|
|
"model",
|
|
"provider",
|
|
"taskId",
|
|
"asset"
|
|
],
|
|
"properties": {
|
|
"imageSrc": {
|
|
"type": "string",
|
|
"description": "生成图片 Data URL。"
|
|
},
|
|
"width": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"height": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"prompt": {
|
|
"type": "string"
|
|
},
|
|
"actualPrompt": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"model": {
|
|
"type": "string"
|
|
},
|
|
"provider": {
|
|
"type": "string"
|
|
},
|
|
"taskId": {
|
|
"type": "string"
|
|
},
|
|
"asset": {
|
|
"$ref": "#/components/schemas/EditorAsset"
|
|
},
|
|
"resource": {
|
|
"anyOf": [
|
|
{
|
|
"$ref": "#/components/schemas/EditorProjectResource"
|
|
},
|
|
{
|
|
"type": "null"
|
|
}
|
|
]
|
|
},
|
|
"project": {
|
|
"anyOf": [
|
|
{
|
|
"$ref": "#/components/schemas/EditorProject"
|
|
},
|
|
{
|
|
"type": "null"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"EditorProject": {
|
|
"type": "object",
|
|
"required": ["projectId", "title", "canvas", "viewport", "layers", "resources", "updatedAt"],
|
|
"properties": {
|
|
"projectId": {
|
|
"type": "string"
|
|
},
|
|
"title": {
|
|
"type": "string"
|
|
},
|
|
"canvas": {
|
|
"$ref": "#/components/schemas/EditorCanvas"
|
|
},
|
|
"viewport": {
|
|
"$ref": "#/components/schemas/EditorCanvasViewport"
|
|
},
|
|
"layers": {
|
|
"type": "object"
|
|
},
|
|
"resources": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/EditorProjectResource"
|
|
}
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"EditorCanvas": {
|
|
"type": "object",
|
|
"required": ["canvasId", "projectId", "title", "viewport", "layers", "createdAt", "updatedAt"],
|
|
"properties": {
|
|
"canvasId": {
|
|
"type": "string"
|
|
},
|
|
"projectId": {
|
|
"type": "string"
|
|
},
|
|
"title": {
|
|
"type": "string"
|
|
},
|
|
"viewport": {
|
|
"$ref": "#/components/schemas/EditorCanvasViewport"
|
|
},
|
|
"layers": {
|
|
"type": "object"
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"EditorCanvasViewport": {
|
|
"type": "object",
|
|
"required": ["x", "y", "scale"],
|
|
"properties": {
|
|
"x": {
|
|
"type": "number"
|
|
},
|
|
"y": {
|
|
"type": "number"
|
|
},
|
|
"scale": {
|
|
"type": "number",
|
|
"minimum": 0.01,
|
|
"maximum": 8
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"EditorProjectResource": {
|
|
"type": "object",
|
|
"required": ["resourceId", "projectId", "imageSrc", "width", "height", "sourceType", "createdAt", "updatedAt"],
|
|
"properties": {
|
|
"resourceId": {
|
|
"type": "string"
|
|
},
|
|
"projectId": {
|
|
"type": "string"
|
|
},
|
|
"imageSrc": {
|
|
"type": "string"
|
|
},
|
|
"objectKey": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"assetObjectId": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"width": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"height": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"sourceType": {
|
|
"type": "string"
|
|
},
|
|
"prompt": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"actualPrompt": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"model": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"provider": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"taskId": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"sourceResourceId": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"EditorAsset": {
|
|
"type": "object",
|
|
"required": ["assetId", "folderId", "label", "imageSrc", "width", "height", "sourceType", "createdAt", "updatedAt"],
|
|
"properties": {
|
|
"assetId": {
|
|
"type": "string"
|
|
},
|
|
"folderId": {
|
|
"type": "string"
|
|
},
|
|
"label": {
|
|
"type": "string"
|
|
},
|
|
"imageSrc": {
|
|
"type": "string"
|
|
},
|
|
"objectKey": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"assetObjectId": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"width": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"height": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"sourceType": {
|
|
"type": "string"
|
|
},
|
|
"prompt": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"actualPrompt": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"model": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"provider": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"taskId": {
|
|
"type": ["string", "null"]
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"ExternalApiKeyCreateRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"maxLength": 80
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"ExternalApiKeyCreateResponse": {
|
|
"type": "object",
|
|
"required": ["apiKey", "key"],
|
|
"properties": {
|
|
"apiKey": {
|
|
"type": "string",
|
|
"description": "仅创建时返回一次。"
|
|
},
|
|
"key": {
|
|
"$ref": "#/components/schemas/ExternalApiKey"
|
|
}
|
|
}
|
|
},
|
|
"ExternalApiKeyListResponse": {
|
|
"type": "object",
|
|
"required": ["keys"],
|
|
"properties": {
|
|
"keys": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ExternalApiKey"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"ExternalApiKeyResponse": {
|
|
"type": "object",
|
|
"required": ["key"],
|
|
"properties": {
|
|
"key": {
|
|
"$ref": "#/components/schemas/ExternalApiKey"
|
|
}
|
|
}
|
|
},
|
|
"ExternalApiKey": {
|
|
"type": "object",
|
|
"required": ["keyId", "name", "keyPrefix", "scopes", "createdAt", "updatedAt"],
|
|
"properties": {
|
|
"keyId": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"keyPrefix": {
|
|
"type": "string"
|
|
},
|
|
"scopes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"lastUsedAt": {
|
|
"type": ["string", "null"],
|
|
"format": "date-time"
|
|
},
|
|
"revokedAt": {
|
|
"type": ["string", "null"],
|
|
"format": "date-time"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"ErrorResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"code": {
|
|
"type": "string"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
},
|
|
"details": {
|
|
"type": ["object", "null"]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|