@agile-team/wl-skills-kit 2.3.3 → 2.3.5

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 (91) hide show
  1. package/CHANGELOG.md +24 -23
  2. package/README.md +15 -146
  3. package/files/.cursor/mcp.json +8 -0
  4. package/files/.github/guides/README.md +13 -13
  5. package/files/.github/guides/architecture.md +555 -555
  6. package/files/.github/guides/mcp-setup.md +109 -0
  7. package/files/.github/guides/usage.md +184 -176
  8. package/files/.github/reports/README.md +65 -65
  9. package/files/.github/reports/SYS_DICT_INFO.md +50 -50
  10. package/files/.github/reports/SYS_MENU_INFO.md +247 -247
  11. package/files/.github/reports/SYS_PERMISSION_INFO.md +20 -20
  12. package/files/.github/reports//347/273/204/344/273/266/346/217/220/345/217/226/345/273/272/350/256/256.md +33 -33
  13. package/files/.github/reports//350/247/204/350/214/203/345/256/241/346/237/245/346/212/245/345/221/212.md +44 -44
  14. package/files/.github/skills/_compat/README.md +108 -108
  15. package/files/.github/skills/_compat/editors.json +7 -0
  16. package/files/.github/skills/_compat/headers/agents.txt +8 -8
  17. package/files/.github/skills/_compat/headers/claude-code.txt +7 -7
  18. package/files/.github/skills/_compat/headers/cline.txt +7 -7
  19. package/files/.github/skills/_compat/headers/cursor-mdc.txt +16 -16
  20. package/files/.github/skills/_compat/headers/cursor-rules.txt +7 -7
  21. package/files/.github/skills/_compat/headers/github-copilot.txt +1 -1
  22. package/files/.github/skills/_compat/headers/kiro.txt +10 -10
  23. package/files/.github/skills/_compat/headers/qoder.txt +8 -0
  24. package/files/.github/skills/_compat/headers/trae.txt +11 -11
  25. package/files/.github/skills/_compat/headers/windsurf.txt +7 -7
  26. package/files/.github/skills/_registry.md +81 -81
  27. package/files/.github/skills/core/api-contract/SKILL.md +344 -344
  28. package/files/.github/skills/core/api-contract/USAGE.md +110 -110
  29. package/files/.github/skills/core/convention-audit/SKILL.md +189 -189
  30. package/files/.github/skills/core/convention-audit/USAGE.md +99 -99
  31. package/files/.github/skills/core/page-codegen/SKILL.md +973 -973
  32. package/files/.github/skills/core/page-codegen/USAGE.md +102 -102
  33. package/files/.github/skills/core/page-codegen/templates/_index.md +46 -46
  34. package/files/.github/skills/core/page-codegen/templates/domains/_CONTRIBUTING.md +107 -107
  35. package/files/.github/skills/core/page-codegen/templates/domains/produce/TPL-OPERATION-STATION.md +442 -442
  36. package/files/.github/skills/core/page-codegen/templates/domains/sale/README.md +26 -26
  37. package/files/.github/skills/core/page-codegen/templates/universal/TPL-CHANGE-HISTORY.md +276 -276
  38. package/files/.github/skills/core/page-codegen/templates/universal/TPL-DETAIL-TABS.md +1145 -1145
  39. package/files/.github/skills/core/page-codegen/templates/universal/TPL-DRIVEN.md +309 -309
  40. package/files/.github/skills/core/page-codegen/templates/universal/TPL-FORM-ROUTE.md +436 -436
  41. package/files/.github/skills/core/page-codegen/templates/universal/TPL-LIST.md +191 -191
  42. package/files/.github/skills/core/page-codegen/templates/universal/TPL-MASTER-DETAIL.md +148 -148
  43. package/files/.github/skills/core/page-codegen/templates/universal/TPL-RECORD-FORM.md +376 -376
  44. package/files/.github/skills/core/page-codegen/templates/universal/TPL-TREE-LIST.md +186 -186
  45. package/files/.github/skills/core/prototype-scan/SKILL.md +498 -498
  46. package/files/.github/skills/core/prototype-scan/USAGE.md +95 -95
  47. package/files/.github/skills/core/template-extract/SKILL.md +139 -139
  48. package/files/.github/skills/core/template-extract/USAGE.md +93 -93
  49. package/files/.github/skills/domain/README.md +51 -51
  50. package/files/.github/skills/sync/menu-sync/SKILL.md +263 -263
  51. package/files/.github/skills/sync/menu-sync/USAGE.md +104 -104
  52. package/files/.github/skills/sync/menu-sync/env/env.local.json +7 -7
  53. package/files/.github/skills/sync/menu-sync/env/guide.md +99 -99
  54. package/files/.github/skills/sync/permission-sync/SKILL.draft.md +91 -91
  55. package/files/.github/standards/01-toolchain.md +57 -57
  56. package/files/.github/standards/02-code-structure.md +111 -111
  57. package/files/.github/standards/03-comments.md +53 -53
  58. package/files/.github/standards/04-coding-basics.md +33 -33
  59. package/files/.github/standards/05-logging.md +38 -38
  60. package/files/.github/standards/06-security.md +44 -44
  61. package/files/.github/standards/07-config.md +52 -52
  62. package/files/.github/standards/08-git.md +60 -60
  63. package/files/.github/standards/09-typescript.md +71 -71
  64. package/files/.github/standards/10-pinia.md +57 -57
  65. package/files/.github/standards/11-form-validation.md +81 -81
  66. package/files/.github/standards/12-base-table.md +153 -153
  67. package/files/.github/standards/13-platform-components.md +123 -123
  68. package/files/.github/standards/index.md +89 -89
  69. package/files/.kiro/settings/mcp.json +8 -0
  70. package/files/.mcp.json +8 -0
  71. package/files/.vscode/mcp.json +9 -0
  72. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/data.ts +196 -196
  73. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.scss +150 -150
  74. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.vue +79 -79
  75. package/files/docs/jh-date-range.md +257 -257
  76. package/files/docs/jh-date.md +222 -222
  77. package/files/docs/jh-dept-picker.md +190 -190
  78. package/files/docs/jh-drag-row.md +590 -590
  79. package/files/docs/jh-file-upload.md +216 -216
  80. package/files/docs/jh-picker.md +218 -218
  81. package/files/docs/jh-select.md +148 -148
  82. package/files/docs/jh-text.md +248 -248
  83. package/files/docs/jh-user-picker.md +197 -197
  84. package/files/src/components/global/C_RightToolbar/data.ts +228 -228
  85. package/files/src/components/global/C_RightToolbar/index.scss +44 -44
  86. package/files/src/components/global/C_Splitter/index.scss +61 -61
  87. package/files/src/components/global/C_SvgIcon/index.scss +15 -15
  88. package/files/src/components/global/C_TagStatus/index.scss +20 -20
  89. package/files/src/components/global/C_Tree/data.ts +61 -61
  90. package/files/src/components/local/c_listModal/index.scss +4 -4
  91. package/package.json +1 -1
