8e0c49eb
李曜臣
产品标签类别优化;
|
1
2
3
4
5
6
7
8
9
|
# 本次接口变更汇总(标签 / 产品类别 / 模板组件 / App 树 / Web 会话)
> 说明:本文只汇总本次迭代中相关内容:
> - 标签模块 Label Categories:对齐“新增类别”原型图(`buttonAppearance` + `categoryPhotoUrl` / 展示文案 / 门店范围)
> - 产品模块 Categories:对齐“新增产品类别”原型图(同上)
> - 模板组件(`fl_label_template_element`):新增字段 `TypeAdd`(并补齐 `ElementName`)
> - App `labeling-tree`:L1 标签分类返回 `buttonAppearance`
> - Web 管理端 `auth-session`:**当前用户菜单与权限**、**退出登录**(食品标签-美国版模块)
> - Web `rbac-menu` 列表/详情:补充返回 `routerName`、`router`
|
c2e3194d
李曜臣
登陆优化;产品-门店绑定优化
|
10
|
> - 产品 **Products**:`POST/PUT /api/app/product` 支持可选 Body 字段 **`locationIds`**(多门店批量绑定 / 编辑时整表替换关联),详见 `项目相关文档/标签模块接口对接说明.md` **§6**
|
8e0c49eb
李曜臣
产品标签类别优化;
|
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
|
>
> 其余标签打印相关接口不在本文范围内。
---
## 1. 模板组件字段(`fl_label_template_element`)
### 1.1 字段变更
- 新增字段:`TypeAdd`(元素附加类型,如 `label_Duration`)
- 新增字段:`ElementName`(元素名称,用于更稳定的显示/快照)
### 1.2 接口影响范围
- 模板新增/编辑:保存 `elements[].typeAdd` / `elements[].elementName`
- 模板详情/预览:返回 `elements[].typeAdd` / `elements[].elementName`
### 1.3 JSON 对齐(elements[])
| 前端字段 | 后端字段 | 说明 |
|---|---|---|
| `type` | `ElementType` | 元素类型 |
| `typeAdd` | `TypeAdd` | 元素附加类型 |
| `elementName` | `ElementName` | 元素名称 |
---
## 2. 产品模块 Categories(Products → Categories)
> 数据库侧你已完成:`fl_product_category` 新字段、`fl_product_category_location` 新表。
### 2.1 表结构要点
- `fl_product_category`(主表)关键字段:
- `DisplayText`:按钮展示文案(为空可回退 `CategoryName`)
|
ecb291fd
李曜臣
门店支持优化;标签,产品组件优化
|
46
47
|
- `ButtonAppearance`:**JSON 格式字符串**落库(如 `["TEXT","COLOR"]`、`["IMAGE"]`);兼容历史单行 `TEXT`/`COLOR`/`IMAGE`(保存时规范为 JSON 数组)
- `CategoryPhotoUrl`:**JSON 格式字符串**落库(展示数据由前端解析);非 JSON 纯文本(色值、URL 等)保存时会被后端包成 JSON 字符串
|
8e0c49eb
李曜臣
产品标签类别优化;
|
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
|
- **已删除列**(需在库上执行 `DROP COLUMN`):`ButtonTextColor`、`ButtonBgColor`、`ButtonImageUrl`、`ButtonStyleJson`
- `AvailabilityType`:`ALL/SPECIFIED`(门店可用范围)
- `fl_product_category_location`(关联表):
- `(CategoryId, LocationId)` 唯一约束;用于 `AvailabilityType=SPECIFIED` 指定门店
### 2.2 CRUD 接口(字段扩展)
接口路径不变,仅扩展字段。
#### 2.2.1 列表
- **方法**:`GET`
- **路径**:`/api/app/product-category`
- **列表行新增返回**:
- `displayText`
- `buttonAppearance`
- `categoryPhotoUrl`
- `availabilityType`
#### 2.2.2 详情
- **方法**:`GET`
- **路径**:`/api/app/product-category/{id}`
- **新增返回字段**:
- `displayText`
|
ecb291fd
李曜臣
门店支持优化;标签,产品组件优化
|
73
|
- `buttonAppearance`、`categoryPhotoUrl`(**JSON 格式字符串**,展示语义由前端解析)
|
8e0c49eb
李曜臣
产品标签类别优化;
|
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
|
- `availabilityType`
- `locationIds`(当 `availabilityType=SPECIFIED` 返回门店 Id 列表,否则为空数组)
#### 2.2.3 新增
- **方法**:`POST`
- **路径**:`/api/app/product-category`
- **新增入参字段**:
- `displayText`
- `buttonAppearance`、`categoryPhotoUrl`
- `availabilityType`
- `locationIds`(当 `availabilityType=SPECIFIED` 必填且至少 1 个)
#### 2.2.4 编辑
- **方法**:`PUT`
- **路径**:`/api/app/product-category/{id}`
- **入参同新增**
#### 2.2.5 删除
- **方法**:`DELETE`
- **路径**:`/api/app/product-category/{id}`
- **说明**:逻辑删除;若被产品引用会阻止删除(保持原行为)
### 2.3 后端校验规则(本次新增)
- `availabilityType` 仅允许 `ALL/SPECIFIED`
- `SPECIFIED` 时 `locationIds` 至少 1 个
|
ecb291fd
李曜臣
门店支持优化;标签,产品组件优化
|
103
|
- `buttonAppearance`:须为 **合法 JSON**(任意对象/数组),或为兼容的 **`TEXT`/`COLOR`/`IMAGE` 单行**;其它字符串拒绝。`categoryPhotoUrl` 非空且非 JSON 时后端会序列化为 JSON 字符串存储;是否必填由业务/前端约定
|
8e0c49eb
李曜臣
产品标签类别优化;
|
104
105
106
107
108
109
110
111
112
113
114
|
---
## 3. 标签模块 Label Categories(Labels → Label Categories)
> 数据库侧新增:`fl_label_category` 新字段、`fl_label_category_location` 新表。
### 3.1 表结构要点
- `fl_label_category`(主表)关键字段:
- `DisplayText`:按钮展示文案(为空可回退 `CategoryName`)
|
ecb291fd
李曜臣
门店支持优化;标签,产品组件优化
|
115
116
|
- `ButtonAppearance`:**JSON 格式字符串**落库(如 `["TEXT","COLOR"]`、`["IMAGE"]`);兼容历史单行 `TEXT`/`COLOR`/`IMAGE`(保存时规范为 JSON 数组)
- `CategoryPhotoUrl`:**JSON 格式字符串**落库(展示数据由前端解析);非 JSON 纯文本(色值、URL 等)保存时会被后端包成 JSON 字符串
|
8e0c49eb
李曜臣
产品标签类别优化;
|
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
|
- **已删除列**(需在库上执行 `DROP COLUMN`):`ButtonTextColor`、`ButtonBgColor`、`ButtonImageUrl`、`ButtonStyleJson`
- `AvailabilityType`:`ALL/SPECIFIED`(门店可用范围)
- `fl_label_category_location`(关联表):
- `(CategoryId, LocationId)` 唯一约束;用于 `AvailabilityType=SPECIFIED` 指定门店(`LocationId` 对应 `location` 表主键)
### 3.2 CRUD 接口(字段扩展)
接口路径不变,仅扩展字段。
#### 3.2.1 列表
- **方法**:`GET`
- **路径**:`/api/app/label-category`
- **列表行新增返回**:
- `displayText`
- `buttonAppearance`
- `categoryPhotoUrl`
- `availabilityType`
#### 3.2.2 详情
- **方法**:`GET`
- **路径**:`/api/app/label-category/{id}`
- **新增返回字段**:
- `displayText`
|
ecb291fd
李曜臣
门店支持优化;标签,产品组件优化
|
142
|
- `buttonAppearance`、`categoryPhotoUrl`(**JSON 格式字符串**,展示语义由前端解析)
|
8e0c49eb
李曜臣
产品标签类别优化;
|
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
|
- `availabilityType`
- `locationIds`(当 `availabilityType=SPECIFIED` 返回门店 Id 列表,否则为空数组)
#### 3.2.3 新增
- **方法**:`POST`
- **路径**:`/api/app/label-category`
- **新增入参字段**:
- `displayText`
- `buttonAppearance`、`categoryPhotoUrl`
- `availabilityType`
- `locationIds`(当 `availabilityType=SPECIFIED` 必填且至少 1 个)
#### 3.2.4 编辑
- **方法**:`PUT`
- **路径**:`/api/app/label-category/{id}`
- **入参同新增**
#### 3.2.5 删除
- **方法**:`DELETE`
- **路径**:`/api/app/label-category/{id}`
- **说明**:逻辑删除;若被标签引用会阻止删除(保持原行为)
### 3.3 后端校验规则(本次新增)
- `availabilityType` 仅允许 `ALL/SPECIFIED`
- `SPECIFIED` 时 `locationIds` 至少 1 个
|
ecb291fd
李曜臣
门店支持优化;标签,产品组件优化
|
172
|
- `buttonAppearance`:须为 **合法 JSON**(任意对象/数组),或为兼容的 **`TEXT`/`COLOR`/`IMAGE` 单行**;其它字符串拒绝。`categoryPhotoUrl` 非空且非 JSON 时后端会序列化为 JSON 字符串存储;是否必填由业务/前端约定
|
8e0c49eb
李曜臣
产品标签类别优化;
|
173
174
175
176
177
|
---
## 4. App 端 `GET /api/app/us-app-labeling/labeling-tree`
|
ecb291fd
李曜臣
门店支持优化;标签,产品组件优化
|
178
179
|
- **L1(标签分类)节点**:返回 `categoryPhotoUrl`、`buttonAppearance`(均为库中字符串,**多为 JSON**,与 CRUD 一致);缺省或空时 `buttonAppearance` 后端默认 **`"TEXT"`**(兼容旧数据,**不再**对整段做 `ToUpperInvariant` 以免破坏 JSON)。
- **L2(产品分类)节点**:返回 `displayText`、`buttonAppearance`、`categoryPhotoUrl`、`availabilityType`、`orderNum` 等;外观数据由 **`buttonAppearance` + `categoryPhotoUrl`** 承载(已不再返回 `buttonTextColor`、`buttonBgColor`、`buttonImageUrl`、`buttonStyleJson`)。
|
8e0c49eb
李曜臣
产品标签类别优化;
|
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
|
### 4.1 数据库迁移(两张主表)
在确认历史数据已按需迁到 `CategoryPhotoUrl` 后,可执行(列不存在时需跳过或调整):
```sql
ALTER TABLE `fl_label_category`
DROP COLUMN `ButtonTextColor`,
DROP COLUMN `ButtonBgColor`,
DROP COLUMN `ButtonImageUrl`,
DROP COLUMN `ButtonStyleJson`;
ALTER TABLE `fl_product_category`
DROP COLUMN `ButtonTextColor`,
DROP COLUMN `ButtonBgColor`,
DROP COLUMN `ButtonImageUrl`,
DROP COLUMN `ButtonStyleJson`;
```
---
## 5. Web 管理端会话(`AuthSession` / 食品标签-美国版)
> 实现:`IAuthSessionAppService` / `AuthSessionAppService`。需携带与后台一致的 **JWT**(`Authorization: Bearer {token}`)。具体 action 路径以部署环境 **Swagger / OpenAPI** 为准;下列为 ABP 常规约定(`RootPath = api/app`)。
### 5.1 获取当前登录用户菜单与权限
- **方法**:`GET`
- **路径**(约定):`/api/app/auth-session/my-menus`
- **鉴权**:需要登录
- **用途**:前端动态路由、侧边栏、按钮级权限(`permissionCodes`)
- **返回体**(`CurrentUserMenuPermissionsOutputDto`,JSON 字段名为 camelCase):
| 字段 | 类型 | 说明 |
|---|---|---|
| `user` | object | 当前用户简要信息(无密码) |
| `user.id` | guid | 用户 Id |
| `user.userName` | string | 登录名 |
| `user.nick` | string? | 昵称 |
| `user.email` | string? | 邮箱 |
| `user.icon` | string? | 头像 |
| `roleCodes` | string[] | 角色编码列表(已排序) |
| `permissionCodes` | string[] | 权限码列表(已排序;超级管理员常见为 `*:*:*`) |
| `menus` | array | **菜单树**(根节点列表,子节点在 `children`) |
**菜单树节点**(`CurrentUserMenuNodeDto`)主要字段:
| 字段 | 说明 |
|---|---|
| `id` / `parentId` | 菜单 Id、父 Id(根父级多为 `"0"`) |
| `menuName` | 菜单名称 |
| `routerName` / `router` | 路由名、路径 |
| `permissionCode` | 权限标识(按钮/接口控制用) |
| `menuType` / `menuSource` | 枚举整型值(与 `Menu` 表一致) |
| `orderNum` / `state` | 排序、是否启用 |
| `menuIcon` / `component` / `isLink` / `isCache` / `isShow` / `query` / `remark` | 与菜单表一致 |
| `children` | 子节点数组 |
**业务说明**:
- 数据来源与框架 `UserManager.GetInfoAsync` 一致:按用户角色合并菜单与权限码。
- 用户名为 **`admin`** 时:与 `AccountService.GetVue3Router` 对齐,返回 **`Menu` 表中未逻辑删除** 的全部菜单再组树(`permissionCodes` 仍为超级管理员约定值)。
### 5.2 退出登录
- **方法**:`POST`
- **路径**(约定):`/api/app/auth-session/logout`
- **鉴权**:需要登录(未登录或无法解析用户时返回 `false`)
- **请求体**:无
- **返回**:`boolean`
- `true`:已清除服务端 **用户信息分布式缓存**(与 `AccountService.PostLogout` 一致)
- `false`:当前请求未识别到用户 Id(例如未登录)
- **说明**:JWT 为无状态令牌,**前端仍需丢弃本地 Token**;退出接口主要清理服务端缓存侧用户信息。
---
## 6. 权限菜单 `rbac-menu` 列表/详情补充字段
- **路径**:`GET /api/app/rbac-menu`(列表)、`GET /api/app/rbac-menu/{id}`(详情)
- **新增返回**(与 `menu` 表字段一致,JSON 一般为 camelCase):
- `routerName`:路由名称
- `router`:路由路径
- **说明**:树接口 `GET /api/app/rbac-menu/tree`(若已使用)本身已包含完整菜单字段,无需重复改动。
|