创建完整的API文档: - 模板管理API(5个接口) * 获取模板列表 * 获取模板详情(含使用统计) * 创建模板(含验证规则) * 更新模板(含版本控制) * 删除模板(含使用检查) - 模板验证API * 内置模板验证逻辑 * 自定义模板验证逻辑 * 内置模板列表 - 字段池管理API(2个接口) * 获取字段池列表 * 同步字段池 - 分类字段管理API * 获取分类管理字段 - 错误代码规范 * 统一错误响应格式 * 常见错误代码说明 - 性能指标 * 响应时间目标 * 数据库优化说明(20+个索引) - 最佳实践 * 版本控制使用方法 * 错误处理示例 * 字段验证示例 * 性能优化建议 文档位置:docs/api/template-system-api.md
575 lines
12 KiB
Markdown
575 lines
12 KiB
Markdown
# 自定义上传模板系统 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
|
||
- 实现模板验证功能
|