美国版 · 批量导入 / 批量导出(Excel·PDF)/ 下载模板 / 批量编辑 — 接口汇总
本文档集中维护 Account Management、Reports 及相关模块的「下载 Excel 模板」「批量导出(Excel 或 PDF)」「批量导入 Excel」以及 网格「保存全部」式批量编辑(JSON) 等接口。单条 CRUD、分页列表仍以各业务模块说明为准(如门店见 门店(Location)接口对接说明.md)。
目录
| 章节 | 内容 |
|---|---|
| 公共约定 | 基址、鉴权、Swagger、通用注意事项 |
| 共享配置 | appsettings 中 FoodLabeling:BatchImport |
| 1 Location Manager(门店) | 下载模板 / Excel 导出 / 导入 / 批量编辑 |
| 2 Team Member(成员) | 下载模板 / PDF 全量导出 / Excel 导入 / 批量编辑 |
| 3 Products(菜单-产品) | 下载模板 / Excel 全量导出 / Excel 导入 / 批量编辑 |
| 4 后续模块(预留) | 新接口在此追加小节 |
| 5 Account Management(Company / Region) | PDF 全量导出(Company、Region 页签) |
| 6 Reports — Print Log(Excel) | Excel 全量导出(Print Log 页签) |
| 附录 curl 模板 | 登录、Location / Team Member / Products / Company / Region / Reports 调用示例 |
公共约定
- 宿主:美国版后端
Yi.Abp.Web;本地 Swagger 示例:http://localhost:19001/swagger。 - 路由前缀:约定式控制器
RootPath为api/app(与 ABP 实际配置一致)。 - Swagger 分组:「食品标签-美国版接口」;具体路径以 Swagger 展示为准(下表为常见命名,联调时请以 Swagger 为准)。
- 鉴权:与其它业务接口相同,请求头携带登录接口返回的
data.token完整值(已含Bearer前缀),示例:Authorization: {data.token}。 - 文件类响应:
Content-Type多为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(.xlsx)。 - 导入类请求:统一使用
multipart/form-data,文件字段名以各接口说明为准(Location 为file)。 - 批量编辑类请求:使用
application/json,一次提交多行(与前端表格「保存全部」对齐)。 - 导出类响应:Location 与 Products(菜单-产品)、Reports — Print Log 为 Excel 全量;Team Member、Account Management 的 Company / Region、Reports — Label Report 等为 PDF(见各小节);数据量极大时请注意服务端内存与响应耗时。
共享配置
配置节全名:FoodLabeling:BatchImport(绑定类:FoodLabelingBatchImportOptions,在 FoodLabelingApplicationModule 中注册)。
| 配置项 | 说明 |
|---|---|
TemplateDirectory |
服务器上存放批量导入模板的目录(生产示例:/www/wwwroot/FoodLabelingManagementUs/batchImportOfFiles) |
LocationTemplateFileName |
Location 模板文件名(默认:Location-Manager-批量导入模板.xlsx) |
TeamMemberTemplateFileName |
Team Member 模板文件名(默认:Team-Member-批量导入模板.xlsx) |
ProductTemplateFileName |
Product(菜单-产品)模板文件名(默认:Product-Manager-批量导入模板.xlsx) |
TeamMemberImportDefaultPassword |
Team Member 批量导入时,Excel 未填 Password 列则使用的默认初始密码 |
MaxImportRows |
单次导入最多数据行数(默认 5000) |
MaxUploadBytes |
上传 Excel 最大字节数(默认 10MB) |
MaxBulkUpdateItems |
单次「批量编辑」请求中 items 数组最大长度(默认 500;含占位空行,与前端网格行数一致) |
后续若增加其它模块模板文件名等,可在此表同一节下扩展配置项说明(并与 appsettings、Options 类保持一致)。
1 Location Manager(门店)
应用服务:LocationAppService(模块 food-labeling-us)。
列表筛选字段(导出与列表对齐时):Sorting、Keyword、Partner、GroupName、State — 含义与分页列表一致,详见 门店(Location)接口对接说明.md 接口 1。
1.1 下载批量导入模板
| 项目 | 说明 |
|---|---|
| 方法 | DownloadLocationImportTemplateAsync |
| HTTP | GET |
| 常见路径 | /api/app/location/download-location-import-template |
| 作用 | 从 TemplateDirectory 读取 LocationTemplateFileName 指向的文件并作为附件下载 |
| 失败常见原因 | 未配置目录、文件名、或服务器上文件不存在 |
1.2 批量导出 Excel
| 项目 | 说明 |
|---|---|
| 方法 | ExportLocationsExcelAsync |
| HTTP | GET |
| 常见路径 | /api/app/location/export-locations-excel |
| Query | 与门店列表筛选一致:Sorting、Keyword、Partner、GroupName、State |
| 数据范围 | 全量:符合筛选条件的全部记录;不使用请求中的 SkipCount / MaxResultCount(与列表分页无关) |
| 排序 | 与列表一致:有 Sorting 则按其排序,否则默认 CreationTime 降序 |
| 响应文件名示例 | locations-export-yyyyMMdd-HHmmss.xlsx |
1.3 批量导入 Excel
| 项目 | 说明 |
|---|---|
| 方法 | ImportLocationsBatchAsync |
| HTTP | POST |
| Content-Type | multipart/form-data |
| 常见路径 | /api/app/location/import-locations-batch |
| 表单字段 | file:仅支持 .xlsx |
| 返回类型 | LocationBatchImportResultDto(JSON) |
LocationBatchImportResultDto 字段
| 字段 | 说明 |
|---|---|
SuccessCount |
成功新增条数 |
FailCount |
失败条数(含解析错误与逐行业务校验失败) |
SkippedEmptyRows |
预留,当前一般为 0 |
Errors |
RowNumber、LocationCode、Message |
解析与业务摘要
- 表头须能识别 Location ID(或同义列);建议使用官方模板。
- 必填:Location ID(
LocationCode)、Location Name(与单条新增一致)。 - 可选:Company/Region、地址、电话、邮箱、经纬度、
Active等;经纬度为空则null,有值则校验格式。
1.4 批量编辑(网格「保存全部」)
对应前端在 Location Manager 进入批量编辑页后,将多行修改一次性提交;每行通过主键 id 定位记录,可编辑字段与单条 PUT /api/app/location/{id} 的 body(LocationUpdateInputVo)一致。不修改 Location ID(LocationCode)(与单条更新接口一致)。
| 项目 | 说明 |
|---|---|
| 方法 | UpdateLocationsBulkAsync |
| HTTP | PUT |
| Content-Type | application/json |
| 常见路径 | /api/app/location/locations-bulk(ABP 会去掉方法名中的 Update 前缀,不是 update-locations-bulk) |
| Body | LocationBulkUpdateInputVo |
请求体 LocationBulkUpdateInputVo
| 字段 | 类型 | 说明 |
|---|---|---|
items |
数组 | 每一元素为 LocationBulkUpdateItemVo |
LocationBulkUpdateItemVo(单行)
| 字段 | 说明 |
|---|---|
id |
Guid,列表接口返回的门店主键;为 00000000-0000-0000-0000-000000000000 或未填写的占位行将被忽略(便于与「至少 10 行空行」类 UI 对齐) |
partner |
可选,Company |
groupName |
可选,Region |
locationName |
必填(与单条更新校验一致) |
street / city / stateCode / country / zipCode / phone / email |
可选 |
latitude / longitude |
可选,decimal |
state |
是否启用,默认 true |
返回 LocationBulkUpdateResultDto
| 字段 | 说明 |
|---|---|
SuccessCount |
成功更新条数 |
FailCount |
失败条数 |
Errors |
LocationBulkUpdateErrorDto:rowNumber(在 items 数组中的序号,从 1 开始)、id、message |
行为说明
- 逐条提交:内部对每一有效行调用与单条更新相同的业务逻辑;一行失败不影响其它行。
- 整单校验:
items为空、超过MaxBulkUpdateItems、或没有任何有效id时返回 400 类业务错误(UserFriendlyException)。 - JSON 命名:与项目其它接口一致,一般为 camelCase(以实际 JSON 序列化配置为准)。
2 Team Member(成员)
应用服务:TeamMemberAppService(模块 food-labeling-us;前端常见路径前缀 /team-member)。
列表筛选字段(导出与列表对齐):Keyword、RoleId、LocationId、State、Sorting — 与成员分页列表一致(LocationId 为门店主键字符串,与 UserLocation.LocationId 一致)。
2.1 下载批量导入模板
| 项目 | 说明 |
|---|---|
| 方法 | DownloadTeamMemberImportTemplateAsync |
| HTTP | GET |
| 常见路径 | /api/app/team-member/download-team-member-import-template |
| 作用 | 从 TemplateDirectory 读取 TeamMemberTemplateFileName 指向的 xlsx 并下载 |
2.2 批量导出 PDF(全量)
| 项目 | 说明 |
|---|---|
| 方法 | ExportTeamMembersPdfAsync |
| HTTP | GET |
| 常见路径 | /api/app/team-member/export-team-members-pdf |
| Query | 与成员列表筛选一致:Keyword、RoleId、LocationId、State、Sorting |
| 数据范围 | 全量:符合筛选条件的全部成员;不使用 SkipCount / MaxResultCount |
| 排序 | 有 Sorting 则按其排序,否则按创建时间降序 |
| 响应 | Content-Type: application/pdf,文件名示例 team-members_yyyy-MM-dd_HH-mm-ss.pdf |
| PDF 列 | Name、Email、Phone、Role、Assigned Locations(多门店以分号拼接)、Status(Active/Inactive) |
说明:PDF 中「Assigned Locations」展示该成员全部已分配门店(不受列表按门店筛选时「仅显示命中门店」的收缩影响),便于导出后审阅完整权限。
2.3 批量导入 Excel
| 项目 | 说明 |
|---|---|
| 方法 | ImportTeamMembersBatchAsync |
| HTTP | POST |
| Content-Type | multipart/form-data |
| 常见路径 | /api/app/team-member/import-team-members-batch |
| 表单字段 | file,仅 .xlsx |
| 返回 | TeamMemberBatchImportResultDto:successCount、failCount、errors(rowNumber、userName、message) |
表头识别(摘要)
- 必填列:
Name(或 FullName)、Email;Role;Assigned Locations(至少一条)。 - 可选列:
UserName/Login(不填则登录账号用 Email)、Password(不填则用配置TeamMemberImportDefaultPassword)、Phone、Status。 - Assigned Locations:多个门店可用
;、|、换行、中文,分隔;支持33333 - Central Park Store(取-前为门店编码或 Guid)。 - Role:与系统
Role.RoleName一致(忽略大小写与中间空格);未匹配则该行失败。
内部对每行调用与单条创建相同的业务逻辑;单行失败不影响其它行。
2.4 批量编辑(网格「保存全部」)
| 项目 | 说明 |
|---|---|
| 方法 | UpdateTeamMembersBulkAsync |
| HTTP | PUT |
| Content-Type | application/json |
| 常见路径 | /api/app/team-member/team-members-bulk(勿写 update-team-members-bulk,否则易命中 PUT …/{id} 导致 Guid 校验错误) |
| Body | TeamMemberBulkUpdateInputVo:items 为 TeamMemberBulkUpdateItemVo 数组 |
每行含 id(成员 Guid) 及与单条 PUT /api/app/team-member/{id} 相同的字段(password 可空表示不改密码)。id 为全零 GUID 的项忽略。整单规则与 Location 批量编辑相同(MaxBulkUpdateItems、至少一条有效 id 等)。
返回 TeamMemberBulkUpdateResultDto:successCount、failCount、errors(rowNumber、id、message)。
3 Products(菜单-产品)
应用服务:ProductAppService(模块 food-labeling-us;前端常见路径前缀 /product)。
列表筛选字段(导出与列表对齐):Keyword、State、Sorting — 与产品分页列表一致(Keyword 匹配产品编码、名称、分类名称)。
路由说明:单条 GET/PUT/DELETE 的 {id} 为 Guid 类型(与 fl_product.Id 的 Guid 字符串一致),约定路由会带 {id:guid} 约束,因此 export-products-excel、download-product-import-template、import-products-batch、update-products-bulk 等字面路径不会被误判为产品 Id。
3.1 下载批量导入模板
| 项目 | 说明 |
|---|---|
| 方法 | DownloadProductImportTemplateAsync |
| HTTP | GET(已标 [HttpGet],与约定 Download* 可能判为 POST 的情况区分) |
| 常见路径 | /api/app/product/download-product-import-template |
| 作用 | 从 TemplateDirectory 读取 ProductTemplateFileName 指向的 xlsx 并下载(工作表名一般为 Products) |
3.2 批量导出 Excel(全量)
| 项目 | 说明 |
|---|---|
| 方法 | ExportProductsExcelAsync |
| HTTP | GET(应用服务方法上已标 [HttpGet];ABP 对 Export* 默认易判成 POST,用 GET 否则会 405) |
| 常见路径 | /api/app/product/export-products-excel |
| Postman | 不要 填 Body;筛选用 Params(Query)或拼在 URL 上;导出不需要上传 file(上传文件是 3.3 导入) |
| Query | 与产品列表筛选一致:Keyword、State、Sorting |
| 数据范围 | 全量:符合筛选条件的全部产品;不使用 SkipCount / MaxResultCount |
| 排序 | 有 Sorting 则按其排序,否则默认按 ProductName 降序 |
| 响应文件名示例 | products-export-yyyyMMdd-HHmmss.xlsx |
| 列(与导入模板一致) | Location(多门店英文逗号拼接门店名称)、Product Category(分类名称)、Product(产品名称)、Product Code(产品编码;可为空则导出为空单元格) |
部署:须使用 dotnet publish 后的完整输出目录(含 ClosedXML.dll、DocumentFormat.OpenXml.dll、Yi.Abp.Web.deps.json 等)部署;不要用 bin/Debug(或 bin/Release)里挑文件当上线包。也禁止「本地跑起来后只把若干 dll / 自己改过的文件」覆盖到线上(极易漏掉第三方依赖)。上线建议整包替换发布目录,或在服务器上 git pull + dotnet publish;发布时若输出里缺少 ClosedXML.dll,当前 Yi.Abp.Web 工程会在 dotnet publish 结束时报错提示。
3.3 批量导入 Excel
| 项目 | 说明 |
|---|---|
| 方法 | ImportProductsBatchAsync |
| HTTP | POST |
| Content-Type | multipart/form-data |
| 常见路径 | /api/app/product/import-products-batch |
| 表单字段 | file,仅 .xlsx |
| 返回 | ProductBatchImportResultDto:successCount、failCount、errors(rowNumber、productName、message) |
表头识别(摘要)
- 必填列:
Product Category(分类名称,与fl_product_category.CategoryName匹配,忽略大小写;若同名多条则该行失败)、Product(产品名称)。 - 可选列:
Location(多门店可用英文逗号,、中文逗号、分号、竖线、换行分隔;每个片段:若为 Guid 则按门店主键;否则按 Location Code 精确匹配,或按 Location Name 不区分大小写匹配;同一片段匹配到多条门店则该行失败)、Product Code(可空,空则创建时由后端生成唯一编码,与单条创建一致)。 - 不在模板中的字段:产品主键、启用状态由后端处理;导入创建的产品
state恒为true(启用);productImageUrl不通过本导入写入。
内部对每行调用与单条 POST 创建产品 相同的业务逻辑(含门店关联写入);单行失败不影响其它行。
3.4 批量编辑(网格「保存全部」)
| 项目 | 说明 |
|---|---|
| 方法 | UpdateProductsBulkAsync |
| HTTP | PUT |
| Content-Type | application/json |
| 常见路径 | /api/app/product/products-bulk |
| Body | ProductBulkUpdateInputVo:items 为 ProductBulkUpdateItemVo 数组 |
每行含 id(产品主键字符串,与列表/详情返回的 id 一致) 及与单条 PUT /api/app/product/{id} 相同的 body 字段(ProductUpdateInputVo / ProductCreateInputVo 形状:productCode、productName、categoryId、productImageUrl、state、locationIds)。id 为空或仅空白的项忽略。整单规则与 Location / Team Member 批量编辑相同(MaxBulkUpdateItems、至少一条有效 id 等)。
返回 ProductBulkUpdateResultDto:successCount、failCount、errors(rowNumber、id、message)。
4 后续模块(预留)
新模块的批量能力可在此追加 ## 7 xxx 等章节,并更新文首 目录 与 共享配置 表(本节为占位,章节号可按实际顺延)。
5 Account Management(Company / Region)
前端 Account Management 菜单中 Company、Region 两个页签的「Bulk Export (PDF)」对应后端已有接口:数据模型分别为 fl_partner(合作伙伴 / 公司)、fl_group(组织 / 大区);应用服务为 PartnerAppService、GroupAppService。导出为 QuestPDF 生成的 PDF,筛选条件与各自分页列表一致,不使用 SkipCount / MaxResultCount(全量导出)。单次导出超过 5000 条时返回业务错误,需缩小筛选范围。单条 GET/PUT/DELETE 的 {id} 为 Guid(与 fl_partner.Id / fl_group.Id 的 Guid 字符串一致),约定路由 {id:guid},export-pdf 等字面路径不会误判为资源 Id;ExportPdfAsync 已标 [HttpGet]。
5.1 Company(合作伙伴 / PartnerAppService)
| 项目 | 说明 |
|---|---|
| 方法 | ExportPdfAsync |
| HTTP | GET |
| 常见路径 | /api/app/partner/export-pdf |
| Query | 与 Company 列表一致:Keyword、State、Sorting |
| 数据范围 | 符合筛选条件的全部记录(全量) |
| 排序 | 与列表 GetListAsync 内 BuildPartnerListQuery 一致(含 Sorting 各分支;无则 CreationTime 降序) |
| 响应 | Content-Type: application/pdf,文件名示例 companies_yyyy-MM-dd_HH-mm-ss.pdf |
| PDF 列 | Company(公司名称)、Contact(邮箱)、Phone、Status(active/inactive)、Created |
5.2 Region(组织 / GroupAppService)
| 项目 | 说明 |
|---|---|
| 方法 | ExportPdfAsync |
| HTTP | GET |
| 常见路径 | /api/app/group/export-pdf |
| Query | 与 Region 列表一致:Keyword、PartnerId(下拉「所属公司」对应 fl_partner.Id)、State、Sorting |
| 数据范围 | 符合筛选条件的全部记录(全量) |
| 排序 | 与列表 GetListAsync 内 BuildGroupJoinedQuery 一致 |
| 响应 | Content-Type: application/pdf,文件名示例 regions_yyyy-MM-dd_HH-mm-ss.pdf |
| PDF 列 | Region Name、Parent company、Status(active/inactive)、Created |
说明:前端 partnerService.exportPartnersPdf / groupService.exportGroupsPdf 已按上述路径封装;鉴权与其它 GET 一致。
6 Reports — Print Log(Excel)
应用服务:ReportsAppService(模块 food-labeling-us)。前端 Reports 菜单 Print Log 页签的「Export Report」在实现上调用 Excel 全量导出(与列表同一套筛选;不使用分页参数参与数据范围,仅可选用 Sorting 与列表对齐)。
6.1 Print Log 批量导出 Excel
| 项目 | 说明 |
|---|---|
| 方法 | ExportPrintLogExcelAsync |
| HTTP | GET |
| 常见路径 | /api/app/reports/export-print-log-excel |
| Query | 与 Print Log 分页列表一致:PartnerId、GroupId、LocationId、StartDate、EndDate、Keyword、Sorting(不传 SkipCount / MaxResultCount 或传了也会被后端忽略;全量以筛选为准) |
| 数据范围 | 符合筛选条件的全部打印任务行(上限 5000 条;超出则 UserFriendlyException) |
| 排序 | 与列表一致:Sorting 为 PrintedAt asc 时按打印时间升序,否则按打印时间降序 |
| 响应 | Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,文件名示例 print-log_yyyyMMdd-HHmmss.xlsx |
Excel 列(工作表名 Print Log) |
Label ID、Product Name、Category、Template、Printed At、Printed By、Location、Expiry Date(空值语义与列表「无」一致) |
| 权限 | 与 GetPrintLogListAsync 相同:admin 可查全部;非 admin 仅导出本人打印记录 |
说明:同模块另有 GET .../export-print-log-pdf(PDF);Label Report 页签仍使用 export-label-report-pdf。前端 reportsService.exportPrintLogExcel 已封装本接口。
附录 curl 模板
将 TOKEN 替换为登录响应中的 data.token 整段;将 BASE 替换为实际基址(如 http://localhost:19001)。
# 登录
curl -X POST "$BASE/api/oauth/Login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "userName=admin&password=123456"
# --- Location Manager ---
curl -X GET "$BASE/api/app/location/download-location-import-template" \
-H "Authorization: TOKEN" \
-o "Location-Manager-template.xlsx"
curl -X GET "$BASE/api/app/location/export-locations-excel?Partner=&GroupName=&State=&Keyword=&Sorting=" \
-H "Authorization: TOKEN" \
-o "locations-export.xlsx"
curl -X POST "$BASE/api/app/location/import-locations-batch" \
-H "Authorization: TOKEN" \
-F "file=@./Location-Manager-template.xlsx"
curl -X PUT "$BASE/api/app/location/locations-bulk" \
-H "Authorization: TOKEN" \
-H "Content-Type: application/json" \
-d "{\"items\":[{\"id\":\"YOUR_LOCATION_ID\",\"locationName\":\"UNCC store\",\"state\":true}]}"
# --- Team Member ---
curl -X GET "$BASE/api/app/team-member/download-team-member-import-template" \
-H "Authorization: TOKEN" \
-o "Team-Member-template.xlsx"
curl -X GET "$BASE/api/app/team-member/export-team-members-pdf?Keyword=&RoleId=&LocationId=&State=&Sorting=" \
-H "Authorization: TOKEN" \
-o "team-members.pdf"
curl -X POST "$BASE/api/app/team-member/import-team-members-batch" \
-H "Authorization: TOKEN" \
-F "file=@./Team-Member-template.xlsx"
curl -X PUT "$BASE/api/app/team-member/team-members-bulk" \
-H "Authorization: TOKEN" \
-H "Content-Type: application/json" \
-d "{\"items\":[{\"id\":\"YOUR_USER_GUID\",\"fullName\":\"John\",\"userName\":\"john@example.com\",\"email\":\"john@example.com\",\"phone\":789654444,\"roleId\":\"ROLE_GUID\",\"locationIds\":[\"LOCATION_GUID\"],\"state\":true}]}"
# --- Account Management:Company / Region(PDF 全量)---
curl -X GET "$BASE/api/app/partner/export-pdf?Keyword=&State=&Sorting=" \
-H "Authorization: TOKEN" \
-o "companies-export.pdf"
curl -X GET "$BASE/api/app/group/export-pdf?Keyword=&PartnerId=&State=&Sorting=" \
-H "Authorization: TOKEN" \
-o "regions-export.pdf"
# --- Reports:Print Log(Excel 全量)---
curl -X GET "$BASE/api/app/reports/export-print-log-excel?PartnerId=&GroupId=&LocationId=&StartDate=&EndDate=&Keyword=&Sorting=PrintedAt%20desc" \
-H "Authorization: TOKEN" \
-o "print-log-export.xlsx"
# --- Products(菜单-产品)---
curl -X GET "$BASE/api/app/product/download-product-import-template" \
-H "Authorization: TOKEN" \
-o "Product-Manager-template.xlsx"
curl -X GET "$BASE/api/app/product/export-products-excel?Keyword=&State=&Sorting=" \
-H "Authorization: TOKEN" \
-o "products-export.xlsx"
curl -X POST "$BASE/api/app/product/import-products-batch" \
-H "Authorization: TOKEN" \
-F "file=@./Product-Manager-template.xlsx"
curl -X PUT "$BASE/api/app/product/products-bulk" \
-H "Authorization: TOKEN" \
-H "Content-Type: application/json" \
-d "{\"items\":[{\"id\":\"YOUR_PRODUCT_ID\",\"productName\":\"Tuna & Bacon Sub\",\"categoryId\":\"CATEGORY_ID\",\"productCode\":\"40001\",\"state\":true,\"locationIds\":[\"LOCATION_GUID_1\",\"LOCATION_GUID_2\"]}]}"
更完整的接口测试流程见仓库内 .codex/skills/api-interface-testing/SKILL.md。
文档维护说明
- 新增某模块的导入/导出/下载模板/批量编辑接口时:在本文件 目录 表增加一行锚点,新增 ## n 模块名 章节,并同步 共享配置 表(若有新配置项)。
- 避免在多个 Markdown 中重复粘贴大段相同表格;门店分页与单条接口仍以
门店(Location)接口对接说明.md为准;本文侧重「批量」与「多行一次提交」类接口。