- 新增 dict 实体表,字典查询改为从数据库读取 - 使用 childrenKey 实现组件一级类型到二级字典的关系映射 - Component 查询后通过 DecodeDictKey 和 AfterLoad 自动补充翻译字段 - 移除 ComponentDto、本地字典常量和本地 seed 文件 - 将 common 能力按 decorators/interceptors/services/swagger 重新分层 - 使用全局 SaveBodyInterceptor 替代 SaveMiddleware 统一处理 save 请求 - 更新 MinIO、组件、字典接口的 Swagger 响应和少量关键注释 - 重写 README.md 和 API.md,补充项目功能、目录结构和接口说明 BREAKING CHANGE: 字典数据依赖数据库 dict 表维护,不再使用本地字典常量。
9.8 KiB
KT Template Online API
后端服务默认监听 48085,Swagger 地址为 /api,OpenAPI JSON 地址为 /api-json。
除文件下载接口外,接口统一返回:
{
"code": 200,
"msg": "操作成功",
"data": {}
}
失败时仍使用相同结构,常见为:
{
"code": 400,
"msg": "操作失败",
"data": null
}
功能模块
| 模块 | 说明 |
|---|---|
| Component | 组件/图表模板的列表、详情、新增、编辑、逻辑删除 |
| Dict | 数据库字典查询,以及组件一级类型到二级类型的数据库关系映射 |
| MinIO | Bucket 检查/创建、文件上传、列表、临时访问地址、下载和删除 |
| Common | 统一响应 Swagger 注解、字典翻译注解、POST */save 请求体规范化拦截器 |
通用规则
Save 请求体规范化
系统全局注册 SaveBodyInterceptor,默认会对 POST */save 请求删除 body.id,避免新增接口因为前端误传 id 而走指定主键保存。
如果个别接口需要保留 id,可在对应 Controller 方法上使用 @SkipSaveBodyNormalize()。
数据库字典翻译
字典数据维护在数据库 dict 表中。Component.typeMsg、Component.componentTypeMsg 会在 TypeORM AfterLoad 阶段根据字典缓存自动映射。
dict 表核心字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 字典 ID |
| dictKey | string | 字典分组,例如 COMPONENT_TYPE、CHART、COMPONENT |
| label | string | 展示文本 |
| value | string | 字典值 |
| childrenKey | string | 子字典分组,例如 COMPONENT_TYPE.value=1 指向 CHART |
| sort | number | 排序 |
| is_deleted | boolean | 逻辑删除标记 |
当前数据库示例关系:
| dictKey | value | label | childrenKey |
|---|---|---|---|
| COMPONENT_TYPE | 1 | 图表 | CHART |
| COMPONENT_TYPE | 2 | 组件 | COMPONENT |
数据结构
Component
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 组件 ID,新增时由后端生成 |
| name | string | 组件名称 |
| type | number | 一级类型,实际含义由 dict 表维护 |
| componentType | number | 二级类型,实际含义由 dict 表维护 |
| typeMsg | string | 一级类型文本,查询后自动映射 |
| componentTypeMsg | string | 二级类型文本,查询后自动映射 |
| image | string | 封面图或封面图地址 |
| template | string | Playground 序列化模板内容 |
| createTime | string | 创建时间 |
| updateTime | string | 更新时间 |
| is_deleted | boolean | 逻辑删除标记 |
Dict
接口返回的字典项结构:
| 字段 | 类型 | 说明 |
|---|---|---|
| label | string | 展示文本 |
| value | number/string | 字典值 |
MinIO
bucketName 未传时默认读取环境变量 MINIO_BUCKET,缺省值为 kt-template-online。
Root
GET /
重定向到 Swagger 文档页 /api#/,HTTP 状态码为 301。
Component 接口
GET /component/allList
获取全部组件。
响应 data:Component[]。
示例:
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": "1d8d3dd2-99f0-4d10-9a44-0cf9566b37c9",
"name": "基础折线图",
"type": 1,
"componentType": 1,
"typeMsg": "图表",
"componentTypeMsg": "折线图",
"image": "",
"template": "%7B%22version%22%3A%221.0%22%7D",
"createTime": "2026-05-13T02:30:00.000Z",
"updateTime": "2026-05-13T02:30:00.000Z",
"is_deleted": false
}
]
}
GET /component/list
分页获取组件列表。列表默认过滤 is_deleted=false,并支持按名称模糊搜索。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pageNo | number | 是 | 页码 |
| pageSize | number | 是 | 每页条数 |
| name | string | 否 | 组件名称模糊搜索 |
| type | number | 否 | 一级类型 |
| componentType | number | 否 | 二级类型 |
响应 data:
{
list: Component[]
total: number
}
GET /component/detail
获取组件详情。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 是 | 组件 ID |
响应 data:Component。
POST /component/save
新增组件。全局 SaveBodyInterceptor 会删除 body.id,新增时不需要传 id。
Body:
{
"name": "基础折线图",
"type": 1,
"componentType": 1,
"image": "",
"template": "%7B%22version%22%3A%221.0%22%7D"
}
响应 data:新增组件 ID。
{
"code": 200,
"msg": "操作成功",
"data": "1d8d3dd2-99f0-4d10-9a44-0cf9566b37c9"
}
POST /component/update
编辑组件。
Body:
{
"id": "1d8d3dd2-99f0-4d10-9a44-0cf9566b37c9",
"name": "基础折线图",
"type": 1,
"componentType": 1,
"image": "",
"template": "%7B%22version%22%3A%221.0%22%7D"
}
响应 data:true 表示更新成功。
POST /component/remove
逻辑删除组件。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 是 | 组件 ID |
响应 data:true 表示删除成功。
Dict 接口
GET /dict/getDictByKey
根据字典分组获取字典项。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| dictKey | string | 是 | 字典分组,例如 CHART |
响应示例:
{
"code": 200,
"msg": "操作成功",
"data": [
{
"label": "折线图",
"value": 1
}
]
}
GET /dict/getComponentDictByType
根据组件一级类型获取对应的二级类型字典。
查询逻辑:先查 dictKey=COMPONENT_TYPE 且 value=type 的字典项,再使用该项的 childrenKey 查询子字典。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | number | 是 | 一级类型 |
响应 data:Array<{ label: string; value: number | string }>。
MinIO 接口
GET /minio/check
检查 MinIO 连接和 bucket 状态。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bucketName | string | 否 | bucket 名称 |
响应 data:{ bucketName: string; exists: boolean }。
POST /minio/bucket
创建 bucket,已存在时跳过。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bucketName | string | 否 | bucket 名称 |
响应 data:bucket 名称。
POST /minio/upload
上传文件,请求类型为 multipart/form-data。
Body:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 文件 |
| bucketName | string | 否 | bucket 名称 |
| objectName | string | 否 | 对象名,不传时自动生成 |
响应示例:
{
"code": 200,
"msg": "操作成功",
"data": {
"bucketName": "kt-template-online",
"objectName": "uploads/1715580000000-a1b2c3-demo.png",
"etag": "9b2cf535f27731c974343645a3985328",
"size": 2048,
"mimeType": "image/png",
"url": "http://127.0.0.1:9000/kt-template-online/uploads/demo.png"
}
}
GET /minio/list
获取文件列表。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bucketName | string | 否 | bucket 名称 |
| prefix | string | 否 | 对象名前缀 |
| recursive | string | 否 | 是否递归,传 false 时不递归 |
响应 data:MinIO 对象数组,常见字段为 name、size、etag、lastModified。
GET /minio/url
获取文件临时访问地址。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| objectName | string | 是 | 对象名 |
| bucketName | string | 否 | bucket 名称 |
| expiry | string | 否 | 有效期秒数,默认 86400 秒 |
响应 data:临时访问 URL。
GET /minio/download
下载文件,直接返回文件流。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| objectName | string | 是 | 对象名 |
| bucketName | string | 否 | bucket 名称 |
DELETE /minio/remove
删除文件。
Query:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| objectName | string | 是 | 对象名 |
| bucketName | string | 否 | bucket 名称 |
响应 data:true 表示删除成功。