Blame view

项目相关文档/6-17代码优化.md 11.1 KB
14afbc16   李曜臣   2026-6-22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
  # 6-17 代码优化
  
  本文档说明 **2026-06-17** 对美国版的两项后端改造:
  
  1. **`GET /api/app/label-template`** 列表 500 修复(scope 库结构兼容)
  2. **`POST /api/app/us-app-labeling/get-print-log-list`** 增加 **按自然日** 的打印时间筛选
  
  测试环境:`http://flus-test.3ffoodsafety.com`
  
  ---
  
  ## 一、label-template 列表修复
  
  Web 管理端 **Label Templates** 页加载失败,Network 中:
  
  `GET /api/app/label-template?SkipCount=1&MaxResultCount=10` 返回错误,页面提示 **Failed to load label templates**
  
  ### 根因
  
  6-4 改造引入 **Company / Region / Location** 三维适用范围后,代码会:
  
  1. 查询 `fl_label_template.AppliedPartnerType` / `AppliedRegionType`
  2. 关联 `fl_label_template_partner` / `fl_label_template_region`
  
  测试库若**尚未执行**迁移脚本 `fl_label_template_scope.sql`,上述列/表不存在,SqlSugar 生成 SQL 时报 **Unknown column / Table doesn't exist**,接口 500。
  
  > `SkipCount=1` 表示**第 1 页**(页码从 1 起),不是报错原因。
  
  ---
  
  ### 修复说明
  
  #### 1. 库结构兼容(未迁移仍可列表)
  
  | 改动 | 说明 |
  |------|------|
  | `LabelTemplateScopeSchemaHelper` | 启动后首次请求检测 partner/region 关联表是否存在 |
  | `FlLabelTemplateDbEntity` | `AppliedPartnerType` / `AppliedRegionType` 标记 `IsIgnore`,避免 SELECT 不存在列 |
  | `LabelTemplateScopeHelper` | 未迁移时列表/详情 **仅 Location 维度** 过滤与展示;Company/Region 显示 `All Companies` / `All Regions` |
  | 已迁移库 | 行为与 6-4 一致,按关联表判断 ALL/SPECIFIED |
  
  #### 2. 列表筛选补全
  
  `LabelTemplateGetListInputVo` 增加 **`partnerId`**(Company),与 `groupId`、`locationId` 按「门店优先」解析(`ResolveFilteredLocationIdsForListAsync`)。
  
  #### 3. Items 列
  
  `LabelTemplateListItemsHelper` 补全 `ElementKey` 查询字段,控件名称排序稳定。
  
  ---
  
  ### 接口说明(label-template)
  
  | 项目 | 内容 |
  |------|------|
  | 方法 | `GET` |
  | 路径 | `/api/app/label-template` |
  | 鉴权 | Bearer Token |
  
  ### 入参(Query)
  
  | 参数 | 类型 | 必填 | 说明 |
  |------|------|------|------|
  | `SkipCount` | int | 否 | **页码,从 1 起**;第一页传 `1`(与全平台列表约定一致) |
  | `MaxResultCount` | int | 否 | 每页条数,默认 10 |
  | `Keyword` | string | 否 | 模板名称 / 编码模糊搜索 |
  | `PartnerId` | string | 否 | 按 Company(`fl_partner.Id`)筛选 |
  | `GroupId` | string | 否 | 按 Region(`fl_group.Id`)筛选 |
  | `LocationId` | string | 否 | 按门店(`location.Id`)筛选;**优先于** Partner/Region |
  | `LabelType` | string | 否 | 如 `PRICE` / `NUTRITION` |
  | `State` | bool | 否 | 启用状态 |
  | `Sorting` | string | 否 | 排序字段 |
  
  筛选解析顺序:**LocationId → GroupId → PartnerId**;均未传则不按门店范围收窄(仍受登录账号数据权限约束)。
  
  ### 出参(`PagedResultWithPageDto<LabelTemplateGetListOutputDto>`)
  
  | 字段 | 说明 |
  |------|------|
  | `pageIndex` | 当前页码 |
  | `pageSize` | 每页条数 |
  | `totalCount` | 总条数 |
  | `totalPages` | 总页数 |
  | `items[]` | 模板列表 |
  
  **`items[]` 主要字段**
  
  | 字段 | 说明 |
  |------|------|
  | `id` / `templateCode` | 模板编码(前端主键) |
  | `templateName` | 模板名称 |
  | `company` / `region` / `location` | 三维适用范围展示文案 |
  | `partnerIds` / `regionIds` / `locationIds` | 对应 Id 数组(ALL 时为空) |
  | `items` / `itemNames` | 模板内控件名称(逗号拼接 / 数组) |
  | `contentsCount` | 控件数量 |
  | `sizeText` | 如 `4x2inch` |
  | `lastEdited` | 最近编辑时间 |
  
  ---
  
  ### 请求示例(label-template)
  
  ```bash
  curl -G "http://flus-test.3ffoodsafety.com/api/app/label-template" \
    -H "Authorization: Bearer {token}" \
    --data-urlencode "SkipCount=1" \
    --data-urlencode "MaxResultCount=10"
  ```
  
  带筛选:
  
  ```bash
  curl -G "http://flus-test.3ffoodsafety.com/api/app/label-template" \
    -H "Authorization: Bearer {token}" \
    --data-urlencode "SkipCount=1" \
    --data-urlencode "MaxResultCount=10" \
    --data-urlencode "PartnerId=1234567890123456789" \
    --data-urlencode "Keyword=Price"
  ```
  
  ### 响应片段(示例)
  
  ```json
  {
    "pageIndex": 1,
    "pageSize": 10,
    "totalCount": 2,
    "totalPages": 1,
    "items": [
      {
        "id": "TPL-PRICE-01",
        "templateCode": "TPL-PRICE-01",
        "templateName": "Standard Price Label",
        "company": "All Companies",
        "region": "All Regions",
        "location": "All Locations",
        "items": "Label Name, Price, Barcode",
        "itemNames": ["Label Name", "Price", "Barcode"],
        "contentsCount": 3,
        "sizeText": "2x2inch",
        "lastEdited": "2026-06-04T10:00:00"
      }
    ]
  }
  ```
  
  ---
  
  ## 数据库迁移(启用完整三维 scope)
  
  未执行前:列表可正常返回,但 **无法** 保存 Company/Region 多选明细。
  
  **脚本(可重复执行)**
  
  `美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/scripts/fl_label_template_scope.sql`
  
  | 对象 | 说明 |
  |------|------|
  | `fl_label_template.AppliedPartnerType` | Company:ALL / SPECIFIED |
  | `fl_label_template.AppliedRegionType` | Region:ALL / SPECIFIED |
  | `fl_label_template_partner` | Company 多选明细 |
  | `fl_label_template_region` | Region 多选明细 |
  
  执行后重启应用,新建/编辑模板即可写入 Company/Region 范围。
  
  ### SQL 检查是否已迁移
  
  ```sql
  SELECT COLUMN_NAME
  FROM information_schema.COLUMNS
  WHERE TABLE_SCHEMA = DATABASE()
    AND TABLE_NAME = 'fl_label_template'
    AND COLUMN_NAME IN ('AppliedPartnerType', 'AppliedRegionType');
  
  SELECT TABLE_NAME
  FROM information_schema.TABLES
  WHERE TABLE_SCHEMA = DATABASE()
    AND TABLE_NAME IN ('fl_label_template_partner', 'fl_label_template_region');
  ```
  
  ---
  
  ### 涉及代码(label-template)
  
  | 文件 | 说明 |
  |------|------|
  | `Helpers/LabelTemplateScopeSchemaHelper.cs` | 检测 scope 表是否已迁移 |
  | `Helpers/LabelTemplateScopeHelper.cs` | 兼容未迁移库的过滤/展示/保存 |
  | `Helpers/LabelTemplateListItemsHelper.cs` | Items 列 ElementKey |
  | `Services/DbModels/FlLabelTemplateDbEntity.cs` | Partner/Region 列 IsIgnore |
  | `Services/LabelTemplateAppService.cs` | 列表筛选支持 `partnerId` |
  | `Dtos/LabelTemplate/LabelTemplateGetListInputVo.cs` | 新增 `PartnerId` |
  | `IServices/ILabelTemplateAppService.cs` | 接口注释 |
  
  ### 验证步骤(label-template)
  
  1. **未迁移库**:仅执行后端部署,调用 `GET /api/app/label-template?SkipCount=1&MaxResultCount=10`**200**,Web 列表可加载。
  2. **已迁移库**:列表 `company`/`region` 展示与 6-4 一致;指定 Company 保存后再查列表 Id 数组正确。
  3. 分页:第 1 页 `SkipCount=1`,第 2 页 `SkipCount=2`,`totalCount` 与 UI 分页一致。
  4. 筛选:传 `LocationId` 后仅返回该门店可见模板 + 全范围模板。
  
  ---
  
  ## 二、App Print Log 按日筛选(get-print-log-list)
  
  ### 背景
  
  App **Print Log** 页增加 **Date** 选择器(及 **Today** 快捷按钮),需按所选自然日只展示该门店当日的打印记录;无记录时提示如 `No print records for 06/16/2026`
  
  改造前接口仅按门店 + 权限分页,**无日期条件**,无法与 UI 日期筛选对齐。
  
  ### 接口说明
  
  | 项目 | 内容 |
  |------|------|
  | 方法 | `POST` |
  | 路径 | `/api/app/us-app-labeling/get-print-log-list` |
  | 鉴权 | App Bearer Token |
  
  ### 入参(Body:`PrintLogGetListInputVo`)
  
  | 字段 | 类型 | 必填 | 说明 |
  |------|------|------|------|
  | `locationId` | string | 是 | 当前门店 Id(`location.Id`) |
  | **`printDate`** | DateTime | 否 | **打印日期(自然日)**;按 `PrintedAt ?? CreationTime` 落在该日的任务筛选 |
  | `skipCount` | int | 否 | 页码,从 **1** 起 |
  | `maxResultCount` | int | 否 | 每页条数 |
  
  #### `printDate` 规则
  
  1. **未传** → 默认 **服务器当天**(与 App 默认选中 Today 一致)。
  2. **传入任意时刻** → 仅取 **日期部分**`Date`),区间为 `[当天 00:00:00, 次日 00:00:00)`
  3. 有效时间字段:`fl_label_print_task.PrintedAt` 优先,为空则用 `CreationTime`(与 Label ID 序号、`6-2` / `6-11` 一致)。
  4. 权限不变:管理员 / Partner 看门店全部;其它角色仅本人(`CreatedBy`)。
  
  ### 出参
  
  仍为 `PagedResultWithPageDto<PrintLogItemDto>`;`items[]` 字段不变。`totalCount`**该日**符合条件的总数。
  
  | 字段 | 说明 |
  |------|------|
  | `labelId` | 门店当日打印序号 `yyyyMMdd-n`(与 preview / 报表一致) |
  | `printedAt` | 打印时间 |
  | 其它 | 与改造前一致 |
  
  ### 请求示例
  
  **查询当天(显式传 printDate)**
  
  ```bash
  curl -X POST "http://flus-test.3ffoodsafety.com/api/app/us-app-labeling/get-print-log-list" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{
      "locationId": "550e8400-e29b-41d4-a716-446655440000",
      "printDate": "2026-06-16T00:00:00",
      "skipCount": 1,
      "maxResultCount": 20
    }'
  ```
  
  **Today 按钮(不传 printDate,后端默认当天)**
  
  ```json
  {
    "locationId": "550e8400-e29b-41d4-a716-446655440000",
    "skipCount": 1,
    "maxResultCount": 20
  }
  ```
  
  ### 响应片段(示例)
  
  ```json
  {
    "pageIndex": 1,
    "pageSize": 20,
    "totalCount": 2,
    "totalPages": 1,
    "items": [
      {
        "taskId": "1234567890123456789",
        "labelId": "20260616-1",
        "productName": "Organic Milk",
        "printedAt": "2026-06-16T09:15:00",
        "operatorName": "Alice",
        "locationName": "Ordos Airport"
      },
      {
        "taskId": "1234567890123456788",
        "labelId": "20260616-2",
        "printedAt": "2026-06-16T14:30:00"
      }
    ]
  }
  ```
  
  `totalCount = 0`,App 可展示 `No print records for MM/DD/YYYY`
  
  ### 涉及代码(get-print-log-list)
  
  | 文件 | 说明 |
  |------|------|
  | `Dtos/UsAppLabeling/PrintLogGetListInputVo.cs` | 新增 `PrintDate` |
  | `Services/UsAppLabelingAppService.cs` | `GetPrintLogListAsync` 增加日期 Where |
  | `Helpers/ReportsPrintLogDailyLabelIdHelper.cs` | 新增 `ResolvePrintLogFilterDayRange` |
  | `IServices/IUsAppLabelingAppService.cs` | 接口注释 |
  
  ### 验证步骤(get-print-log-list)
  
  1. 门店在 `2026-06-16` 有 N 条打印任务,传 `printDate=2026-06-16` → `totalCount=N`,且每条 `printedAt` 落在该日。
  2.`printDate=2026-06-15` 且无记录 → `totalCount=0`,`items=[]`
  3. 不传 `printDate` → 等价于查询**服务器当天**
  4. 同一 `printDate` 下 `labelId` 序号与 `6-2` 规则一致(`-1`、`-2` … 按当日时间升序)。
  
  #### SQL 抽查
  
  ```sql
  SELECT Id, LocationId, PrintedAt, CreationTime
  FROM fl_label_print_task
  WHERE LocationId = '{locationId}'
    AND IFNULL(PrintedAt, CreationTime) >= '2026-06-16'
    AND IFNULL(PrintedAt, CreationTime) < '2026-06-17'
  ORDER BY IFNULL(PrintedAt, CreationTime), Id;
  ```
  
  行数应与接口 `totalCount`(该日、该门店、权限范围内)一致。
  
  ---
  
  ## 关联文档
  
  - 三维 scope 业务规则:`项目相关文档/6-4代码优化.md`
  - App Print Log Label ID:`项目相关文档/6-2代码优化.md`
  - Preview 当日序号:`项目相关文档/6-11代码优化.md`
  - 分页约定(SkipCount = 页码):`Helpers/PagedQueryConvention.cs`