2026-07-09代码修改.md 9.7 KB

2026-07-09 代码修改

本文档说明 2026-07-09 对美国版标签(Label)模块的接口补充:标签列表批量导入(Bulk Add Labels)。


一、背景与目标

项目 说明
业务场景 Web 管理端 Bulk Add Labels 页面:同一模板下多行录入标签基本字段 + 模板数据字段后一次性保存
原行为 前端 LabelsList.tsx 对每行循环调用 POST /api/app/label 单条创建,模板数据再单独 updateLabelTemplate
新行为 新增 POST /api/app/label/batch-create,一次提交多行;可选合并写入 fl_label_template_product_default
列表接口 GET /api/app/label?SkipCount=1&MaxResultCount=10 为标签分页列表(按标签维度分页,非 label-product 笛卡尔行)

二、标签列表

基本信息

项目 内容
方法 GET
路径 /api/app/label
鉴权 Bearer Token
示例 /api/app/label?SkipCount=1&MaxResultCount=10

分页参数

参数 类型 说明
SkipCount int 页码,从 1 起(非 0)
MaxResultCount int 每页条数

筛选参数(Query)

参数 说明
PartnerId 按 Company(fl_partner.Id)下门店集合筛选
GroupId 按 Region(fl_group.Id)筛选:命中 fl_label_regionfl_label_locationAppliedRegionType=ALL
LocationId 按门店(location.Id)筛选;传则优先于 GroupId
ProductId 按产品筛选(一个产品可对应多个标签)
Keyword 关键词
LabelCategoryId 标签分类
LabelTypeId 标签类型(可选)
TemplateCode 模板编码
State 启用状态

出参结构

{
  "pageIndex": 1,
  "pageSize": 10,
  "totalCount": 100,
  "totalPages": 10,
  "items": [
    {
      "id": "LBL_xxx",
      "labelName": "Turkey Breast",
      "locationName": "Store A, Store B",
      "locationIds": ["loc-id-1", "loc-id-2"],
      "region": "Region A",
      "regionIds": ["group-id-1"],
      "groupIds": ["group-id-1"],
      "appliedRegionType": "SPECIFIED",
      "labelCategoryName": "Prep",
      "productCategoryName": "Meat",
      "products": "Turkey Breast",
      "templateName": "3\"x6\" Nutrition Details",
      "templateCode": "tpl_229mx5_mr05n3cq",
      "labelTypeName": "Use By",
      "state": true,
      "lastEdited": "2026-07-09T10:00:00",
      "hasError": false
    }
  ]
}

列表 curl 示例

# 登录(管理端)
curl -X POST "http://192.168.31.88:19001/api/app/account/login" \
  -H "Content-Type: application/json" \
  -d '{"userName":"sandi@123.com","password":"123456"}'

# 标签列表第一页(10 条)
curl -G "http://192.168.31.88:19001/api/app/label" \
  -H "Authorization: Bearer {token}" \
  --data-urlencode "SkipCount=1" \
  --data-urlencode "MaxResultCount=10"

三、标签批量导入

基本信息

项目 内容
方法 POST
路径 /api/app/label/batch-create
鉴权 Bearer Token
对应页面 Web 端 Bulk Add LabelsLabelsList.tsxLabelBulkAddPage
单次上限 500 行

Body 顶层字段

字段 类型 必填 说明
templateCode string 所有行共用的模板编码
items array 导入行列表
saveTemplateProductDefaults bool 是否合并写入模板 ProductDefaults,默认 true

items[] 每行字段

标签基本字段(与单条 POST /api/app/label 一致)

字段 类型 必填 说明
labelName string 标签名称
labelCategoryId string 标签分类 Id
labelTypeId string 建议 标签类型 Id
productIds string[] 至少 1 个产品
locationIds string[] 建议 适用门店(主字段)
locationId string 兼容单门店,与 locationIds 合并
appliedRegionType string ALL / SPECIFIED
regionIds / groupIds string[] 条件 SPECIFIED 时传 Region
partnerId / partnerIds string / string[] Company 范围
labelCode string 不传则自动生成 LBL_{guid}
labelInfoJson object 标签级模板 JSON(通常走 ProductDefaults)
state bool 默认 true

模板数据字段(对应 Bulk Add 表格列)

字段 类型 说明
templateDefaultValues object 已组装的 elementId → 值;优先使用,不再从下方字段推导
templateDataValues object 文本类录入(如 Text、Barcode 手填值)
templateDateOffsets object 日期/时间/时长:{ "el-id": { "unit": "Days", "value": "3" } }
nutritionByElementId object 营养成分:{ "el-nutrition": { "calories": "120" } }

模板数据落库规则

  • saveTemplateProductDefaults=true 时:按 productId + labelTypeId 合并写入 fl_label_template_product_default(与前端 saveTemplateDefaultsAfterLabels 一致)
  • 日期偏移存为 JSON 字符串:{"unit":"Days","value":"3"}
  • Template 面板条码/二维码自动填充产品 codeValue;Label Name / Label Type 自动绑定行内 labelName、类型名