@@ -2,195 +2,195 @@
2
2
 
3
3
  > 见 SKILL.md 主文件(约束 + 按钮规则 + Mock 规范等共用规则)。
4
4
 
5
-
6
- #### data.ts
7
-
8
- ```typescript
9
- // 实际项目中统一从桶文件导入(src/types/page.ts)
10
- import {
11
- AbstractPageQueryHook,
12
- BaseQueryItemDesc,
13
- ActionButtonDesc,
14
- TableColumnDesc,
15
- BusLogicDataType
16
- } from "@/types/page";
17
- import { getAction, postAction } from "@jhlc/common-core/src/api/action";
18
-
19
- export const API_CONFIG = {
20
- list: "/[服务缩写]/[资源名]/list",
21
- remove: "/[服务缩写]/[资源名]/remove",
22
- getById: "/[服务缩写]/[资源名]/getById",
23
- save: "/[服务缩写]/[资源名]/save",
24
- update: "/[服务缩写]/[资源名]/update",
25
- export: "/[服务缩写]/[资源名]/export"
26
- } as const;
27
-
28
- /** 静态下拉选项(无字典 code 时在前端定义) */
29
- const OPTS = {
30
- [optionKey]: [
31
- { label: "选项1", value: "value1" },
32
- { label: "选项2", value: "value2" }
33
- ]
34
- };
35
-
36
- export function createPage(editModalRef?: any) {
37
- let Page = new (class extends AbstractPageQueryHook {
38
- constructor() {
39
- super({ url: { list: API_CONFIG.list, remove: API_CONFIG.remove } });
40
- }
41
-
42
- queryDef(): BaseQueryItemDesc<any>[] {
43
- return [
44
- // 普通输入框
45
- {
46
- name: "[fieldName]",
47
- label: "[中文名]",
48
- placeholder: "请输入[中文名]"
49
- },
50
- // 字典下拉(后端字典表)
51
- {
52
- name: "[statusField]",
53
- label: "[状态名]",
54
- placeholder: "请选择",
55
- logicType: BusLogicDataType.dict,
56
- logicValue: "[dictCode]"
57
- },
58
- // 静态下拉(前端定义选项,无字典 code 时使用)
59
- {
60
- name: "[selectField]",
61
- label: "[下拉名]",
62
- component: () => ({ tag: "jh-select", items: OPTS.[optionKey] })
63
- },
64
- // 日期范围(需要 startName/endName)
65
- {
66
- name: "[dateField]",
67
- startName: "[startDate]",
68
- endName: "[endDate]",
69
- label: "[日期名]",
70
- placeholder: "请选择",
71
- component: () => ({
72
- tag: "jh-date",
73
- type: "daterange",
74
- rangeSeparator: "至",
75
- showFormat: "YYYY-MM-DD",
76
- valueFormat: "YYYY-MM-DD"
77
- })
78
- }
79
- ];
80
- }
81
-
82
- toolbarDef(): ActionButtonDesc[] {
83
- return [
84
- // name 决定按钮颜色:primary=蓝底, danger=红色, warning=橙色; plain=true 为线框风格
85
- // 按钮顺序必须与 page-spec toolbar 数组顺序严格一致
86
- {
87
- name: "primary",
88
- label: "新增",
89
- plain: true,
90
- onClick: () => editModalRef?.value?.open()
91
- }
92
- ];
93
- }
94
-
95
- columnsDef(): TableColumnDesc<any>[] {
96
- return [
97
- { type: "selection" },
98
- { type: "index" },
99
- // 普通列
100
- {
101
- label: "[列名]",
102
- name: "[fieldName]",
103
- minWidth: 120,
104
- sortable: true,
105
- filterable: true
106
- },
107
- // 字典列(自动翻译)
108
- {
109
- label: "[状态名]",
110
- name: "[statusField]",
111
- minWidth: 120,
112
- logicType: BusLogicDataType.dict,
113
- logicValue: "[dictCode]",
114
- sortable: true,
115
- filterable: true
116
- },
117
- // 操作列(如需要行内编辑/删除按钮)
118
- {
119
- label: "操作",
120
- width: 150,
121
- fixed: "right",
122
- operations: [
123
- {
124
- name: "edit",
125
- label: "编辑",
126
- onClick: (row: any) => editModalRef?.value?.open(row.id)
127
- },
128
- {
129
- name: "remove",
130
- label: "删除",
131
- onClick: (row: any) => this.remove(row.id)
132
- }
133
- ]
134
- }
135
- ];
136
- }
137
- })();
138
-
139
- return (Page as any).create() as any;
140
- }
141
- ```
142
-
143
- #### index.vue
144
-
145
- ```vue
146
- <template>
147
- <div class="app-container app-page-container">
148
- <BaseQuery
149
- :form="queryParam"
150
- :items="queryItems"
151
- @select="select"
152
- @reset="select"
153
- />
154
- <BaseToolbar :items="toolbars" />
155
- <BaseTable ref="tableRef" :data="list" :columns="columns" showToolbar />
156
- <jh-pagination
157
- v-show="page.total && page.total > 0"
158
- :total="page.total || 0"
159
- v-model:currentPage="page.current"
160
- v-model:pageSize="page.size"
161
- @current-change="select"
162
- @size-change="select"
163
- />
164
- </div>
165
- </template>
166
-
167
- <script setup lang="ts">
168
- import { createPage } from "./data";
169
-
170
- const Page = createPage();
171
- const {
172
- tableRef,
173
- page,
174
- queryParam,
175
- list,
176
- queryItems,
177
- columns,
178
- toolbars,
179
- select
180
- } = Page;
181
-
182
- onMounted(() => select());
183
- </script>
184
-
185
- <style scoped lang="scss">
186
- @import "./index.scss";
187
- </style>
188
- ```
189
-
190
- #### index.scss
191
-
192
- ```scss
193
- // 页面特有样式(无特殊需求可留空)
194
- ```
195
-
5
+
6
+ #### data.ts
7
+
8
+ ```typescript
9
+ // 实际项目中统一从桶文件导入(src/types/page.ts)
10
+ import {
11
+ AbstractPageQueryHook,
12
+ BaseQueryItemDesc,
13
+ ActionButtonDesc,
14
+ TableColumnDesc,
15
+ BusLogicDataType
16
+ } from "@/types/page";
17
+ import { getAction, postAction } from "@jhlc/common-core/src/api/action";
18
+
19
+ export const API_CONFIG = {
20
+ list: "/[服务缩写]/[资源名]/list",
21
+ remove: "/[服务缩写]/[资源名]/remove",
22
+ getById: "/[服务缩写]/[资源名]/getById",
23
+ save: "/[服务缩写]/[资源名]/save",
24
+ update: "/[服务缩写]/[资源名]/update",
25
+ export: "/[服务缩写]/[资源名]/export"
26
+ } as const;
27
+
28
+ /** 静态下拉选项(无字典 code 时在前端定义) */
29
+ const OPTS = {
30
+ [optionKey]: [
31
+ { label: "选项1", value: "value1" },
32
+ { label: "选项2", value: "value2" }
33
+ ]
34
+ };
35
+
36
+ export function createPage(editModalRef?: any) {
37
+ let Page = new (class extends AbstractPageQueryHook {
38
+ constructor() {
39
+ super({ url: { list: API_CONFIG.list, remove: API_CONFIG.remove } });
40
+ }
41
+
42
+ queryDef(): BaseQueryItemDesc<any>[] {
43
+ return [
44
+ // 普通输入框
45
+ {
46
+ name: "[fieldName]",
47
+ label: "[中文名]",
48
+ placeholder: "请输入[中文名]"
49
+ },
50
+ // 字典下拉(后端字典表)
51
+ {
52
+ name: "[statusField]",
53
+ label: "[状态名]",
54
+ placeholder: "请选择",
55
+ logicType: BusLogicDataType.dict,
56
+ logicValue: "[dictCode]"
57
+ },
58
+ // 静态下拉(前端定义选项,无字典 code 时使用)
59
+ {
60
+ name: "[selectField]",
61
+ label: "[下拉名]",
62
+ component: () => ({ tag: "jh-select", items: OPTS.[optionKey] })
63
+ },
64
+ // 日期范围(需要 startName/endName)
65
+ {
66
+ name: "[dateField]",
67
+ startName: "[startDate]",
68
+ endName: "[endDate]",
69
+ label: "[日期名]",
70
+ placeholder: "请选择",
71
+ component: () => ({
72
+ tag: "jh-date",
73
+ type: "daterange",
74
+ rangeSeparator: "至",
75
+ showFormat: "YYYY-MM-DD",
76
+ valueFormat: "YYYY-MM-DD"
77
+ })
78
+ }
79
+ ];
80
+ }
81
+
82
+ toolbarDef(): ActionButtonDesc[] {
83
+ return [
84
+ // name 决定按钮颜色:primary=蓝底, danger=红色, warning=橙色; plain=true 为线框风格
85
+ // 按钮顺序必须与 page-spec toolbar 数组顺序严格一致
86
+ {
87
+ name: "primary",
88
+ label: "新增",
89
+ plain: true,
90
+ onClick: () => editModalRef?.value?.open()
91
+ }
92
+ ];
93
+ }
94
+
95
+ columnsDef(): TableColumnDesc<any>[] {
96
+ return [
97
+ { type: "selection" },
98
+ { type: "index" },
99
+ // 普通列
100
+ {
101
+ label: "[列名]",
102
+ name: "[fieldName]",
103
+ minWidth: 120,
104
+ sortable: true,
105
+ filterable: true
106
+ },
107
+ // 字典列(自动翻译)
108
+ {
109
+ label: "[状态名]",
110
+ name: "[statusField]",
111
+ minWidth: 120,
112
+ logicType: BusLogicDataType.dict,
113
+ logicValue: "[dictCode]",
114
+ sortable: true,
115
+ filterable: true
116
+ },
117
+ // 操作列(如需要行内编辑/删除按钮)
118
+ {
119
+ label: "操作",
120
+ width: 150,
121
+ fixed: "right",
122
+ operations: [
123
+ {
124
+ name: "edit",
125
+ label: "编辑",
126
+ onClick: (row: any) => editModalRef?.value?.open(row.id)
127
+ },
128
+ {
129
+ name: "remove",
130
+ label: "删除",
131
+ onClick: (row: any) => this.remove(row.id)
132
+ }
133
+ ]
134
+ }
135
+ ];
136
+ }
137
+ })();
138
+
139
+ return (Page as any).create() as any;
140
+ }
141
+ ```
142
+
143
+ #### index.vue
144
+
145
+ ```vue
146
+ <template>
147
+ <div class="app-container app-page-container">
148
+ <BaseQuery
149
+ :form="queryParam"
150
+ :items="queryItems"
151
+ @select="select"
152
+ @reset="select"
153
+ />
154
+ <BaseToolbar :items="toolbars" />
155
+ <BaseTable ref="tableRef" :data="list" :columns="columns" showToolbar />
156
+ <jh-pagination
157
+ v-show="page.total && page.total > 0"
158
+ :total="page.total || 0"
159
+ v-model:currentPage="page.current"
160
+ v-model:pageSize="page.size"
161
+ @current-change="select"
162
+ @size-change="select"
163
+ />
164
+ </div>
165
+ </template>
166
+
167
+ <script setup lang="ts">
168
+ import { createPage } from "./data";
169
+
170
+ const Page = createPage();
171
+ const {
172
+ tableRef,
173
+ page,
174
+ queryParam,
175
+ list,
176
+ queryItems,
177
+ columns,
178
+ toolbars,
179
+ select
180
+ } = Page;
181
+
182
+ onMounted(() => select());
183
+ </script>
184
+
185
+ <style scoped lang="scss">
186
+ @import "./index.scss";
187
+ </style>
188
+ ```
189
+
190
+ #### index.scss
191
+
192
+ ```scss
193
+ // 页面特有样式(无特殊需求可留空)
194
+ ```
195
+
196
196
  ---
