flnxi-Wu/docs/api/template-system-api.md
WuYongJie 473176997a docs: 完成API文档编写(任务26)
创建完整的API文档:
- 模板管理API(5个接口)
  * 获取模板列表
  * 获取模板详情(含使用统计)
  * 创建模板(含验证规则)
  * 更新模板(含版本控制)
  * 删除模板(含使用检查)

- 模板验证API
  * 内置模板验证逻辑
  * 自定义模板验证逻辑
  * 内置模板列表

- 字段池管理API(2个接口)
  * 获取字段池列表
  * 同步字段池

- 分类字段管理API
  * 获取分类管理字段

- 错误代码规范
  * 统一错误响应格式
  * 常见错误代码说明

- 性能指标
  * 响应时间目标
  * 数据库优化说明(20+个索引)

- 最佳实践
  * 版本控制使用方法
  * 错误处理示例
  * 字段验证示例
  * 性能优化建议

文档位置:docs/api/template-system-api.md
2025-12-13 15:42:39 +08:00

575 lines
12 KiB
Markdown
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.

# 自定义上传模板系统 API 文档
## 概述
本文档描述了自定义上传模板系统的所有API接口,包括模板管理、字段管理、字段池管理等功能。
## 基础信息
- **Base URL**: `/api`
- **认证方式**: Session Cookie
- **内容类型**: `application/json`
- **字符编码**: UTF-8
## 错误代码
所有API遵循统一的错误响应格式:
```json
{
"error": "错误信息",
"errorCode": "ERROR_CODE",
"details": {
// 详细错误信息(可选)
}
}
```
### 常见错误代码
| 错误代码 | HTTP状态码 | 说明 |
|---------|-----------|------|
| `VALIDATION_ERROR` | 400 | 请求参数验证失败 |
| `UNAUTHORIZED` | 401 | 未授权访问 |
| `FORBIDDEN` | 403 | 权限不足 |
| `NOT_FOUND` | 404 | 资源不存在 |
| `CONFLICT` | 409 | 资源冲突(如版本冲突) |
| `INTERNAL_ERROR` | 500 | 服务器内部错误 |
## 模板管理 API
### 1. 获取模板列表
获取所有自定义上传模板列表。
**请求**
```http
GET /api/admin/upload-templates
```
**响应**
```json
[
{
"id": "uuid",
"name": "3DMAX 素材模板",
"description": "适用于 3D 模型类素材",
"status": "active",
"materialType": "3DMAX",
"materialKind": "IMAGE",
"version": 1,
"fieldGroups": null,
"displayConfig": null,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"fields": [
{
"id": "uuid",
"key": "productModel",
"label": "SPU型号",
"type": "text",
"required": true,
"orderIndex": 0,
"layoutWidth": "full",
"validations": null,
"optionsStatic": null,
"allowedExtensions": null,
"visibleOnHomeFilter": false,
"isSearchable": true,
"isReadOnly": false,
"addToCategory": false,
"conditions": null
}
]
}
]
```
**字段说明**
- `status`: 模板状态 - `draft`(草稿)、`active`(启用)、`archived`(归档)
- `materialKind`: 素材大类 - `IMAGE`、`VIDEO`、`OTHER`
- `fields`: 模板字段数组,按 `orderIndex` 排序
### 2. 获取单个模板详情
获取指定模板的详细信息,包括使用统计。
**请求**
```http
GET /api/admin/upload-templates/:id
```
**响应**
```json
{
"id": "uuid",
"name": "3DMAX 素材模板",
"description": "适用于 3D 模型类素材",
"status": "active",
"materialType": "3DMAX",
"materialKind": "IMAGE",
"version": 1,
"fieldGroups": null,
"displayConfig": null,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"fields": [...],
"materialCount": 150,
"materials": [
{
"id": "uuid",
"previewUrl": "https://...",
"productModel": "ABC-123"
}
],
"fieldStats": [
{
"key": "productModel",
"label": "SPU型号",
"filledCount": 150,
"fillRate": 100,
"isLowFillRate": false
}
]
}
```
**字段说明**
- `materialCount`: 使用该模板的素材数量
- `materials`: 使用该模板的素材列表(最多10个预览)
- `fieldStats`: 字段填写率统计
- `fillRate`: 填写率百分比(0-100)
- `isLowFillRate`: 是否为低填写率字段(<30%)
### 3. 创建模板
创建新的自定义上传模板。
**请求**
```http
POST /api/admin/upload-templates
Content-Type: application/json
{
"name": "新模板",
"description": "模板描述",
"status": "draft",
"materialType": "3DMAX",
"materialKind": "IMAGE",
"fieldGroups": null,
"displayConfig": null,
"fields": [
{
"key": "productModel",
"label": "SPU型号",
"type": "text",
"required": true,
"orderIndex": 0,
"layoutWidth": "full",
"validations": null,
"optionsStatic": null,
"allowedExtensions": null,
"visibleOnHomeFilter": false,
"isSearchable": true,
"isReadOnly": false,
"addToCategory": false,
"conditions": null
}
]
}
```
**验证规则**
- `name`: 必填,不能为空
- `materialType`: 必填,有效值:`3DMAX`、`PSD`、`AI 工作流`、`视频`、`模特`、`其他`
- `materialKind`: 必填,有效值:`IMAGE`、`VIDEO`、`OTHER`
- `fields`: 必填,至少包含一个字段
- `fields[].key`: 必填,只能包含字母、数字、下划线,必须以字母开头,长度不超过50
- `fields[].key`: 在同一模板内必须唯一
- `fields[].type`: 必填,有效值:`text`、`textarea`、`number`、`select`、`checkbox`、`radio`、`date`、`uppercase`
**响应**
```json
{
"id": "uuid",
"name": "新模板",
"version": 1,
...
}
```
**错误响应示例**
```json
{
"error": "字段键名重复:字段 2 已使用键名 productModel",
"errorCode": "VALIDATION_ERROR"
}
```
### 4. 更新模板
更新现有模板,支持版本控制。
**请求**
```http
PUT /api/admin/upload-templates/:id
Content-Type: application/json
{
"name": "更新后的模板名称",
"description": "更新后的描述",
"status": "active",
"materialType": "3DMAX",
"materialKind": "IMAGE",
"version": 1,
"fieldGroups": null,
"displayConfig": null,
"fields": [...]
}
```
**版本控制**
- 请求必须包含 `version` 字段
- 如果服务器上的版本号与请求中的版本号不匹配,返回 409 冲突错误
- 更新成功后,版本号自动递增
**响应**
```json
{
"id": "uuid",
"name": "更新后的模板名称",
"version": 2,
...
}
```
**版本冲突错误**
```json
{
"error": "模板版本冲突,请刷新后重试",
"errorCode": "VERSION_CONFLICT",
"details": {
"clientVersion": 1,
"serverVersion": 2,
"lastUpdated": "2024-01-01T00:00:00Z"
}
}
```
### 5. 删除模板
删除指定模板。如果模板正在被使用,会返回警告信息。
**请求**
```http
DELETE /api/admin/upload-templates/:id
```
**响应**
```json
{
"success": true,
"message": "模板已删除"
}
```
**使用中的模板错误**
```json
{
"error": "该模板正在被 150 个素材使用,无法删除",
"errorCode": "TEMPLATE_IN_USE",
"details": {
"materialCount": 150
}
}
```
## 模板验证 API
### 验证模板ID
验证模板ID是否有效(内置模板或自定义模板)。
**内部使用**
此功能在素材上传API中自动调用,不需要单独调用。
**验证逻辑**
1. 如果 `templateId` 以 `builtin-` 开头,验证是否为有效的内置模板
2. 否则,从数据库查询验证模板是否存在
3. 如果 `templateId` 为空或 null,允许通过(向后兼容)
**内置模板列表**
- `builtin-3dmax-material`: 3DMAX 素材模板
- `builtin-psd-material`: PSD 素材模板
- `builtin-ai-material`: AI 工作流模板
- `builtin-video-material`: 视频素材模板
- `builtin-model-material`: 模特素材模板
- `builtin-other-material`: 其他素材模板
## 字段池管理 API
### 1. 获取字段池列表
获取所有字段定义及其选项。
**请求**
```http
GET /api/field-pool
```
**响应**
```json
[
{
"id": "uuid",
"key": "categoryName",
"label": "使用店铺",
"type": "select",
"description": "素材使用的店铺分类",
"source": "custom",
"sourceTemplateIds": ["uuid1", "uuid2"],
"isStandard": false,
"isFilterEnabled": true,
"filterDisplayName": "店铺",
"filterOrder": 1,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"options": [
{
"id": "uuid",
"value": "默认店铺",
"label": "默认店铺",
"orderIndex": 0
}
]
}
]
```
**字段说明**
- `source`: 字段来源 - `standard`(标准字段)、`custom`(自定义字段)
- `isFilterEnabled`: 是否启用为筛选字段
- `filterDisplayName`: 筛选时显示的名称(优先于 `label`)
- `filterOrder`: 筛选字段的排序顺序
### 2. 同步字段池
从模板同步字段到字段池(管理员操作)。
**请求**
```http
POST /api/admin/field-pool/sync
```
**响应**
```json
{
"success": true,
"syncedFields": 5,
"syncedOptions": 25,
"message": "字段池同步成功"
}
```
## 分类字段管理 API
### 获取分类管理字段
获取启用了分类管理的字段列表。
**请求**
```http
GET /api/category-fields
```
**响应**
```json
{
"managedFields": [
"categoryName",
"sceneName",
"renderer",
"brandName",
"seriesName",
"materialTexture"
]
}
```
## 性能指标
### 响应时间目标
| API | 目标响应时间 | 说明 |
|-----|------------|------|
| 获取模板列表 | < 200ms | 已添加数据库索引优化 |
| 获取模板详情 | < 300ms | 包含统计信息 |
| 创建模板 | < 500ms | 包含字段验证和同步 |
| 更新模板 | < 500ms | 包含版本检查和同步 |
| 删除模板 | < 200ms | 包含使用检查 |
| 字段池同步 | < 2s | 批量操作,支持重试 |
### 数据库优化
已添加以下索引以优化查询性能:
**UploadTemplate 表**
- `status` - 按状态筛选
- `materialType` - 按素材类型筛选
- `materialKind` - 按素材大类筛选
- `createdAt` / `updatedAt` - 按时间排序
**UploadField 表**
- `templateId` - 查询模板字段
- `key` - 按字段键名查询
- `type` - 按字段类型筛选
- `visibleOnHomeFilter` - 查询首页筛选字段
- `isSearchable` - 查询可搜索字段
- `addToCategory` - 查询分类管理字段
- `templateId, orderIndex` - 复合索引优化排序
**FieldDefinition 表**
- `source` - 按来源筛选
- `isStandard` - 查询标准字段
- `isFilterEnabled` - 查询启用的筛选字段
- `isFilterEnabled, filterOrder` - 复合索引优化筛选查询
**FieldOption 表**
- `fieldId` - 查询字段选项
- `fieldId, orderIndex` - 复合索引优化选项排序
## 最佳实践
### 1. 版本控制
更新模板时始终包含版本号,避免并发冲突:
```javascript
// 获取模板
const template = await fetch(`/api/admin/upload-templates/${id}`)
const data = await template.json()
// 更新时包含版本号
await fetch(`/api/admin/upload-templates/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...data,
name: '新名称',
version: data.version // 必须包含
})
})
```
### 2. 错误处理
始终处理API错误并向用户显示友好的错误信息:
```javascript
try {
const response = await fetch('/api/admin/upload-templates', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(templateData)
})
if (!response.ok) {
const error = await response.json()
// 显示错误信息
showError(error.error || '操作失败')
return
}
const result = await response.json()
// 处理成功结果
} catch (error) {
// 处理网络错误
showError('网络错误,请重试')
}
```
### 3. 字段验证
创建或更新模板前,在前端进行字段验证:
```javascript
// 验证字段key格式
const keyPattern = /^[a-zA-Z][a-zA-Z0-9_]*$/
if (!keyPattern.test(field.key)) {
showError('字段键名必须以字母开头,只能包含字母、数字和下划线')
return
}
// 验证字段key唯一性
const keys = fields.map(f => f.key)
const duplicates = keys.filter((key, index) => keys.indexOf(key) !== index)
if (duplicates.length > 0) {
showError(`字段键名重复:${duplicates[0]}`)
return
}
```
### 4. 性能优化
使用SWR或类似的缓存库减少不必要的API请求:
```javascript
import useSWR from 'swr'
function TemplateList() {
const { data, error, mutate } = useSWR(
'/api/admin/upload-templates',
fetcher,
{
revalidateOnFocus: false,
dedupingInterval: 5000
}
)
// 使用缓存的数据
return <div>{/* 渲染模板列表 */}</div>
}
```
## 更新日志
### 2024-12-13
- 添加数据库索引优化查询性能
- 添加模板使用统计API
- 添加字段填写率统计
- 优化错误响应格式
- 添加版本控制支持
### 2024-12-12
- 初始版本
- 实现模板CRUD API
- 实现字段池管理API
- 实现模板验证功能