培训接口文档.md 13.4 KB

培训接口文档(泰额版)

模块:培训 / 资料中心
范围:泰额版后端(租户业务库,非 antis-foodlabeling-host
认证:Authorization: Bearer {token};业务请求建议带 __tenant: {tenantId}
JSON:camelCase
Base URL 示例:http://127.0.0.1:19002(以实际部署为准)
更新日期:2026-08-07


1. 业务说明

概念 说明
一级分类 parentId 为空
二级分类 parentId 指向一级分类 Id;仅两级
培训文件 只能挂在二级分类下
文件权限 落在文件上:Company / Region / Location,各为 ALLSPECIFIED
Company fl_partner;字段 partnerIds / companyIds 等价
Region fl_group;字段 regionIds / groupIds 等价
Location location;字段 locationIds

权限约定(推荐做法)

主路径:上传 / 编辑文件时直接传公司、区域、门店范围(可传 ALL 或具体多值 Id)。
独立「编辑文件权限」接口仅作兼容保留,前端可不使用。

维度 类型字段 Id 数组 说明
Company appliedPartnerType partnerIds / companyIds ALLSPECIFIED + Guid 列表(可含哨兵 "ALL"
Region appliedRegionType regionIds / groupIds 同上
Location availabilityType(别名 appliedLocationType locationIds 同上
  • 上传时不传任何 scope 字段 → 默认三维度均为 ALL
  • 编辑时不传任何 scope 字段 → 不改原权限(仅改文件名/排序)
  • 编辑时传入任一 scope 字段 → 整套权限按入参覆盖保存
  • SPECIFIED 且仅选当前上下文「恰好全集」时,回显保持具体 Guid / 声明类型,不误折成 ["ALL"](与标签模板等一致)

文件存储

环境 路径
Linux 生产 /www/wwwroot/FoodLabelingManagementSAAS/training
本地兜底 {API ContentRoot}/wwwroot/FoodLabelingManagementSAAS/training
库中 fileUrl /training/{存储文件名}
  • 单文件最大 20MB
  • 扩展名:.jpg/.jpeg/.png/.webp/.gif/.bmp.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx/.txt/.csv
  • fileTypeimage / doc / other

建表

  • 脚本:module/food-labeling-us/scripts/fl_training.sql
  • 在每个租户业务库执行;新租户开通时会自动执行

2. 接口一览

2.1 管理端 TrainingAppService

功能 方法 路由
分类树 GET /api/app/training/category-tree
新增分类 POST /api/app/training/category
编辑分类 PUT /api/app/training/category/{id}
删除分类 DELETE /api/app/training/category/{id}
上传文件(含权限) POST /api/app/training/file/upload
编辑文件(含权限) PUT /api/app/training/{id}/file
删除文件 DELETE /api/app/training/{id}/file
文件排序 PUT /api/app/training/sort-files
获取文件权限(兼容) GET /api/app/training/file-scope/{id}
设置文件权限(兼容) PUT /api/app/training/file-scope/{id}

上传、file-scope 为显式路由;其余多为 ABP 约定路由。以 Swagger 为准。
另有约定路径 GET/PUT /api/app/training/{id}/file-scope,与 file-scope/{id} 等价兼容。

2.2 APP UsAppTrainingAppService

功能 方法 路由
门店可见分类树+文件 GET /api/app/us-app-training/tree

3. 管理端接口详情

3.1 获取分类树

GET /api/app/training/category-tree

Query

参数 类型 必填 说明
keyword string 匹配分类名或文件名
locationId string 按门店过滤可见文件;不传则不过滤权限
includeFiles bool 是否返回文件,默认 true

响应要点:一级 children 为二级;二级 filesTrainingFileDto(含完整 scope 回显字段)。

[
  {
    "id": "1001",
    "categoryName": "分类1",
    "parentId": null,
    "orderNum": 100,
    "children": [
      {
        "id": "1002",
        "categoryName": "子1",
        "parentId": "1001",
        "orderNum": 90,
        "children": [],
        "files": [
          {
            "id": "23148558702612480",
            "categoryId": "1002",
            "fileName": "学情测评试题.pdf",
            "fileUrl": "/training/20260807120000_xxx.pdf",
            "fileType": "doc",
            "fileSize": 102400,
            "orderNum": 100,
            "appliedPartnerType": "ALL",
            "company": "All Companies",
            "partnerIds": ["ALL"],
            "companyIds": ["ALL"],
            "appliedRegionType": "SPECIFIED",
            "region": "武侯区",
            "regionIds": ["3a22e2f6-0679-9a5b-19b4-fc6db2d92dcc"],
            "groupIds": ["3a22e2f6-0679-9a5b-19b4-fc6db2d92dcc"],
            "availabilityType": "SPECIFIED",
            "location": "分店2",
            "locationIds": ["3a22e2f6-e944-2038-ffd8-fc82d9d388ac"],
            "creationTime": "2026-08-07T12:00:00",
            "lastModificationTime": "2026-08-07T12:00:00"
          }
        ]
      }
    ],
    "files": []
  }
]

3.2 新增分类

POST /api/app/training/category

{
  "categoryName": "Training",
  "parentId": null,
  "orderNum": 100
}
字段 说明
categoryName 必填;同级不可重名
parentId 空 = 一级;传一级 Id = 二级
orderNum 排序

响应TrainingCategoryGetOutputDtoid / categoryName / parentId / orderNum / 时间字段)

常见错误:名称为空、父级不存在、在二级下再建子级、同级重名。


3.3 编辑分类

PUT /api/app/training/category/{id}

{
  "categoryName": "Training(更新)",
  "orderNum": 90
}

不可改层级(parentId 不可改)。


3.4 删除分类

DELETE /api/app/training/category/{id}

软删除。规则:一级下仍有二级不可删;二级下仍有文件不可删。


3.5 上传文件(主路径,含权限)

POST /api/app/training/file/upload
Content-Type: multipart/form-data

表单字段 类型 必填 说明
file file 文件本体
categoryId string 二级分类 Id
orderNum int 排序
appliedPartnerType string ALL / SPECIFIED
partnerIds string[] 可重复传多个 form 字段;可含 ALL
companyIds string[] 同 partnerIds
appliedRegionType string ALL / SPECIFIED
regionIds string[] 可含 ALL
groupIds string[] 同 regionIds
availabilityType string Location:ALL / SPECIFIED
appliedLocationType string availabilityType 别名
locationIds string[] 可含 ALL

curl 示例(全 ALL)

curl -X POST "http://127.0.0.1:19002/api/app/training/file/upload" \
  -H "Authorization: Bearer <token>" \
  -H "__tenant: <tenantId>" \
  -F "file=@./手册.pdf" \
  -F "categoryId=<二级分类Id>" \
  -F "orderNum=100" \
  -F "appliedPartnerType=ALL" \
  -F "partnerIds=ALL" \
  -F "appliedRegionType=ALL" \
  -F "regionIds=ALL" \
  -F "availabilityType=ALL" \
  -F "locationIds=ALL"

curl 示例(指定公司 + 门店)

curl -X POST "http://127.0.0.1:19002/api/app/training/file/upload" \
  -H "Authorization: Bearer <token>" \
  -H "__tenant: <tenantId>" \
  -F "file=@./手册.pdf" \
  -F "categoryId=<二级分类Id>" \
  -F "appliedPartnerType=SPECIFIED" \
  -F "partnerIds=<partnerGuid>" \
  -F "appliedRegionType=SPECIFIED" \
  -F "regionIds=<groupGuid>" \
  -F "availabilityType=SPECIFIED" \
  -F "locationIds=<locationGuid1>" \
  -F "locationIds=<locationGuid2>"

响应:完整 TrainingFileDto(含 scope 回显,结构见 3.1)。


3.6 编辑文件(主路径,含权限)

PUT /api/app/training/{id}/file

{
  "fileName": "操作手册.pdf",
  "orderNum": 100,
  "appliedPartnerType": "SPECIFIED",
  "partnerIds": ["3a22e2f5-a785-ba39-9847-de45bdd47e50"],
  "companyIds": ["3a22e2f5-a785-ba39-9847-de45bdd47e50"],
  "appliedRegionType": "ALL",
  "regionIds": ["ALL"],
  "groupIds": ["ALL"],
  "availabilityType": "SPECIFIED",
  "locationIds": ["3a22e2f6-e944-2038-ffd8-fc82d9d388ac"]
}
字段 说明
fileName 必填;展示名(不换物理文件)
orderNum 排序
scope 各字段 见第 1 节;只要传了任一 scope 字段即整套覆盖;全不传则保持原权限

响应:完整 TrainingFileDto

curl -X PUT "http://127.0.0.1:19002/api/app/training/<fileId>/file" \
  -H "Authorization: Bearer <token>" \
  -H "__tenant: <tenantId>" \
  -H "Content-Type: application/json" \
  -d "{\"fileName\":\"学情测评试题.pdf\",\"orderNum\":100,\"appliedPartnerType\":\"ALL\",\"partnerIds\":[\"ALL\"],\"appliedRegionType\":\"ALL\",\"availabilityType\":\"ALL\",\"locationIds\":[\"ALL\"]}"

3.7 删除文件

DELETE /api/app/training/{id}/file

软删除,并清理 scope 关联行。


3.8 文件排序

PUT /api/app/training/sort-files

{
  "items": [
    { "id": "23148558702612480", "orderNum": 100 },
    { "id": "23148558702612481", "orderNum": 90 }
  ]
}

3.9 获取 / 设置文件权限(兼容,非推荐主路径)

方法 路由
GET /api/app/training/file-scope/{id}
PUT /api/app/training/file-scope/{id}

推荐:权限在 上传 / 编辑文件 中一并提交,不必单独调本接口。
本接口与 create/update 共用同一套 scope 保存逻辑;PUT body 与 scope 字段相同(无 fileName)。

GET 响应TrainingFileScopeOutputDto

{
  "appliedPartnerType": "SPECIFIED",
  "company": "成都分店",
  "partnerIds": ["3a22e2f5-a785-ba39-9847-de45bdd47e50"],
  "companyIds": ["3a22e2f5-a785-ba39-9847-de45bdd47e50"],
  "appliedRegionType": "SPECIFIED",
  "region": "武侯区",
  "regionIds": ["3a22e2f6-0679-9a5b-19b4-fc6db2d92dcc"],
  "groupIds": ["3a22e2f6-0679-9a5b-19b4-fc6db2d92dcc"],
  "availabilityType": "SPECIFIED",
  "location": "分店2",
  "locationIds": ["3a22e2f6-e944-2038-ffd8-fc82d9d388ac"]
}

PUT body 示例

{
  "appliedPartnerType": "ALL",
  "partnerIds": ["ALL"],
  "appliedRegionType": "SPECIFIED",
  "regionIds": ["3a22e2f6-0679-9a5b-19b4-fc6db2d92dcc"],
  "availabilityType": "SPECIFIED",
  "locationIds": ["3a22e2f6-e944-2038-ffd8-fc82d9d388ac"]
}

4. APP 接口

4.1 门店可见分类树

GET /api/app/us-app-training/tree

参数 类型 必填 说明
locationId string 当前门店 Id;校验用户可访问该门店
keyword string 匹配分类名或文件名

按门店过滤文件:Company / Region / Location 三维度 ALLSPECIFIED 命中该门店才可见。
响应结构同管理端分类树(includeFiles=true)。

curl -G "http://127.0.0.1:19002/api/app/us-app-training/tree" \
  --data-urlencode "locationId=<locationGuid>" \
  -H "Authorization: Bearer <token>" \
  -H "__tenant: <tenantId>"

5. TrainingFileDto 字段说明

字段 说明
id 文件 Id
categoryId 所属二级分类
fileName / fileUrl / fileType / fileSize 文件信息
orderNum 排序
appliedPartnerType Company:ALL / SPECIFIED
company Company 展示文案
partnerIds / companyIds Company Id 列表(可含 ALL
appliedRegionType Region:ALL / SPECIFIED
region Region 展示文案
regionIds / groupIds Region Id 列表
availabilityType Location:ALL / SPECIFIED
location Location 展示文案
locationIds 门店 Id 列表
creationTime / lastModificationTime 时间

6. 联调检查清单

  • [ ] 分类仅两级;文件只能挂二级
  • [ ] 上传可不传 scope → 默认三维度 ALL
  • [ ] 上传/编辑传 ALL 或具体多值 Guid → 库表 type 字段 + 关联表正确
  • [ ] 分类树 files[] 含完整 scope 回显
  • [ ] PUT .../file 不传 scope 时不改权限;传了则覆盖
  • [ ] GET/PUT /api/app/training/file-scope/{id} 不再 404(兼容路径)
  • [ ] APP us-app-training/tree 按 locationId 过滤可见文件
  • [ ] 文件 ≤20MB、扩展名合法

查库(租户业务库):

SELECT Id, FileName, AppliedPartnerType, AppliedRegionType, AvailabilityType
FROM fl_training_file WHERE IsDeleted = 0;

SELECT * FROM fl_training_file_partner WHERE TrainingFileId = '<fileId>';
SELECT * FROM fl_training_file_region WHERE TrainingFileId = '<fileId>';
SELECT * FROM fl_training_file_location WHERE TrainingFileId = '<fileId>';

7. 相关代码

说明 路径
管理端服务 FoodLabeling.Application/Services/TrainingAppService.cs
APP 服务 FoodLabeling.Application/Services/UsAppTrainingAppService.cs
Scope 辅助 FoodLabeling.Application/Helpers/TrainingFileScopeHelper.cs
建表脚本 module/food-labeling-us/scripts/fl_training.sql

8. 变更记录

日期 说明
2026-08-07 重写文档:权限并入上传/编辑;file-scope 改为兼容路径;补全 TrainingFileDto scope 回显与 curl 示例
(历史) 初版:分类树、文件 CRUD、独立 file-scope、APP tree