@@ -2,152 +2,152 @@
2
2
 
3
3
  > 见 SKILL.md 主文件(约束 + 按钮规则 + Mock 规范等共用规则)。
4
4
 
5
-
6
- #### data.ts(额外部分)
7
-
8
- 在标准 createPage 基础上,增加 createBottomPage:
9
-
10
- ```typescript
11
- // ... 同模板 A 的 imports 和 API_CONFIG(增加从表相关 URL)
12
- export const API_CONFIG = {
13
- list: "/[服务缩写]/[主资源]/list",
14
- remove: "/[服务缩写]/[主资源]/remove",
15
- // ...标准 CRUD
16
- bottomList: "/[服务缩写]/[从资源]/list" // 从表查询
17
- } as const;
18
-
19
- export function createPage(/* refs */) {
20
- // ... 主表同模板 A
21
- }
22
-
23
- // 双击主表行 → 加载从表数据
24
- export function handleRowDblclick(
25
- row: any,
26
- bottomSelect: Function,
27
- BottomPage: any
28
- ) {
29
- BottomPage.queryParam.value.mainId = row.id;
30
- BottomPage.tableRef.value.loading();
31
- getAction(API_CONFIG.bottomList, BottomPage.queryParam.value)
32
- .then((res) => {
33
- BottomPage.list.value = res.data;
34
- BottomPage.tableRef.value.clearSelection();
35
- })
36
- .finally(() => {
37
- BottomPage.tableRef.value.closeLoading();
38
- });
39
- }
40
-
41
- // 从表 Hook
42
- export function createBottomPage() {
43
- let Page = new (class extends AbstractPageQueryHook {
44
- constructor() {
45
- super({ url: { list: API_CONFIG.bottomList } });
46
- }
47
- queryDef(): BaseQueryItemDesc<any>[] {
48
- return [];
49
- }
50
- toolbarDef(): ActionButtonDesc[] {
51
- return [];
52
- }
53
- columnsDef(): TableColumnDesc<any>[] {
54
- return [
55
- { type: "index" }
56
- // 从表字段
57
- ];
58
- }
59
- })();
60
- return (Page as any).create() as any;
61
- }
62
- ```
63
-
64
- #### index.vue
65
-
66
- ```vue
67
- <template>
68
- <div class="app-container app-page-container">
69
- <jh-drag-row :top-height="350">
70
- <template #top>
71
- <BaseQuery
72
- :form="queryParam"
73
- :items="queryItems"
74
- @select="select"
75
- @reset="select"
76
- />
77
- <BaseToolbar :items="toolbars" />
78
- <BaseTable
79
- ref="tableRef"
80
- :data="list"
81
- :columns="columns"
82
- showToolbar
83
- @row-dblclick="
84
- (row) => handleRowDblclick(row, bottomSelect, BottomPage)
85
- "
86
- />
87
- <jh-pagination
88
- v-show="page.total && page.total > 0"
89
- :total="page.total || 0"
90
- v-model:currentPage="page.current"
91
- v-model:pageSize="page.size"
92
- @current-change="select"
93
- @size-change="select"
94
- />
95
- </template>
96
- <template #bottom>
97
- <BaseToolbar :items="bottomToolbars" />
98
- <BaseTable
99
- ref="bottomTableRef"
100
- :data="bottomList"
101
- :columns="bottomColumns"
102
- showToolbar
103
- />
104
- </template>
105
- </jh-drag-row>
106
- </div>
107
- </template>
108
-
109
- <script setup lang="ts">
110
- import { createPage, createBottomPage, handleRowDblclick } from "./data";
111
-
112
- const Page = createPage();
113
- const {
114
- tableRef,
115
- page,
116
- queryParam,
117
- list,
118
- queryItems,
119
- columns,
120
- toolbars,
121
- select
122
- } = Page;
123
-
124
- const BottomPage = createBottomPage();
125
- const {
126
- tableRef: bottomTableRef,
127
- list: bottomList,
128
- columns: bottomColumns,
129
- select: bottomSelect,
130
- toolbars: bottomToolbars
131
- } = BottomPage;
132
-
133
- onMounted(() => select());
134
- </script>
135
-
136
- <style scoped lang="scss">
137
- @import "./index.scss";
138
- </style>
139
- ```
140
-
141
- #### index.scss
142
-
143
- ```scss
144
- .app-page-container .drager_row {
145
- height: 100%;
146
- }
147
-
148
- .base-toolbar-box {
149
- margin-bottom: 4px;
150
- }
151
- ```
152
-
5
+
6
+ #### data.ts(额外部分)
7
+
8
+ 在标准 createPage 基础上,增加 createBottomPage:
9
+
10
+ ```typescript
11
+ // ... 同模板 A 的 imports 和 API_CONFIG(增加从表相关 URL)
12
+ export const API_CONFIG = {
13
+ list: "/[服务缩写]/[主资源]/list",
14
+ remove: "/[服务缩写]/[主资源]/remove",
15
+ // ...标准 CRUD
16
+ bottomList: "/[服务缩写]/[从资源]/list" // 从表查询
17
+ } as const;
18
+
19
+ export function createPage(/* refs */) {
20
+ // ... 主表同模板 A
21
+ }
22
+
23
+ // 双击主表行 → 加载从表数据
24
+ export function handleRowDblclick(
25
+ row: any,
26
+ bottomSelect: Function,
27
+ BottomPage: any
28
+ ) {
29
+ BottomPage.queryParam.value.mainId = row.id;
30
+ BottomPage.tableRef.value.loading();
31
+ getAction(API_CONFIG.bottomList, BottomPage.queryParam.value)
32
+ .then((res) => {
33
+ BottomPage.list.value = res.data;
34
+ BottomPage.tableRef.value.clearSelection();
35
+ })
36
+ .finally(() => {
37
+ BottomPage.tableRef.value.closeLoading();
38
+ });
39
+ }
40
+
41
+ // 从表 Hook
42
+ export function createBottomPage() {
43
+ let Page = new (class extends AbstractPageQueryHook {
44
+ constructor() {
45
+ super({ url: { list: API_CONFIG.bottomList } });
46
+ }
47
+ queryDef(): BaseQueryItemDesc<any>[] {
48
+ return [];
49
+ }
50
+ toolbarDef(): ActionButtonDesc[] {
51
+ return [];
52
+ }
53
+ columnsDef(): TableColumnDesc<any>[] {
54
+ return [
55
+ { type: "index" }
56
+ // 从表字段
57
+ ];
58
+ }
59
+ })();
60
+ return (Page as any).create() as any;
61
+ }
62
+ ```
63
+
64
+ #### index.vue
65
+
66
+ ```vue
67
+ <template>
68
+ <div class="app-container app-page-container">
69
+ <jh-drag-row :top-height="350">
70
+ <template #top>
71
+ <BaseQuery
72
+ :form="queryParam"
73
+ :items="queryItems"
74
+ @select="select"
75
+ @reset="select"
76
+ />
77
+ <BaseToolbar :items="toolbars" />
78
+ <BaseTable
79
+ ref="tableRef"
80
+ :data="list"
81
+ :columns="columns"
82
+ showToolbar
83
+ @row-dblclick="
84
+ (row) => handleRowDblclick(row, bottomSelect, BottomPage)
85
+ "
86
+ />
87
+ <jh-pagination
88
+ v-show="page.total && page.total > 0"
89
+ :total="page.total || 0"
90
+ v-model:currentPage="page.current"
91
+ v-model:pageSize="page.size"
92
+ @current-change="select"
93
+ @size-change="select"
94
+ />
95
+ </template>
96
+ <template #bottom>
97
+ <BaseToolbar :items="bottomToolbars" />
98
+ <BaseTable
99
+ ref="bottomTableRef"
100
+ :data="bottomList"
101
+ :columns="bottomColumns"
102
+ showToolbar
103
+ />
104
+ </template>
105
+ </jh-drag-row>
106
+ </div>
107
+ </template>
108
+
109
+ <script setup lang="ts">
110
+ import { createPage, createBottomPage, handleRowDblclick } from "./data";
111
+
112
+ const Page = createPage();
113
+ const {
114
+ tableRef,
115
+ page,
116
+ queryParam,
117
+ list,
118
+ queryItems,
119
+ columns,
120
+ toolbars,
121
+ select
122
+ } = Page;
123
+
124
+ const BottomPage = createBottomPage();
125
+ const {
126
+ tableRef: bottomTableRef,
127
+ list: bottomList,
128
+ columns: bottomColumns,
129
+ select: bottomSelect,
130
+ toolbars: bottomToolbars
131
+ } = BottomPage;
132
+
133
+ onMounted(() => select());
134
+ </script>
135
+
136
+ <style scoped lang="scss">
137
+ @import "./index.scss";
138
+ </style>
139
+ ```
140
+
141
+ #### index.scss
142
+
143
+ ```scss
144
+ .app-page-container .drager_row {
145
+ height: 100%;
146
+ }
147
+
148
+ .base-toolbar-box {
149
+ margin-bottom: 4px;
150
+ }
151
+ ```
152
+
153
153
  ---