Blame view

项目相关文档/6-26代码优化.md 6.26 KB
7083cd6d   李曜臣   优化代码
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
  # 6-26 代码优化
  
  本文档说明 **2026-06-26** 对美国版标签模板 `contents` 字段的**数据来源澄清****编辑不生效**修复。
  
  ---
  
  ## 一、问题现象
  
  | 项目 | 说明 |
  |------|------|
  | 接口 | `GET/PUT /api/app/label-template/{id}`(如 `tpl_c23gov_mqri4g5a`) |
  | 期望 | `contents` = `"Nutrition Facts, Text (For Template)"`(模板列表 Contents 列展示) |
  | 实际 | 返回/展示 `"nutritionfacts, text"` |
  | 用户反馈 | 在编辑器修改 Element name 后保存,列表 Contents **没有变化** |
  
  ---
  
  ## 二、`contents` 取自哪个字段?
  
  ### 结论(优先级)
  
  | 优先级 | 来源 | 字段 | 说明 |
  |--------|------|------|------|
  | 1 | 编辑器右侧 **Element name** | `elements[].elementName` | 用户可编辑;保存时写入 `fl_label_template_element.ElementName` |
  | 2 | 旧数据兼容(slug) | `elements[].typeAdd` | 当 `elementName` 为旧 slug(如 `nutritionfacts`、`text`)时,按 typeAdd 推导展示名 |
  | 3 | 持久化缓存 | `fl_label_template.Contents` | 保存时写入;**列表以 element 实时汇总为准**,避免旧缓存覆盖新编辑 |
  
  ### typeAdd 推导规则
  
  `typeAdd` 形如 `{分组前缀}_{面板控件英文名}`
  
  | typeAdd 示例 | 推导展示名 |
  |--------------|------------|
  | `label_Nutrition Facts` | `Nutrition Facts (For Label)` |
  | `template_Text` | `Text (For Template)` |
  | `auto_Company` | `Company (Entered Automatically)` |
  | `print_Multiple Options` | `Multiple Options (Entered When Printing)` |
  
  **拼接格式**`{控件面板名称} ({分组标题})`  
  分组标题与左侧 Elements 面板一致:`For Template` / `For Label` / `Entered Automatically` / `Entered When Printing`
  
  ### 与 elementName 的关系
  
  | 场景 | elementName 示例 | contents 单项 |
  |------|------------------|---------------|
  | 新拖入控件(修复后) | `Text (For Template)` | `Text (For Template)` |
  | 旧模板 slug | `text` | `Text (For Template)`(由 typeAdd 推导) |
  | 用户手动改 Element name | `My Custom Field` | `My Custom Field`(以用户输入为准) |
  
  **注意**`elementName` 同时用于录入表表头;`contents` 是各控件展示名的逗号拼接,**不是** slug 字段。
  
  ---
  
  ## 三、根因说明
  
  1. **新建控件时** `allocateElementName` 把 Element name 默认成 slug(`nutritionfacts`),与 UI 期望的「Nutrition Facts (For Label)」不一致。  
  2. **列表 contents** 曾优先读 `fl_label_template.Contents` 缓存,保存后 element 已变但缓存仍是旧 slug 串。  
  3. **列表回退逻辑** 直接读 `ElementName` 原文,slug 原样展示为 `nutritionfacts, text`
  
  ---
  
  ## 四、修复内容
  
  ### 后端
  
  | 文件 | 改动 |
  |------|------|
  | `LabelTemplateContentsHelper.cs` | `ResolveElementContentsLabel`:Element name 优先;slug 则 typeAdd 推导 |
  | `LabelTemplateContentsHelper.cs` | `ResolveContentsMapFromElementsAsync`:列表按 element 表**实时**汇总 |
  | `LabelTemplateListItemsHelper.cs` | `items` / `itemNames` 与 contents 使用同一套展示名逻辑 |
  | `LabelTemplateAppService.cs` | 列表/详情 **优先** element 汇总 contents;保存仍写入 `Contents` 列(若已迁移) |
  
  ### 前端
  
  | 文件 | 改动 |
  |------|------|
  | `labelTemplate.ts` | 新增 `allocateElementDisplayName`、`resolveElementContentsLabel`、`deriveContentsLabelFromTypeAdd` |
  | `LabelTemplateEditor/index.tsx` | 新控件默认 Element name = `控件名 (For Template/For Label…)` |
  | `LabelTemplateEditor/index.tsx` | 保存时 `contents: buildTemplateContentsFromElements(elements)` |
  
  ---
  
  ## 五、接口说明
  
  ### 1. 模板详情
  
  | 项目 | 内容 |
  |------|------|
  | 方法 | `GET` |
  | 路径 | `/api/app/label-template/{id}` |
  | 示例 | `/api/app/label-template/tpl_c23gov_mqri4g5a` |
  
  **出参(节选)**
  
  ```json
  {
    "id": "tpl_c23gov_mqri4g5a",
    "templateName": "Unnamed template",
    "contents": "Nutrition Facts (For Label), Text (For Template)",
    "elements": [
      {
        "elementName": "nutritionfacts",
        "typeAdd": "label_Nutrition Facts",
        "type": "NUTRITIONFACTS"
      },
      {
        "elementName": "text",
        "typeAdd": "template_Text",
        "type": "TEXT_STATIC"
      }
    ]
  }
  ```
  
  > 旧 slug 的 `elementName` 可保留;`contents` 按 typeAdd 展示。保存后新模板会直接写入展示型 Element name。
  
  ### 2. 模板列表
  
  | 项目 | 内容 |
  |------|------|
  | 方法 | `GET` |
  | 路径 | `/api/app/label-template` |
  | 参数 | `SkipCount=1&MaxResultCount=10` |
  
  **出参 `items[]`**
  
  | 字段 | 说明 |
  |------|------|
  | `contents` | Contents 列文案,与详情一致 |
  | `items` | 兼容字段,与 `contents` 相同 |
  | `contentsCount` | 控件数量 |
  
  ### 3. 新建 / 编辑
  
  | 方法 | 路径 |
  |------|------|
  | `POST` | `/api/app/label-template` |
  | `PUT` | `/api/app/label-template/{id}` |
  
  **Body 节选**
  
  ```json
  {
    "id": "tpl_c23gov_mqri4g5a",
    "name": "Unnamed template",
    "contents": "Nutrition Facts (For Label), Text (For Template)",
    "elements": [
      {
        "id": "el_1",
        "elementName": "Nutrition Facts (For Label)",
        "typeAdd": "label_Nutrition Facts",
        "type": "NUTRITIONFACTS",
        "orderNum": 1
      },
      {
        "id": "el_2",
        "elementName": "Text (For Template)",
        "typeAdd": "template_Text",
        "type": "TEXT_STATIC",
        "orderNum": 2
      }
    ]
  }
  ```
  
  | 字段 | 说明 |
  |------|------|
  | `contents` | 可选;不传则后端按 `elements` 推导 |
  | `elements[].elementName` | **主数据源**(Element name) |
  | `elements[].typeAdd` | slug 兼容推导用 |
  
  ---
  
  ## 六、部署与验证
  
  1. 重新编译并重启 `Yi.Abp.Web`  
  2. (可选)执行 `scripts/fl_label_template_contents.sql` 持久化 `Contents`
  3. 打开 `tpl_c23gov_mqri4g5a` 保存一次 → GET 详情/列表 `contents` 应为展示名,而非 `nutritionfacts, text`  
  4. 修改 Element name 后再保存 → 列表 Contents **立即**更新(不再被旧 `Contents` 缓存挡住)
  
  **curl 示例**
  
  ```bash
  curl -s "http://localhost:5000/api/app/label-template/tpl_c23gov_mqri4g5a" \
    -H "Authorization: Bearer <TOKEN>"
  ```
  
  ---
  
  ## 七、与 6-25 文档关系
  
  - **6-25**:引入 `contents` 字段、DB 迁移、未迁移列兼容  
  - **6-26**:明确字段来源(Element name + typeAdd 推导)、修复 slug/缓存导致的展示与编辑不生效问题