@brms/ai-skills 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/brms-vxe-plus-developer/SKILL.md +5 -0
- package/skills/brms-vxe-plus-developer/references/resource-index.md +6 -0
- package/skills/brms-vxe-plus-developer/references/review-checklist.md +3 -0
- package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/05-request-and-eiinfo.md +13 -0
- package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/06-eiinfo-data-format.md +276 -0
- package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/07-development-tips.md +113 -0
- package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/README.md +7 -2
package/package.json
CHANGED
|
@@ -41,6 +41,8 @@ Then load only the needed knowledge files:
|
|
|
41
41
|
- `03-vxe-plus-table.md`: `VxePlusTable`, columns, editable grids, toolbar buttons.
|
|
42
42
|
- `04-example-map.md`: embedded code examples and offline `sources/project/base/src/views` examples.
|
|
43
43
|
- `05-request-and-eiinfo.md`: EiInfo query/save/transform rules.
|
|
44
|
+
- `06-eiinfo-data-format.md`: raw EiInfo JSON shape; use it for `__blocks__`, `rows` mapping, `attr.count`, and `__sys__` errors.
|
|
45
|
+
- `07-development-tips.md`: approval-detail flag, dynamic button visibility, and cross-page refresh patterns.
|
|
44
46
|
- `90-anti-patterns.md`: final hard-stop checks.
|
|
45
47
|
|
|
46
48
|
If the business project also has `doc/components/vxe-plus-knowledge`, use it as a project-local supplement. If it is missing, use local docs such as `doc/vibeCoding/README.md`, `libs/components/src`, and neighboring pages under the confirmed `project/*/src/views` as supplement.
|
|
@@ -93,8 +95,11 @@ Do not load every source example by default. Search within the confirmed project
|
|
|
93
95
|
- New generated real pages should not import `useForm()` solely to get helper renderers.
|
|
94
96
|
- `VxeDatePicker type="month"` must not use `valueFormat: 'MM'`; use `valueFormat: 'yyyy-MM'` plus `labelFormat: 'MM'`.
|
|
95
97
|
- Table actions belong in `toolbarButtons` / `toolbarButtonClick` unless the existing page has a clear different pattern.
|
|
98
|
+
- For approval-detail, button visibility, and cross-page refresh behavior, prefer existing project patterns: `__approveFlag__`, `btnSetVisible`, and `pageRefreshStore`.
|
|
96
99
|
- Do not add operation/action columns by default.
|
|
97
100
|
- Do not generate REST `http.*` calls when the interface is EiInfo.
|
|
101
|
+
- EiInfo response business data is read from `__blocks__` through `getBlock(blockName)?.getMappedRows()`; errors/status come from `__sys__` or `getStatus()` / `getMsg()`.
|
|
102
|
+
- For EiInfo request construction, do not mix `set()` path writes and `EiBlock.build()` / `addBlock()` on the same `EiInfo` instance.
|
|
98
103
|
- Do not add compatibility code for old data unless explicitly requested.
|
|
99
104
|
- For attachment upload/view, use the shared project flow such as `useFileUpload().openFileBFSS0001` when available.
|
|
100
105
|
|
|
@@ -20,6 +20,8 @@ Load only the reference needed for the current task.
|
|
|
20
20
|
- `references/vxe-plus-knowledge/03-vxe-plus-table.md`: table columns, edit mode, toolbar buttons, slots.
|
|
21
21
|
- `references/vxe-plus-knowledge/04-example-map.md`: embedded examples for direct copying and adaptation.
|
|
22
22
|
- `references/vxe-plus-knowledge/05-request-and-eiinfo.md`: EiInfo query/save/transform behavior.
|
|
23
|
+
- `references/vxe-plus-knowledge/06-eiinfo-data-format.md`: raw EiInfo JSON shape, `__blocks__` data mapping, and `__sys__` error fields.
|
|
24
|
+
- `references/vxe-plus-knowledge/07-development-tips.md`: approval-detail flag, button visibility, and cross-page refresh patterns.
|
|
23
25
|
- `references/vxe-plus-knowledge/90-anti-patterns.md`: hard-stop mistakes.
|
|
24
26
|
|
|
25
27
|
## Offline Source Examples
|
|
@@ -41,3 +43,7 @@ Use focused search terms:
|
|
|
41
43
|
- `toolbarButtonClick`
|
|
42
44
|
- `EiCommunicator.send`
|
|
43
45
|
- `valueFormat`
|
|
46
|
+
- `__approveFlag__`
|
|
47
|
+
- `btnSetVisible`
|
|
48
|
+
- `setRefreshFlag`
|
|
49
|
+
- `checkRefreshFlag`
|
|
@@ -30,12 +30,15 @@ Use this reference before handing real BRMS VxePlus code to a newcomer or review
|
|
|
30
30
|
- `transformParams` does not create a new empty EiInfo unless intentionally discarding defaults.
|
|
31
31
|
- `transformResponse(rows)` expects mapped rows, not a full EiInfo, under the normal `serviceConfig` path.
|
|
32
32
|
- Complex save/confirm/delete builds explicit `EiInfo` blocks matching the backend contract.
|
|
33
|
+
- The same `EiInfo` instance does not mix `set()` path writes with `EiBlock.build()` / `addBlock()` construction.
|
|
34
|
+
- Raw EiInfo JSON handling reads business data from `__blocks__`, maps rows through columns or `getMappedRows()`, and reads errors from `__sys__`.
|
|
33
35
|
- No speculative old-data compatibility was added.
|
|
34
36
|
|
|
35
37
|
## Example And Knowledge Checks
|
|
36
38
|
|
|
37
39
|
- The implementation can point to a nearby real `project/*/src/views` example or a packaged offline source under `references/vxe-plus-knowledge/sources/project/base/src/views`.
|
|
38
40
|
- Any deviation from the knowledge-base pattern is explained by local module code or interface contract.
|
|
41
|
+
- Approval-detail behavior, dynamic button visibility, and cross-page refresh were checked against `references/vxe-plus-knowledge/07-development-tips.md` when relevant.
|
|
39
42
|
- Known anti-patterns from `references/vxe-plus-knowledge/90-anti-patterns.md` were checked.
|
|
40
43
|
|
|
41
44
|
## Validation Checks
|
package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/05-request-and-eiinfo.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
AI 写 `VxePlusTable` 页面时,必须先确认请求形态。这个项目主流后端通信不是普通 REST,而是 `@eplat/ei` 的 `EiInfo` / `EiBlock`。
|
|
4
4
|
|
|
5
|
+
本文件关注请求链路和生成写法。需要判断原始 JSON 结构、`__blocks__` 中的二维数组如何映射、或 `__sys__` 错误信息时,继续读 [06-eiinfo-data-format.md](./06-eiinfo-data-format.md)。
|
|
6
|
+
|
|
5
7
|
## 表格查询默认链路
|
|
6
8
|
|
|
7
9
|
```vue
|
|
@@ -100,6 +102,15 @@ const res = await EiCommunicator.send('BMBR01', 'query', ei)
|
|
|
100
102
|
const rows = res.getBlock('result')?.getMappedRows() || []
|
|
101
103
|
```
|
|
102
104
|
|
|
105
|
+
字段很少,或多个 block 都只是补少量字段时,可以连续使用 `set()` 快速构建:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const ei = new EiInfo()
|
|
109
|
+
ei.set('inqu_status-0-level', 1)
|
|
110
|
+
ei.set('result-0-level', 1)
|
|
111
|
+
await EiCommunicator.send('ABBP02', 'query', ei)
|
|
112
|
+
```
|
|
113
|
+
|
|
103
114
|
有 block 数据:
|
|
104
115
|
|
|
105
116
|
```ts
|
|
@@ -111,6 +122,8 @@ ei.addBlock(EiBlock.build('inqu', [formData]))
|
|
|
111
122
|
await EiCommunicator.send('SMSW0101', 'confirm', ei)
|
|
112
123
|
```
|
|
113
124
|
|
|
125
|
+
重要:当前 EiInfo 库里 `set()` 和 `EiBlock.build()` / `addBlock()` 不能在同一个 `EiInfo` 对象上混用。一个对象已经使用 `set()` 后,不要再 `addBlock(EiBlock.build(...))`;已经使用 build/addBlock 后,也不要再用 `set()` 追加字段。需要额外字段时,把字段放进同一个 build 数据对象里,或改为全量 set-only 构建。
|
|
126
|
+
|
|
114
127
|
## 选中行提交
|
|
115
128
|
|
|
116
129
|
有些 `VxePlusTable` 暴露方法可能直接返回 EiInfo 或封装后的 block 数据。复制前必须看当前页面真实写法,不要假设一定是普通数组。
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# 06-EiInfo Data Format
|
|
2
|
+
|
|
3
|
+
This file records the JSON shape behind `@eplat/ei`. Use it when generated code needs to inspect raw responses, debug block names, handle service errors, or explain why `getMappedRows()` is required.
|
|
4
|
+
|
|
5
|
+
## Practical Reading Rule
|
|
6
|
+
|
|
7
|
+
For BRMS page development, the useful response data is usually in `__blocks__`.
|
|
8
|
+
|
|
9
|
+
Other top-level fields such as `serviceName`, `methodName`, `baseUserInfo`, `__version__`, `UUID`, and project/session metadata are real metadata, but generated page code normally should not depend on them unless the local page already does.
|
|
10
|
+
|
|
11
|
+
Error and status information is in `__sys__`. When an interface fails or returns business errors, check `__sys__.status`, `__sys__.msg`, `__sys__.detailMsg`, `__sys__.msgKey`, and `__sys__.traceId`.
|
|
12
|
+
|
|
13
|
+
## Raw JSON Shape
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
type EiInfoJson = {
|
|
17
|
+
__blocks__?: Record<string, EiBlockJson>
|
|
18
|
+
__sys__?: {
|
|
19
|
+
status?: number
|
|
20
|
+
msg?: string
|
|
21
|
+
detailMsg?: string
|
|
22
|
+
msgKey?: string
|
|
23
|
+
traceId?: string
|
|
24
|
+
name?: string
|
|
25
|
+
descName?: string
|
|
26
|
+
}
|
|
27
|
+
[metadata: string]: unknown
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type EiBlockJson = {
|
|
31
|
+
meta?: {
|
|
32
|
+
columns?: Array<{
|
|
33
|
+
pos: number
|
|
34
|
+
name: string
|
|
35
|
+
descName?: string
|
|
36
|
+
[metadata: string]: unknown
|
|
37
|
+
}>
|
|
38
|
+
attr?: Record<string, unknown>
|
|
39
|
+
desc?: string
|
|
40
|
+
}
|
|
41
|
+
attr?: Record<string, unknown>
|
|
42
|
+
rows?: unknown[][]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Example shape:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"__blocks__": {
|
|
51
|
+
"inqu_status": {
|
|
52
|
+
"meta": {
|
|
53
|
+
"columns": [
|
|
54
|
+
{ "pos": 0, "name": "cuUnitCodeLike", "descName": " " }
|
|
55
|
+
],
|
|
56
|
+
"attr": {},
|
|
57
|
+
"desc": ""
|
|
58
|
+
},
|
|
59
|
+
"attr": {},
|
|
60
|
+
"rows": [[""]]
|
|
61
|
+
},
|
|
62
|
+
"result": {
|
|
63
|
+
"meta": {
|
|
64
|
+
"columns": [
|
|
65
|
+
{ "pos": 0, "name": "modifiedUserName", "descName": " " },
|
|
66
|
+
{ "pos": 1, "name": "modifiedTime", "descName": " " }
|
|
67
|
+
],
|
|
68
|
+
"attr": {},
|
|
69
|
+
"desc": ""
|
|
70
|
+
},
|
|
71
|
+
"attr": {
|
|
72
|
+
"offset": 0,
|
|
73
|
+
"limit": 10,
|
|
74
|
+
"count": 2454,
|
|
75
|
+
"orderBy": ""
|
|
76
|
+
},
|
|
77
|
+
"rows": [["Zhang San", "2026-06-05 16:41:40"]]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"__sys__": {
|
|
81
|
+
"status": 0,
|
|
82
|
+
"msg": "",
|
|
83
|
+
"detailMsg": "",
|
|
84
|
+
"traceId": "..."
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Block Data Mapping
|
|
90
|
+
|
|
91
|
+
Raw block rows are two-dimensional arrays. Do not read them by hard-coded indexes in page code.
|
|
92
|
+
|
|
93
|
+
Mapping rule:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const columns = block.meta.columns
|
|
97
|
+
const row = block.rows[0]
|
|
98
|
+
const mapped = {
|
|
99
|
+
[columns[0].name]: row[columns[0].pos],
|
|
100
|
+
[columns[1].name]: row[columns[1].pos],
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
In real code, prefer the library method:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const rows = res.getBlock('result')?.getMappedRows() || []
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`getMappedRows()` converts:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
[
|
|
114
|
+
['Zhang San', '2026-06-05 16:41:40']
|
|
115
|
+
]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
into:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
[
|
|
122
|
+
{
|
|
123
|
+
modifiedUserName: 'Zhang San',
|
|
124
|
+
modifiedTime: '2026-06-05 16:41:40',
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Common Blocks
|
|
130
|
+
|
|
131
|
+
Common names, not absolute rules:
|
|
132
|
+
|
|
133
|
+
- `inqu_status`: query form conditions.
|
|
134
|
+
- `result`: table result rows.
|
|
135
|
+
- `${tableId}_filter`: header filter block generated by table query.
|
|
136
|
+
- `inqu`: business form block used by some save/confirm interfaces.
|
|
137
|
+
|
|
138
|
+
The real backend contract wins over these defaults. If the interface or neighboring page uses another block name, follow that contract.
|
|
139
|
+
|
|
140
|
+
## Request Construction
|
|
141
|
+
|
|
142
|
+
For single fields, `EiInfo.set()` uses a three-part path:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
const ei = new EiInfo()
|
|
146
|
+
ei.set('inqu_status-0-bpProposalMainCode', formData.bpProposalMainCode)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The path means:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
<blockName>-<rowIndex>-<columnName>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
When there are only a few fields, or multiple blocks each need only a few fields, repeated `set()` calls are the fastest clear construction style:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const ei = new EiInfo()
|
|
159
|
+
ei.set('inqu_status-0-level', 1)
|
|
160
|
+
ei.set('result-0-level', 1)
|
|
161
|
+
await EiCommunicator.send('ABBP02', 'query', ei)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For row collections, build blocks explicitly:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
const ei = new EiInfo()
|
|
168
|
+
ei.addBlock(EiBlock.build('result', rows))
|
|
169
|
+
ei.addBlock(EiBlock.build('inqu_status', [formData]))
|
|
170
|
+
await EiCommunicator.send('ABBP02', 'save', ei)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`EiBlock.build('result', rows)` creates `meta.columns` from object keys and stores values in `rows` as arrays. Consumers should still read through `getMappedRows()` after receiving a response.
|
|
174
|
+
|
|
175
|
+
## Construction Mode Trap
|
|
176
|
+
|
|
177
|
+
The current EiInfo library has a construction bug: do not mix `set()` path writes and `EiBlock.build()` / `addBlock()` on the same `EiInfo` instance.
|
|
178
|
+
|
|
179
|
+
Choose one mode per object:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
// Good: set-only mode.
|
|
183
|
+
const queryEi = new EiInfo()
|
|
184
|
+
queryEi.set('inqu_status-0-level', 1)
|
|
185
|
+
queryEi.set('result-0-level', 1)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
// Good: build-only mode.
|
|
190
|
+
const saveEi = new EiInfo()
|
|
191
|
+
saveEi.addBlock(EiBlock.build('result', rows))
|
|
192
|
+
saveEi.addBlock(EiBlock.build('inqu_status', [formData]))
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Do not write:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
// Bad: mixed construction mode on the same EiInfo object.
|
|
199
|
+
const ei = new EiInfo()
|
|
200
|
+
ei.set('inqu_status-0-level', 1)
|
|
201
|
+
ei.addBlock(EiBlock.build('result', rows))
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
And do not write:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
// Bad: mixed construction mode on the same EiInfo object.
|
|
208
|
+
const ei = new EiInfo()
|
|
209
|
+
ei.addBlock(EiBlock.build('result', rows))
|
|
210
|
+
ei.set('inqu_status-0-level', 1)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
If both a row collection and extra single fields are required, prefer putting the single fields into another built block:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
const ei = new EiInfo()
|
|
217
|
+
ei.addBlock(EiBlock.build('result', rows))
|
|
218
|
+
ei.addBlock(EiBlock.build('inqu_status', [{
|
|
219
|
+
level: 1,
|
|
220
|
+
...formData,
|
|
221
|
+
}]))
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
If the backend explicitly requires `set()` style fields, keep the whole object in set-only mode and set every required field path explicitly.
|
|
225
|
+
|
|
226
|
+
## Table Query Response
|
|
227
|
+
|
|
228
|
+
For `VxePlusTable id="ABBP02_result"`, the table data block is usually `result`.
|
|
229
|
+
|
|
230
|
+
The response data usually lives at:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
const block = res.getBlock('result')
|
|
234
|
+
const rows = block?.getMappedRows() || []
|
|
235
|
+
const total = block?.getAttr?.().count ?? 0
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Raw JSON equivalent:
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
const block = json.__blocks__?.result
|
|
242
|
+
const total = block?.attr?.count
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Do not use unrelated top-level metadata as table rows.
|
|
246
|
+
|
|
247
|
+
## Error Handling
|
|
248
|
+
|
|
249
|
+
`EiCommunicator.send()` may throw transport errors, and successful HTTP responses may still carry business status in `__sys__`.
|
|
250
|
+
|
|
251
|
+
When local code handles status explicitly, use the `EiInfo` methods or raw `__sys__`:
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
const res = await EiCommunicator.send('ABBP02', 'query', ei)
|
|
255
|
+
const status = res.getStatus?.()
|
|
256
|
+
const message = res.getMsg?.() || res.getDetailMsg?.()
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Raw response equivalent:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
const status = json.__sys__?.status
|
|
263
|
+
const message = json.__sys__?.msg || json.__sys__?.detailMsg
|
|
264
|
+
const traceId = json.__sys__?.traceId
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Do not treat an empty `result` block as an error by itself. Empty rows can be a valid query result.
|
|
268
|
+
|
|
269
|
+
## Generation Rules
|
|
270
|
+
|
|
271
|
+
- Prefer `res.getBlock(blockName)?.getMappedRows()` over raw `__blocks__` access in Vue page code.
|
|
272
|
+
- Use raw `__blocks__` only for debugging, documentation, or when the local utility already returns plain JSON.
|
|
273
|
+
- Never hard-code row array indexes like `row[0]` for business fields when column names are available.
|
|
274
|
+
- Read `block.attr.count` for table totals; do not count the current page rows as total.
|
|
275
|
+
- Read `__sys__` / `getStatus()` / `getMsg()` for errors; do not infer errors from missing optional metadata.
|
|
276
|
+
- Preserve backend block names exactly when service docs or neighboring pages specify them.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# 07-Development Tips
|
|
2
|
+
|
|
3
|
+
本文件记录真实 BRMS `project/*` 页面里常见但不属于 VxePlus/EiInfo 核心契约的开发技巧。遇到审批详情、动态按钮显隐、跨页面返回刷新时优先读本文件。
|
|
4
|
+
|
|
5
|
+
这些技巧来自 `D:/Git/AI/eplat-vue-base` 的真实源码核对。复制到其他项目时仍要先检查目标项目是否有同名组件、store、按钮编码和页面标识。
|
|
6
|
+
|
|
7
|
+
## 审批详情页判断 `__approveFlag__`
|
|
8
|
+
|
|
9
|
+
用途:识别当前页面或子组件是否处于审批详情/只读详情场景。常见影响包括表单只读、表格只读、隐藏新增/保存/提交等操作。
|
|
10
|
+
|
|
11
|
+
推荐写法:在详情根页面根据路由或业务状态 provide,在子组件、form config、table/form wrapper 中 inject。
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// 根页面
|
|
15
|
+
provide('__approveFlag__', route.query.status === 'true' ? true : undefined)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
// 子组件或组合式配置
|
|
20
|
+
const approveFlag = inject<boolean | undefined>('__approveFlag__', undefined)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
生成注意:
|
|
24
|
+
|
|
25
|
+
- 不要自己发明新的审批态字段名,优先搜索目标项目里的 `__approveFlag__`。
|
|
26
|
+
- `true` 表示审批详情/只读倾向;`undefined` 通常表示普通页面,避免强行传 `false` 改变已有组件默认逻辑。
|
|
27
|
+
- 如果目标页面已有 `isApprovePage`、`approveFlag`、`editable` 等本地状态,优先沿用本地命名和计算方式。
|
|
28
|
+
- 只读态不仅是表单禁用,也经常需要配合 `btnSetVisible` 隐藏按钮。
|
|
29
|
+
|
|
30
|
+
源码核对点:
|
|
31
|
+
|
|
32
|
+
- `project/base/src/views/AB/BP/ABBP0201.vue`: uses `provide('__approveFlag__', route.query.status === 'true' ? true : undefined)`.
|
|
33
|
+
- `project/base/src/views/AB/BP/component/ABBP02/formConfig.ts`: injects `__approveFlag__` inside form config composition.
|
|
34
|
+
- `libs/components/src/components/table/src/table.tsx`: table wrapper injects `__approveFlag__`.
|
|
35
|
+
- `libs/components/src/components/form/src/form.tsx`: form wrapper injects `__approveFlag__`.
|
|
36
|
+
|
|
37
|
+
## 按钮显隐 `btnSetVisible`
|
|
38
|
+
|
|
39
|
+
用途:根据审批态、页面状态、业务条件动态显示/隐藏 `BxContainer` 或 `VxePlusTable` 按钮。
|
|
40
|
+
|
|
41
|
+
推荐写法:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
detailContainer.value?.btnSetVisible?.(['SAVE', 'SUBMIT', 'TEMP'], false)
|
|
45
|
+
xGrid.value?.btnSetVisible?.(['ADD', 'DELETE', 'SAVE'], editable.value)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`visible` 默认是 `true`,传 `false` 表示隐藏。
|
|
49
|
+
|
|
50
|
+
生成注意:
|
|
51
|
+
|
|
52
|
+
- 按钮编码必须来自真实按钮配置,例如 `toolbarButtons`、后端按钮配置、已有页面调用,不要猜编码。
|
|
53
|
+
- `BxContainer` 按钮通常按 `nodeCode` 匹配;`VxePlusTable` toolbar 按钮通常按 `code` 匹配。调用层都暴露为 `btnSetVisible(codes, visible)`。
|
|
54
|
+
- 只是禁用按钮时用 `btnSetDisable`;要从界面上隐藏才用 `btnSetVisible`。
|
|
55
|
+
- 在 `watch`、数据加载回调、`onMounted` 或状态变化后调用时,要确保 ref 已经可用,建议使用可选链。
|
|
56
|
+
- 审批态页面隐藏按钮时,优先集中在一个状态同步函数里处理,不要把同一批按钮散落到多个 watcher 里。
|
|
57
|
+
|
|
58
|
+
源码核对点:
|
|
59
|
+
|
|
60
|
+
- `project/base/src/components/bx-container/bx-container-v2.vue`: `btnSetVisible(codes, visible = true)` updates container button visibility.
|
|
61
|
+
- `project/base/src/components/bx-container/bx-container.vue`: exposes `btnSetVisible`.
|
|
62
|
+
- `libs/components/src/hooks/useToolbarConfig.ts`: table toolbar exposes `btnSetVisible`.
|
|
63
|
+
- `libs/components/src/components/table/src/table.tsx`: table exposes toolbar methods.
|
|
64
|
+
- `project/base/src/views/AB/BP/ABBP0202.vue`: uses container `btnSetVisible` to switch detail actions.
|
|
65
|
+
- `project/base/src/views/JM/JR/JMJR0101.vue`: uses container `btnSetVisible` for formula status actions.
|
|
66
|
+
|
|
67
|
+
## 页面刷新标记 `pageRefreshStore`
|
|
68
|
+
|
|
69
|
+
用途:从详情页、编辑页、弹窗页或其他页面跳转/返回后,让目标列表页在 `onActivated` 中按需刷新。适用于 KeepAlive 页面之间的“保存成功后回到列表刷新表格”。
|
|
70
|
+
|
|
71
|
+
推荐写法:触发方设置标记,目标方检查标记并刷新。
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// 触发方:保存、提交、生效、删除成功后
|
|
75
|
+
const pageRefreshStore = usePageRefreshStore()
|
|
76
|
+
pageRefreshStore.setRefreshFlag('SMSO0102')
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
// 目标方:KeepAlive 激活时刷新
|
|
81
|
+
const pageRefreshStore = usePageRefreshStore()
|
|
82
|
+
|
|
83
|
+
onActivated(() => {
|
|
84
|
+
if (pageRefreshStore.checkRefreshFlag('SMSO0102'))
|
|
85
|
+
xGrid.value?.reload()
|
|
86
|
+
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
生成注意:
|
|
90
|
+
|
|
91
|
+
- `setRefreshFlag()` 和 `checkRefreshFlag()` 的 key 必须一致。
|
|
92
|
+
- key 可以是页面名,也可以是更细的业务标识,例如 `JMJR0101.refreshTable`;优先沿用目标模块已有约定。
|
|
93
|
+
- `checkRefreshFlag()` 检查到 `true` 后会重置标记,避免重复刷新。
|
|
94
|
+
- 不要用全局事件或直接跨页面拿 ref 替代该 store,除非目标项目没有 `usePageRefreshStore`。
|
|
95
|
+
- 如果页面没有 KeepAlive 或没有 `onActivated`,先检查本地路由/页面生命周期,不要机械套用。
|
|
96
|
+
|
|
97
|
+
源码核对点:
|
|
98
|
+
|
|
99
|
+
- `project/base/src/stores/modules/pageRefresh.ts`: defines `setRefreshFlag(pageName)` and `checkRefreshFlag(pageName)`.
|
|
100
|
+
- `project/base/src/views/SM/SO/SMSO0101.vue`: calls `setRefreshFlag('SMSO0102')` after confirm.
|
|
101
|
+
- `project/base/src/views/SM/SO/SMSO0102.vue`: uses `onActivated` + `checkRefreshFlag('SMSO0102')` + `xGrid.reload()`.
|
|
102
|
+
- `project/base/src/views/JM/JR/JMJR0101.vue`: uses `setRefreshFlag('JMJR0101.refreshTable')`.
|
|
103
|
+
- `project/base/src/views/JM/JR/JMJR01/right.vue`: checks `JMJR0101.refreshTable` and reloads.
|
|
104
|
+
|
|
105
|
+
## When To Use
|
|
106
|
+
|
|
107
|
+
Use these tips when the requirement says:
|
|
108
|
+
|
|
109
|
+
- 审批详情、审批态、只读详情、查看详情。
|
|
110
|
+
- 隐藏/显示/禁用某些按钮。
|
|
111
|
+
- 保存后返回列表刷新、关闭详情后刷新、跨页面触发表格 reload。
|
|
112
|
+
|
|
113
|
+
Do not introduce these patterns into a simple page unless the behavior is actually required by the requirement or neighboring module style.
|
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
2. 写表单前读 [02-vxe-plus-form.md](./02-vxe-plus-form.md):只复制直接组件契约,不复制历史二次封装。
|
|
13
13
|
3. 写表格前读 [03-vxe-plus-table.md](./03-vxe-plus-table.md):确认 `id`、`form-config`、`service-config`、编辑列、按钮事件。
|
|
14
14
|
4. 写请求前必须读 [05-request-and-eiinfo.md](./05-request-and-eiinfo.md):确认 EiInfo block、分页、响应 block、保存提交方式。
|
|
15
|
-
5.
|
|
16
|
-
6.
|
|
15
|
+
5. 需要判断原始返回、block 映射或接口错误时读 [06-eiinfo-data-format.md](./06-eiinfo-data-format.md):真实数据主要在 `__blocks__`,错误信息看 `__sys__`。
|
|
16
|
+
6. 遇到审批态、按钮显隐、跨页面刷新时读 [07-development-tips.md](./07-development-tips.md):确认 `__approveFlag__`、`btnSetVisible`、`pageRefreshStore`。
|
|
17
|
+
7. 找样例读 [04-example-map.md](./04-example-map.md):按场景复制内嵌样例,再按来源路径核对真实业务差异。
|
|
18
|
+
8. 交付前读 [90-anti-patterns.md](./90-anti-patterns.md):检查高频错误。
|
|
17
19
|
|
|
18
20
|
## 最高优先级约束
|
|
19
21
|
|
|
@@ -21,6 +23,9 @@
|
|
|
21
23
|
- `VxePlusTable` 的查询表单配置使用 `:form-config`,它不是独立 `VxePlusForm` 的属性。
|
|
22
24
|
- 新写代码不要引入新的 `useForm` 二次封装层。历史页面里的 `src/hooks/useForm.ts` 只能作为识别既有代码的词典,不作为推荐样板。
|
|
23
25
|
- 表格请求优先走 `serviceConfig` + `transformParams` / `transformResponse`。复杂保存优先显式构造 `EiInfo`。
|
|
26
|
+
- EiInfo 原始返回中业务数据主要在 `__blocks__`;错误/状态信息看 `__sys__` 或 `getStatus()` / `getMsg()`。
|
|
27
|
+
- 同一个 `EiInfo` 对象不要混用 `set()` 路径写入和 `EiBlock.build()` / `addBlock()` 构建。
|
|
28
|
+
- 审批详情、按钮显隐、跨页面刷新优先沿用项目已有的 `__approveFlag__`、`btnSetVisible`、`pageRefreshStore`。
|
|
24
29
|
- 没有用户明确要求兼容旧数据时,不写字段回退、旧格式兼容、双路径兼容。
|
|
25
30
|
|
|
26
31
|
## 框架源码边界
|