请求示例

{
  "templateCode": "tpl_229mx5_mr05n3cq",
  "saveTemplateProductDefaults": true,
  "items": [
    {
      "labelName": "Chicken Salad",
      "labelCategoryId": "3a2228ca-42fa-5273-1105-3d8252ffdd99",
      "labelTypeId": "3a2228e5-33c5-278e-a09f-47fd6e2ddbc7",
      "locationIds": ["3a222878-b4c1-d27b-d437-93da14886350"],
      "productIds": ["3a2228a8-6a51-6cc4-fee2-b77769766b33"],
      "appliedRegionType": "SPECIFIED",
      "regionIds": [],
      "templateDataValues": {
        "el-1782794752668-0gixa9y": "Fresh batch text",
        "el-1782794771519-4360c0p": "123456789"
      },
      "templateDateOffsets": {
        "el-1782794481721-sdf7mvy": { "unit": "Days", "value": "3" }
      },
      "state": true
    },
    {
      "labelName": "Turkey Wrap",
      "labelCategoryId": "3a2228ca-42fa-5273-1105-3d8252ffdd99",
      "labelTypeId": "3a2228e6-3ed0-b056-a08b-ea8b1eea46a0",
      "locationIds": ["3a222878-b4c1-d27b-d437-93da14886350"],
      "productIds": ["3a2228a8-6a51-6cc4-fee2-b77769766b33"],
      "templateDataValues": {
        "el-1782794752668-0gixa9y": "Ready to serve"
      },
      "templateDateOffsets": {
        "el-1782794481721-sdf7mvy": { "unit": "Days", "value": "5" }
      }
    }
  ]
}

响应示例

{
  "successCount": 2,
  "failCount": 0,
  "successItems": [
    { "rowNumber": 1, "labelCode": "LBL_abc...", "labelName": "Chicken Salad" },
    { "rowNumber": 2, "labelCode": "LBL_def...", "labelName": "Turkey Wrap" }
  ],
  "errors": []
}

部分成功示例(第 2 行校验失败、第 1 行仍创建):

{
  "successCount": 1,
  "failCount": 1,
  "successItems": [
    { "rowNumber": 1, "labelCode": "LBL_abc...", "labelName": "Chicken Salad" }
  ],
  "errors": [
    { "rowNumber": 2, "labelName": "", "message": "标签名称不能为空" }
  ]
}

批量导入 curl 示例

curl -X POST "http://192.168.31.88:19001/api/app/label/batch-create" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "templateCode": "tpl_229mx5_mr05n3cq",
    "saveTemplateProductDefaults": true,
    "items": [
      {
        "labelName": "Batch Test",
        "labelCategoryId": "3a2228ca-42fa-5273-1105-3d8252ffdd99",
        "labelTypeId": "3a2228e5-33c5-278e-a09f-47fd6e2ddbc7",
        "locationIds": ["3a222878-b4c1-d27b-d437-93da14886350"],
        "productIds": ["3a2228a8-6a51-6cc4-fee2-b77769766b33"],
        "templateDataValues": { "el-1782794752668-0gixa9y": "Fresh" },
        "templateDateOffsets": { "el-1782794481721-sdf7mvy": { "unit": "Days", "value": "3" } }
      }
    ]
  }'

四、与单条创建对比

能力 POST /api/app/label POST /api/app/label/batch-create
行数 1 条 最多 500 条
模板编码 每 Body 自带 顶层 templateCode 共用
模板数据 labelInfoJson 支持结构化模板字段 + ProductDefaults 合并
失败处理 整请求失败 行级错误收集,支持部分成功
返回值 标签详情 DTO successCount / failCount / errors / successItems

五、代码改动摘要

文件 改动
ILabelAppService.cs 新增 BatchCreateAsync
LabelAppService.cs 实现批量导入;逐行复用 CreateAsync;可选合并模板 ProductDefaults
LabelBatchCreateInputVo.cs 批量入参 DTO
LabelBatchCreateItemInputVo.cs 单行(基本字段 + 模板数据字段)
LabelBatchDateOffsetInputVo.cs 日期偏移单位+数值
LabelBatchCreateResultDto.cs 批量结果 DTO
LabelBatchTemplateDefaultsHelper.cs 组装/合并模板 ProductDefaults

六、部署与联调注意

  1. dotnet build 编译 FoodLabeling.ApplicationYi.Abp.Web重启 API 进程(未重启时 batch-create 会返回 405)
  2. 管理端登录:POST /api/app/account/login(非 /api/oauth/Login
  3. 本地 Base URL 以 appsettings.jsonApp:SelfUrl 为准(当前示例为 http://192.168.31.88:19001
  4. 前端 LabelsList.tsxsubmit() 仍循环调单条 createLabel;对接批量接口时需改为调用 batch-create

七、相关文档

  • 标签多门店 locationIds项目相关文档/6-23代码优化.md
  • 模板三维 scope:项目相关文档/6-4代码优化.md