@brms/ai-skills 0.1.0

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.
Files changed (90) hide show
  1. package/README.md +256 -0
  2. package/bin/brms-skills.mjs +411 -0
  3. package/package.json +30 -0
  4. package/skills/brms-prototype-generator/SKILL.md +129 -0
  5. package/skills/brms-prototype-generator/agents/openai.yaml +7 -0
  6. package/skills/brms-prototype-generator/examples/few-shot-examples.md +577 -0
  7. package/skills/brms-prototype-generator/references/01-list-query.md +444 -0
  8. package/skills/brms-prototype-generator/references/02-form-entry.md +129 -0
  9. package/skills/brms-prototype-generator/references/03-detail-display.md +125 -0
  10. package/skills/brms-prototype-generator/references/04-composite-page-package.md +339 -0
  11. package/skills/brms-prototype-generator/references/05-dialog-patterns.md +113 -0
  12. package/skills/brms-prototype-generator/references/06-backend-request-patterns.md +118 -0
  13. package/skills/brms-prototype-generator/references/resource-index.md +46 -0
  14. package/skills/brms-prototype-generator/references/system-prompt.md +242 -0
  15. package/skills/brms-prototype-generator/scripts/analyze-doc.mjs +554 -0
  16. package/skills/brms-prototype-generator/scripts/check-project.mjs +228 -0
  17. package/skills/brms-prototype-generator/scripts/discover-targets.mjs +158 -0
  18. package/skills/brms-prototype-generator/scripts/install-codex.mjs +74 -0
  19. package/skills/brms-prototype-generator/scripts/plan-pages.mjs +390 -0
  20. package/skills/brms-prototype-generator/scripts/validate-generated.mjs +838 -0
  21. package/skills/brms-prototype-generator/templates/user-input-template.md +182 -0
  22. package/skills/brms-vxe-plus-developer/SKILL.md +105 -0
  23. package/skills/brms-vxe-plus-developer/agents/openai.yaml +7 -0
  24. package/skills/brms-vxe-plus-developer/references/prototype-to-real.md +54 -0
  25. package/skills/brms-vxe-plus-developer/references/real-base-development.md +110 -0
  26. package/skills/brms-vxe-plus-developer/references/resource-index.md +43 -0
  27. package/skills/brms-vxe-plus-developer/references/review-checklist.md +49 -0
  28. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/01-mental-model.md +150 -0
  29. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/02-vxe-plus-form.md +302 -0
  30. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/03-vxe-plus-table.md +253 -0
  31. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/04-example-map.md +488 -0
  32. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/05-request-and-eiinfo.md +170 -0
  33. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/90-anti-patterns.md +137 -0
  34. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/README.md +43 -0
  35. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/README.md +21 -0
  36. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/A1/P0/A1P01601.vue +483 -0
  37. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/A1/P1/A1P11011.vue +444 -0
  38. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/AB/BP/ABBP0201.vue +1648 -0
  39. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/AM/AF/component/AMAF0601/Bidding/formConfig.ts +228 -0
  40. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/AM/AF/component/AMAF0601/Record/columns.ts +110 -0
  41. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/BM/BR/BMBR01.vue +130 -0
  42. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/BM/BR/component/BMBR01/columns.ts +94 -0
  43. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/BM/BR/component/BMBR01/formConfig.ts +108 -0
  44. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Change/formConfig.ts +123 -0
  45. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Change/index.vue +103 -0
  46. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Clause/columns.ts +48 -0
  47. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Clause/index.vue +202 -0
  48. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Correcte/formConfig.ts +117 -0
  49. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Correcte/index.vue +103 -0
  50. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/Payment/formConfig.ts +90 -0
  51. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/Payment/index.vue +42 -0
  52. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/columns.ts +376 -0
  53. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/index.vue +619 -0
  54. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Domestic/formConfig.ts +73 -0
  55. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Domestic/index.vue +47 -0
  56. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Foreign/formConfig.ts +141 -0
  57. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Foreign/index.vue +42 -0
  58. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/columns.ts +123 -0
  59. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/index.vue +593 -0
  60. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/index.vue +68 -0
  61. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Fee/columns.ts +150 -0
  62. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Fee/index.vue +235 -0
  63. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Files/columns.ts +63 -0
  64. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Files/index.vue +117 -0
  65. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Goods/columns.ts +327 -0
  66. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Goods/index.vue +790 -0
  67. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve/formConfig.ts +341 -0
  68. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve/index.vue +63 -0
  69. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve2/formConfig.ts +232 -0
  70. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve2/index.vue +27 -0
  71. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Diff/columns.ts +46 -0
  72. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Diff/index.vue +92 -0
  73. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/formConfig.ts +979 -0
  74. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/index.vue +62 -0
  75. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Other/formConfig.ts +179 -0
  76. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Other/index.vue +140 -0
  77. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Sign/formConfig.ts +118 -0
  78. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Sign/index.vue +44 -0
  79. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/index.vue +168 -0
  80. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/Major/formConfig.ts +257 -0
  81. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/Major/index.vue +47 -0
  82. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/columns.ts +256 -0
  83. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/index.vue +738 -0
  84. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Price/formConfig.ts +174 -0
  85. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Price/index.vue +51 -0
  86. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Top/index.vue +924 -0
  87. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/SM/SW/SMSW0101.vue +567 -0
  88. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/demo/index.vue +448 -0
  89. package/skills/brms-vxe-plus-developer/scripts/check-project.mjs +259 -0
  90. package/skills/brms-vxe-plus-developer/scripts/check-vxe-plus-page.mjs +137 -0
@@ -0,0 +1,488 @@
1
+ # 04-Embedded Examples
2
+
3
+ 本文件是给 AI 直接复制和改造的场景样例库。每个样例都尽量自包含;“来源”只用于回到工程中核对,不是使用本文档的必要条件。
4
+
5
+ ## 标准查询页
6
+
7
+ 适用:查询条件 + 查询结果表格,最常见页面。
8
+
9
+ ```vue
10
+ <template>
11
+ <BxContainer id="INQU" title="查询条件" :form-ref="xForm" @btn-click="btnClick">
12
+ <VxePlusForm
13
+ ref="xForm"
14
+ folding
15
+ :form-options="formOptions"
16
+ />
17
+ </BxContainer>
18
+
19
+ <BxContainer title="查询结果">
20
+ <VxePlusTable
21
+ id="BMBR01_result"
22
+ ref="xGrid"
23
+ :columns="columns"
24
+ :form-config="tableFormConfig"
25
+ :service-config="serviceConfig"
26
+ :show-checkbox="true"
27
+ v-on="gridEvents"
28
+ />
29
+ </BxContainer>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import { nextTick, reactive, ref } from 'vue'
34
+
35
+ const xForm = ref<any>()
36
+ const xGrid = ref<any>()
37
+
38
+ const formData = reactive({
39
+ formulaCode: '',
40
+ formulaName: '',
41
+ formulaStatus: '',
42
+ })
43
+
44
+ const formOptions = reactive({
45
+ id: 'inqu_status',
46
+ data: formData,
47
+ titleWidth: 120,
48
+ items: [
49
+ { field: 'formulaCode', title: '价格公式编号', itemRender: { name: 'VxeInput' } },
50
+ { field: 'formulaName', title: '价格公式名称', itemRender: { name: 'VxeInput' } },
51
+ {
52
+ field: 'formulaStatus',
53
+ title: '状态',
54
+ itemRender: {
55
+ name: 'formSelect',
56
+ props: {
57
+ codeSet: 'BRMERP.bm.formulaStatus',
58
+ clearable: true,
59
+ },
60
+ },
61
+ },
62
+ ],
63
+ })
64
+
65
+ const tableFormConfig = reactive({
66
+ id: 'inqu_status',
67
+ data: formData,
68
+ })
69
+
70
+ const serviceConfig = reactive({
71
+ serviceName: 'BMBR01',
72
+ queryMethod: 'pageQueryLike',
73
+ })
74
+
75
+ const columns = reactive([
76
+ { field: 'formulaCode', title: '价格公式编号', minWidth: 140 },
77
+ { field: 'formulaName', title: '价格公式名称', minWidth: 180, showOverflow: true },
78
+ {
79
+ field: 'formulaStatus',
80
+ title: '状态',
81
+ editRender: {
82
+ name: 'tableSelect',
83
+ enabled: false,
84
+ props: { codeSet: 'BRMERP.bm.formulaStatus' },
85
+ },
86
+ },
87
+ ])
88
+
89
+ const gridEvents = reactive({
90
+ toolbarButtonClick: ({ code, row }) => {
91
+ if (code === 'VIEW') {
92
+ openDetail(row)
93
+ }
94
+ },
95
+ })
96
+
97
+ function btnClick(btn: { code: string }) {
98
+ if (btn.code === 'QUERY') {
99
+ xGrid.value.reload()
100
+ }
101
+ if (btn.code === 'RESET') {
102
+ xForm.value.getFormInstance().reset()
103
+ nextTick(() => xGrid.value.reload())
104
+ }
105
+ }
106
+
107
+ function openDetail(row: any) {
108
+ console.log(row)
109
+ }
110
+ </script>
111
+ ```
112
+
113
+ 来源:`project/base/src/views/BM/BR/BMBR01.vue`。注意:真实来源里可能有历史 helper,新代码优先使用上面的直接 `itemRender` 写法。
114
+
115
+ ## 查询参数补充与响应转换
116
+
117
+ 适用:查询参数不只来自表单字段,还要额外传 attr、业务类型、路由参数;响应行需要转换。
118
+
119
+ ```vue
120
+ <VxePlusTable
121
+ id="SMSW0101_result"
122
+ ref="xGrid"
123
+ :columns="columns"
124
+ :form-config="tableFormConfig"
125
+ :service-config="serviceConfig"
126
+ :transform-params="transformParams"
127
+ :transform-response="transformResponse"
128
+ />
129
+ ```
130
+
131
+ ```ts
132
+ import type { EiInfo } from '@eplat/ei'
133
+
134
+ const formData = reactive({
135
+ orgId: '',
136
+ goodsName: '',
137
+ qty: true,
138
+ qtyButton: 'Y',
139
+ })
140
+
141
+ const tableFormConfig = reactive({
142
+ id: 'inqu_status',
143
+ data: formData,
144
+ })
145
+
146
+ const serviceConfig = reactive({
147
+ serviceName: 'SMSW0101',
148
+ queryMethod: 'query',
149
+ })
150
+
151
+ function transformParams(formEi: EiInfo) {
152
+ formEi.setAttr({
153
+ qtyButton: formData.qtyButton,
154
+ })
155
+ formEi.set('inqu_status-0-businessType', 'SW_OUTSTOCK')
156
+ return formEi
157
+ }
158
+
159
+ function transformResponse(rows: any[]) {
160
+ return rows.map(row => ({
161
+ ...row,
162
+ h2oValueBase: Number(row.h2oValueBase || 0) * 100,
163
+ }))
164
+ }
165
+ ```
166
+
167
+ 来源:`project/base/src/views/SM/SW/SMSW0101.vue`。关键点:`transformParams` 修改传入的 `formEi`,不要重新 new 空 EiInfo。
168
+
169
+ ## 接口字典下拉
170
+
171
+ 适用:字典选项不是固定 codeset,而是通过服务查询。
172
+
173
+ ```ts
174
+ import { getCodeSetByService } from '@/utils/eiTools'
175
+
176
+ const formOptions = reactive({
177
+ id: 'inqu_status',
178
+ data: formData,
179
+ items: [
180
+ {
181
+ field: 'orgId',
182
+ title: '所属账套',
183
+ itemRender: {
184
+ name: 'formSelect',
185
+ props: {
186
+ codeSet: 'BMBE0000.queryBookOrgByListByPurOrg',
187
+ promiseFn: params => getCodeSetByService({
188
+ serviceName: 'BMBE0000',
189
+ methodName: 'queryBookOrgByListByPurOrg',
190
+ params,
191
+ blockName: 'bookResult',
192
+ value: 'orgId',
193
+ label: 'bookAndOrgDeptName',
194
+ }),
195
+ backfillFields: 'bookId,groupId,deptId,companyId',
196
+ clearable: true,
197
+ filterable: true,
198
+ },
199
+ },
200
+ },
201
+ ],
202
+ rules: {
203
+ orgId: [{ required: true, message: '请选择所属账套' }],
204
+ },
205
+ })
206
+ ```
207
+
208
+ 表格列里同样可以用 `tableSelect`:
209
+
210
+ ```ts
211
+ {
212
+ field: 'teamCode',
213
+ title: '创业团队',
214
+ editRender: {
215
+ name: 'tableSelect',
216
+ props: {
217
+ codeSet: 'BMBF3002.queryTeam',
218
+ promiseFn: params => getCodeSetByService({
219
+ serviceName: 'BMBF3002',
220
+ methodName: 'queryTeam',
221
+ params,
222
+ blockName: 'result',
223
+ value: 'teamCode',
224
+ label: 'teamName',
225
+ }),
226
+ backfillFields: 'teamName',
227
+ },
228
+ },
229
+ }
230
+ ```
231
+
232
+ 来源:`project/base/src/views/SM/SW/SMSW0101.vue`。
233
+
234
+ ## 表单弹窗选择
235
+
236
+ 适用:表单字段通过弹窗选中一行后回填。
237
+
238
+ ```ts
239
+ import CustomerDialog from '@/views/UM/UC/UMUC9902.vue'
240
+
241
+ {
242
+ field: 'customerName',
243
+ title: '客户名称',
244
+ itemRender: {
245
+ name: 'formSelectDialog',
246
+ props: {
247
+ component: CustomerDialog,
248
+ fields: 'customerName,customerCode',
249
+ dialogFields: 'corpName,corpCode',
250
+ componentParam: {
251
+ param: {
252
+ corpType: 'CUSTOMER',
253
+ },
254
+ },
255
+ },
256
+ },
257
+ }
258
+ ```
259
+
260
+ 规则:
261
+
262
+ - `fields` 是当前表单要被回填的字段。
263
+ - `dialogFields` 是弹窗选中行中的字段。
264
+ - 两边数量和顺序必须一致。
265
+ - 字段不确定时,先查看弹窗组件返回行结构。
266
+
267
+ 来源:`project/base/src/views/SM/SW/SMSW0101.vue`、`project/base/src/views/AM/AF/component/AMAF0601/Bidding/formConfig.ts`。
268
+
269
+ ## 表格弹窗选择
270
+
271
+ 适用:可编辑表格某一列通过弹窗回填多个字段。
272
+
273
+ ```ts
274
+ import FeeTypeDialog from './FeeTypeDialog.vue'
275
+
276
+ const columns = reactive([
277
+ {
278
+ field: 'feeTypeName',
279
+ title: '费用类型',
280
+ editRender: {
281
+ name: 'tableSelectDialog',
282
+ props: {
283
+ component: FeeTypeDialog,
284
+ fields: 'feeTypeName,cgFeeTypeCode',
285
+ dialogFields: 'estimationFeeTypeName,ceEstimationFeeTypeCode',
286
+ },
287
+ },
288
+ },
289
+ ])
290
+ ```
291
+
292
+ 来源:`project/base/src/views/AM/AF/component/AMAF0601/Record/columns.ts`。
293
+
294
+ ## 可编辑表格新增、删除、保存
295
+
296
+ 适用:表格支持行编辑,保存时统一提交表格数据。
297
+
298
+ ```vue
299
+ <VxePlusTable
300
+ id="A1P01601_result"
301
+ ref="xGrid"
302
+ :columns="columns"
303
+ :form-config="tableFormConfig"
304
+ :service-config="serviceConfig"
305
+ :is-edit="true"
306
+ :edit-rules="editRules"
307
+ :toolbar-buttons="toolbarButtons"
308
+ v-on="gridEvents"
309
+ />
310
+ ```
311
+
312
+ ```ts
313
+ import { EiBlock, EiCommunicator, EiInfo } from '@eplat/ei'
314
+ import { ElMessage } from 'element-plus'
315
+
316
+ const xGrid = ref<any>()
317
+
318
+ const toolbarButtons = ref([
319
+ { name: '新增', code: 'ADD' },
320
+ { name: '保存', code: 'SAVE', status: 'success' },
321
+ { name: '删除', code: 'DELETE', status: 'danger' },
322
+ ])
323
+
324
+ const editRules = reactive({
325
+ itemName: [{ required: true, message: '名称必填' }],
326
+ itemValue: [{ required: true, message: '值必填' }],
327
+ })
328
+
329
+ const columns = reactive([
330
+ { field: 'itemName', title: '名称', editRender: { name: 'VxeInput' } },
331
+ { field: 'itemValue', title: '值', editRender: { name: 'VxeInput' } },
332
+ ])
333
+
334
+ const gridEvents = reactive({
335
+ toolbarButtonClick: async ({ code, $grid }) => {
336
+ if (code === 'ADD') {
337
+ const { row } = await $grid.insertAt({ id: '' }, -1)
338
+ await $grid.setEditRow(row)
339
+ }
340
+
341
+ if (code === 'DELETE') {
342
+ const rows = $grid.getCheckboxRecords()
343
+ if (!rows.length) {
344
+ ElMessage.warning('请选择数据')
345
+ return
346
+ }
347
+ await $grid.removeCheckboxRow()
348
+ }
349
+
350
+ if (code === 'SAVE') {
351
+ await handleSave()
352
+ }
353
+ },
354
+ })
355
+
356
+ async function handleSave() {
357
+ const $grid = xGrid.value.getGridInstance()
358
+ await $grid.fullValidate()
359
+ const { tableData } = $grid.getTableData()
360
+
361
+ const ei = new EiInfo()
362
+ ei.addBlock(EiBlock.build('result', tableData))
363
+ await EiCommunicator.send('A1P01601', 'save', ei)
364
+ xGrid.value.reload()
365
+ }
366
+ ```
367
+
368
+ 来源:`project/base/src/views/A1/P0/A1P01601.vue`。注意:真实接口可能要求新增、修改、删除分 block,必须按接口调整。
369
+
370
+ ## 选中行确认提交
371
+
372
+ 适用:表格勾选若干行,附加表单信息后调用确认接口。
373
+
374
+ ```ts
375
+ import { EiBlock, EiCommunicator, EiInfo } from '@eplat/ei'
376
+ import { ElMessage, ElMessageBox } from 'element-plus'
377
+
378
+ async function handleConfirm() {
379
+ const checkboxRecords = xGrid.value?.getCheckboxRecords()
380
+ const resultBlock = checkboxRecords?.getBlock?.('result')
381
+
382
+ if (!resultBlock || resultBlock.rows.length === 0) {
383
+ ElMessage.error('请选择要确认的记录')
384
+ return
385
+ }
386
+
387
+ if (!formData.warehouseName) {
388
+ ElMessage.error('请选择仓库信息')
389
+ return
390
+ }
391
+
392
+ checkboxRecords.addBlock(EiBlock.build('inqu', [formData]))
393
+
394
+ await ElMessageBox.confirm('确定要执行确认操作吗?')
395
+ await EiCommunicator.send('SMSW0101', 'confirm', checkboxRecords)
396
+ xGrid.value.reload()
397
+ }
398
+ ```
399
+
400
+ 如果 `getCheckboxRecords()` 返回普通数组,则改为:
401
+
402
+ ```ts
403
+ const rows = xGrid.value.getGridInstance().getCheckboxRecords()
404
+ const ei = new EiInfo()
405
+ ei.addBlock(EiBlock.build('result', rows))
406
+ ei.addBlock(EiBlock.build('inqu', [formData]))
407
+ await EiCommunicator.send('SMSW0101', 'confirm', ei)
408
+ ```
409
+
410
+ 来源:`project/base/src/views/SM/SW/SMSW0101.vue`。
411
+
412
+ ## 条件显隐与联动
413
+
414
+ 适用:某个字段根据其他字段显示,或字段变化时更新辅助参数。
415
+
416
+ ```ts
417
+ const formData = reactive({
418
+ reasonType: '',
419
+ otherReason: '',
420
+ qty: true,
421
+ qtyButton: 'Y',
422
+ })
423
+
424
+ const formOptions = reactive({
425
+ id: 'inqu_status',
426
+ data: formData,
427
+ items: [
428
+ {
429
+ field: 'reasonType',
430
+ title: '原因类型',
431
+ itemRender: {
432
+ name: 'formSelect',
433
+ props: { codeSet: 'brmerp.demo.reasonType' },
434
+ },
435
+ },
436
+ {
437
+ field: 'otherReason',
438
+ title: '其他原因',
439
+ visibleMethod: ({ data }) => data.reasonType === 'OTHER',
440
+ itemRender: { name: 'VxeInput' },
441
+ },
442
+ {
443
+ field: 'qty',
444
+ title: '只看可出库',
445
+ itemRender: {
446
+ name: 'VxeCheckbox',
447
+ events: {
448
+ change({ data }) {
449
+ data.qtyButton = data.qty ? 'Y' : 'N'
450
+ },
451
+ },
452
+ },
453
+ },
454
+ ],
455
+ })
456
+ ```
457
+
458
+ 来源:`project/base/src/views/SM/SW/SMSW0101.vue`、`project/base/src/views/AM/AF/component/AMAF0601/Bidding/formConfig.ts`。
459
+
460
+ ## 复杂页面参考原则
461
+
462
+ 后端驱动表单/表格、复合详情页、多 tab 多表格页面不要作为默认模板。AI 只有在需求明确包含“动态字段”“动态列”“详情总线”“多子模块保存”时才参考这些模式。
463
+
464
+ 最小可复制骨架:
465
+
466
+ ```ts
467
+ provide('__DETAIL_METHODS__', {
468
+ getData,
469
+ validate,
470
+ saveDetail,
471
+ reloadDetail,
472
+ })
473
+
474
+ const detailInfo = ref({})
475
+
476
+ async function reloadDetail() {
477
+ const ei = new EiInfo()
478
+ ei.set('inqu_status-0-id', route.query.id)
479
+ const res = await EiCommunicator.send('DETAIL01', 'detail', ei)
480
+ detailInfo.value = res.getBlock('result')?.getMappedRows()?.[0] || {}
481
+ }
482
+ ```
483
+
484
+ 来源:`project/base/src/views/A1/P1/A1P11011.vue`、`project/base/src/views/PM/PC/component/PMPC0101/`、`project/base/src/views/AB/BP/ABBP0201.vue`。
485
+
486
+ ## Demo 使用边界
487
+
488
+ `project/base/src/views/demo/index.vue` 适合查组件能力,例如导入导出、renderer 名称、特殊 props。它不是业务页面最佳实践。
@@ -0,0 +1,170 @@
1
+ # 05-Requests And EiInfo
2
+
3
+ AI 写 `VxePlusTable` 页面时,必须先确认请求形态。这个项目主流后端通信不是普通 REST,而是 `@eplat/ei` 的 `EiInfo` / `EiBlock`。
4
+
5
+ ## 表格查询默认链路
6
+
7
+ ```vue
8
+ <VxePlusTable
9
+ id="SMSW0101_result"
10
+ :form-config="tableFormConfig"
11
+ :service-config="serviceConfig"
12
+ :transform-params="transformParams"
13
+ :transform-response="transformResponse"
14
+ />
15
+ ```
16
+
17
+ ```ts
18
+ const tableFormConfig = reactive({
19
+ id: 'inqu_status',
20
+ data: formData,
21
+ })
22
+
23
+ const serviceConfig = reactive({
24
+ serviceName: 'SMSW0101',
25
+ queryMethod: 'query',
26
+ })
27
+ ```
28
+
29
+ 组件内部 `useTableData` 的关键推导:
30
+
31
+ - `tableId = id.split('_').slice(1).join('_')`,例如 `SMSW0101_result` -> `result`。
32
+ - `formId = formConfig.id || 'inqu_status'`。
33
+ - 查询时把 `formConfig.data` 写入 EiInfo,内部等价于:
34
+
35
+ ```ts
36
+ formEi.set(`${formId}-0-${key}`, value)
37
+ ```
38
+ - 分页和排序写入 `EiBlock(tableId).attr`,包含 `currentPage/pageSize` 或 `offset/limit`,以及 `orderBy`。
39
+ - 表头筛选会覆盖同名表单字段,并额外构造 `${tableId}_filter` block。
40
+ - 请求调用:`EiCommunicator.send(serviceName, queryMethod || 'query', requestFormEi)`。
41
+ - 响应读取:`res.getBlock(tableId).getMappedRows()`。
42
+ - 总数读取:`res.getBlock(tableId).getAttr().count`。
43
+
44
+ ## transformParams
45
+
46
+ `transformParams` 接收到的是已经按默认规则组装好的 `EiInfo`。只在这里补充额外 attr、block 或特殊字段。
47
+
48
+ ```ts
49
+ import type { EiInfo } from '@eplat/ei'
50
+
51
+ function transformParams(formEi: EiInfo) {
52
+ formEi.setAttr({
53
+ qtyButton: formData.qtyButton,
54
+ })
55
+ formEi.set('inqu_status-0-businessType', 'SW_OUTSTOCK')
56
+ return formEi
57
+ }
58
+ ```
59
+
60
+ 需要新增 block:
61
+
62
+ ```ts
63
+ import { EiBlock } from '@eplat/ei'
64
+
65
+ function transformParams(formEi: EiInfo) {
66
+ formEi.addBlock(EiBlock.build('extra', [{
67
+ projectId: route.query.projectId,
68
+ }]))
69
+ return formEi
70
+ }
71
+ ```
72
+
73
+ 不要在 `transformParams` 里重新 new 一个空 EiInfo,除非你明确要丢弃组件默认组装的表单、分页、排序和筛选。
74
+
75
+ ## transformResponse
76
+
77
+ `serviceConfig` 路径下,`transformResponse` 收到的是 `tableId` block 的 mapped rows 数组。
78
+
79
+ ```ts
80
+ function transformResponse(rows) {
81
+ return rows.map(row => ({
82
+ ...row,
83
+ h2oValueBase: Number(row.h2oValueBase || 0) * 100,
84
+ }))
85
+ }
86
+ ```
87
+
88
+ 不要在这里再 `res.getBlock()`,因为此时通常已经不是完整 `EiInfo`。
89
+
90
+ ## 手工查询
91
+
92
+ 不通过表格代理时,显式构造 EiInfo。
93
+
94
+ ```ts
95
+ import { EiCommunicator, EiInfo } from '@eplat/ei'
96
+
97
+ const ei = new EiInfo()
98
+ ei.set('inqu_status-0-formulaCode', formData.formulaCode)
99
+ const res = await EiCommunicator.send('BMBR01', 'query', ei)
100
+ const rows = res.getBlock('result')?.getMappedRows() || []
101
+ ```
102
+
103
+ 有 block 数据:
104
+
105
+ ```ts
106
+ import { EiBlock, EiCommunicator, EiInfo } from '@eplat/ei'
107
+
108
+ const ei = new EiInfo()
109
+ ei.addBlock(EiBlock.build('result', rows))
110
+ ei.addBlock(EiBlock.build('inqu', [formData]))
111
+ await EiCommunicator.send('SMSW0101', 'confirm', ei)
112
+ ```
113
+
114
+ ## 选中行提交
115
+
116
+ 有些 `VxePlusTable` 暴露方法可能直接返回 EiInfo 或封装后的 block 数据。复制前必须看当前页面真实写法,不要假设一定是普通数组。
117
+
118
+ 常见形态:
119
+
120
+ ```ts
121
+ const checkboxRecords = xGrid.value?.getCheckboxRecords()
122
+ checkboxRecords.addBlock(EiBlock.build('inqu', [formData]))
123
+ await EiCommunicator.send('SMSW0101', 'confirm', checkboxRecords)
124
+ ```
125
+
126
+ 如果底层 `$grid.getCheckboxRecords()` 返回普通数组,则需要自己 build block:
127
+
128
+ ```ts
129
+ const $grid = xGrid.value.getGridInstance()
130
+ const rows = $grid.getCheckboxRecords()
131
+ const ei = new EiInfo()
132
+ ei.addBlock(EiBlock.build('result', rows))
133
+ await EiCommunicator.send(serviceName, methodName, ei)
134
+ ```
135
+
136
+ ## 保存提交
137
+
138
+ 简单新增可以考虑表格代理保存,但生成代码前必须核对组件源码和当前页面。当前 `useTableData` 的 proxy save 主要把 `insertRecords` build 到 `tableId` block,再调用 `insertMethod || 'insert'`,update/delete 逻辑没有完整实现。
139
+
140
+ 复杂保存推荐显式写:
141
+
142
+ ```ts
143
+ const $grid = xGrid.value.getGridInstance()
144
+ await $grid.fullValidate()
145
+ const { tableData } = $grid.getTableData()
146
+
147
+ const ei = new EiInfo()
148
+ ei.addBlock(EiBlock.build('result', tableData))
149
+ ei.addBlock(EiBlock.build('inqu_status', [formData]))
150
+ await EiCommunicator.send('A1P01601', 'save', ei)
151
+ xGrid.value.reload()
152
+ ```
153
+
154
+ 如果后端要求新增、修改、删除分别放不同 block,就按接口要求命名,不要为了兼容猜测多个 block。
155
+
156
+ ## block 命名规则
157
+
158
+ 常见但不是绝对:
159
+
160
+ - 查询条件:`inqu_status`
161
+ - 业务表单:`inqu`
162
+ - 表格结果:`result`
163
+ - 表格过滤:`${tableId}_filter`
164
+ - 表格自身分页 attr block:`tableId`,例如 `result`
165
+
166
+ 优先级:接口文档或同服务真实页面 > 当前模块相邻页面 > 组件默认约定。
167
+
168
+ ## 直接 HTTP
169
+
170
+ 项目里也存在 `http.get`、`http.post`、`http.form`,但 `VxePlusTable` 主路径是 EiInfo。只有当前模块已有 REST 写法,或接口明确是 REST 时,才用普通 HTTP。