worsoft-frontend-codegen-local-mcp 0.1.28 → 0.1.32
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/MVP_DESIGN.md +36 -19
- package/README.md +38 -6
- package/assets/templates/master_child_jump/index.tpl +144 -74
- package/assets/templates/master_child_jump/options.tpl +1 -0
- package/assets/templates/single_table_dialog/index.tpl +142 -74
- package/assets/templates/single_table_dialog/options.tpl +1 -0
- package/assets/templates/single_table_jump/index.tpl +141 -84
- package/assets/templates/single_table_jump/options.tpl +1 -0
- package/mcp_server.js +498 -283
- package/package.json +1 -1
package/MVP_DESIGN.md
CHANGED
|
@@ -4,40 +4,43 @@
|
|
|
4
4
|
|
|
5
5
|
Build a local MCP plugin that generates frontend files from:
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- local
|
|
9
|
-
- style-based
|
|
7
|
+
- structured feature metadata
|
|
8
|
+
- local runtime templates
|
|
9
|
+
- style-based rendering rules
|
|
10
10
|
|
|
11
|
-
without depending on the Worsoft backend generation API
|
|
11
|
+
without depending on the Worsoft backend generation API.
|
|
12
12
|
|
|
13
13
|
## Current Supported Flow
|
|
14
14
|
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
15
|
+
1. Upstream caller parses PRD, API docs, or any other source
|
|
16
|
+
2. Upstream caller builds structured JSON metadata
|
|
17
17
|
3. MCP receives:
|
|
18
18
|
- main table metadata
|
|
19
19
|
- child table metadata
|
|
20
20
|
- explicit `payloadField`
|
|
21
|
+
- explicit `levels[]`
|
|
21
22
|
- field arrays
|
|
22
23
|
4. MCP loads style metadata from `assets/style-catalog.json`
|
|
23
|
-
5. MCP
|
|
24
|
-
6. MCP
|
|
25
|
-
7. MCP
|
|
26
|
-
8. MCP
|
|
27
|
-
9. MCP
|
|
28
|
-
10. MCP optionally writes files
|
|
24
|
+
5. MCP builds a normalized runtime model
|
|
25
|
+
6. MCP maps structured fields into frontend field types
|
|
26
|
+
7. MCP renders runtime templates
|
|
27
|
+
8. MCP returns a render manifest
|
|
28
|
+
9. MCP optionally writes files
|
|
29
|
+
10. MCP optionally writes support files and optionally merges `zh-cn.ts`
|
|
29
30
|
|
|
30
31
|
## Declared Styles
|
|
31
32
|
|
|
32
33
|
- `single_table_jump`
|
|
33
34
|
- `single_table_dialog`
|
|
34
35
|
- `master_child_jump`
|
|
36
|
+
- `multi_level_dict`
|
|
35
37
|
|
|
36
38
|
## Runtime-Implemented Styles
|
|
37
39
|
|
|
38
40
|
- `single_table_jump`
|
|
39
41
|
- `single_table_dialog`
|
|
40
42
|
- `master_child_jump`
|
|
43
|
+
- `multi_level_dict`
|
|
41
44
|
|
|
42
45
|
## Metadata Model
|
|
43
46
|
|
|
@@ -76,22 +79,36 @@ without depending on the Worsoft backend generation API
|
|
|
76
79
|
}
|
|
77
80
|
```
|
|
78
81
|
|
|
79
|
-
##
|
|
82
|
+
## Contracts
|
|
80
83
|
|
|
81
|
-
|
|
84
|
+
### master_child_jump
|
|
82
85
|
|
|
83
86
|
- MCP never infers child relations
|
|
84
87
|
- caller must always pass explicit `children[]`
|
|
85
88
|
- `payloadField` is the only child list truth
|
|
86
89
|
|
|
90
|
+
### multi_level_dict
|
|
91
|
+
|
|
92
|
+
- MCP never infers level hierarchy
|
|
93
|
+
- caller must always pass explicit `levels[]`
|
|
94
|
+
- non-root modules must provide `queryParentField`
|
|
95
|
+
|
|
96
|
+
### side effects
|
|
97
|
+
|
|
98
|
+
- `writeSupportFiles=true` keeps project helper writes enabled
|
|
99
|
+
- `writeSupportFiles=false` turns MCP into a render-only generator for support files
|
|
100
|
+
- `mergeI18nZh=true` keeps existing Chinese locale merge behavior
|
|
101
|
+
- `mergeI18nZh=false` makes zh-cn output source-of-truth from current metadata only
|
|
102
|
+
|
|
87
103
|
## Risks
|
|
88
104
|
|
|
89
|
-
- Quality
|
|
90
|
-
- If
|
|
91
|
-
- Query/list/form metadata
|
|
105
|
+
- Quality depends on upstream structured metadata quality
|
|
106
|
+
- If upstream metadata omits structure or dict codes, caller must stop and report the gap
|
|
107
|
+
- Query/list/form metadata normalization still contains heuristics for widths and default controls
|
|
92
108
|
|
|
93
109
|
## Next Steps
|
|
94
110
|
|
|
95
|
-
1.
|
|
111
|
+
1. Keep the MCP contract source-agnostic and JSON-only
|
|
96
112
|
2. Expand structured validation for field completeness
|
|
97
|
-
3. Keep
|
|
113
|
+
3. Keep render behavior aligned with the structured metadata contract
|
|
114
|
+
4. Continue reducing project-specific side effects so MCP focuses on validate, render, and optional write
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Worsoft Frontend Codegen Local MCP
|
|
2
2
|
|
|
3
|
-
This MCP generates Worsoft frontend files from
|
|
3
|
+
This MCP generates Worsoft frontend files from structured JSON metadata.
|
|
4
4
|
|
|
5
5
|
## Scope
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- structured JSON input
|
|
8
8
|
- style-based template selection
|
|
9
9
|
- local template rendering
|
|
10
10
|
- single-table runtime generation
|
|
@@ -20,10 +20,13 @@ This MCP generates Worsoft frontend files from API-first structured metadata.
|
|
|
20
20
|
- `style`
|
|
21
21
|
- `fields`
|
|
22
22
|
- `children`
|
|
23
|
+
- `levels`
|
|
23
24
|
- `frontendPath`
|
|
24
25
|
- `moduleName`
|
|
25
26
|
- `writeToDisk`
|
|
26
27
|
- `overwrite`
|
|
28
|
+
- `writeSupportFiles`
|
|
29
|
+
- `mergeI18nZh`
|
|
27
30
|
|
|
28
31
|
## Recommended MCP Arguments
|
|
29
32
|
|
|
@@ -88,6 +91,7 @@ PowerShell:
|
|
|
88
91
|
|
|
89
92
|
```powershell
|
|
90
93
|
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario single
|
|
94
|
+
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario single_dialog
|
|
91
95
|
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario master
|
|
92
96
|
powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario multi
|
|
93
97
|
```
|
|
@@ -96,8 +100,9 @@ Node:
|
|
|
96
100
|
|
|
97
101
|
```bash
|
|
98
102
|
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario single
|
|
103
|
+
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario single_dialog
|
|
99
104
|
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario master
|
|
100
|
-
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario
|
|
105
|
+
node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario dict_multi
|
|
101
106
|
```
|
|
102
107
|
|
|
103
108
|
Optional overrides:
|
|
@@ -110,6 +115,17 @@ Optional overrides:
|
|
|
110
115
|
- `--frontend-path`
|
|
111
116
|
- `--write-to-disk`
|
|
112
117
|
|
|
118
|
+
## Side-Effect Controls
|
|
119
|
+
|
|
120
|
+
- `writeSupportFiles=true`:
|
|
121
|
+
MCP may write `src/enums/dict-registry.ts` and `src/utils/crudSchema.ts`
|
|
122
|
+
- `writeSupportFiles=false`:
|
|
123
|
+
MCP does not write support files. Generated code still expects those helpers to already exist in the target project
|
|
124
|
+
- `mergeI18nZh=true`:
|
|
125
|
+
MCP reads an existing `zh-cn.ts` and merges missing keys
|
|
126
|
+
- `mergeI18nZh=false`:
|
|
127
|
+
MCP renders `zh-cn.ts` from current metadata only and does not parse the existing file
|
|
128
|
+
|
|
113
129
|
## Master-Child Contract
|
|
114
130
|
|
|
115
131
|
For `master_child_jump`, MCP does not infer relations.
|
|
@@ -125,6 +141,21 @@ The caller must provide explicit `children[]`, and each child must include:
|
|
|
125
141
|
|
|
126
142
|
If these fields are missing, MCP returns a structured validation error.
|
|
127
143
|
|
|
144
|
+
## Multi-Level Dictionary Contract
|
|
145
|
+
|
|
146
|
+
For `multi_level_dict`, MCP does not infer hierarchy.
|
|
147
|
+
|
|
148
|
+
The caller must provide explicit `levels[]`. Each level must include:
|
|
149
|
+
|
|
150
|
+
- `levelIndex`
|
|
151
|
+
- `modules`
|
|
152
|
+
|
|
153
|
+
Each module must include:
|
|
154
|
+
|
|
155
|
+
- `tableName`
|
|
156
|
+
- `apiPath`
|
|
157
|
+
- `fields`
|
|
158
|
+
|
|
128
159
|
## Current Outputs
|
|
129
160
|
|
|
130
161
|
- `src/views/<module>/<function>/index.vue`
|
|
@@ -144,13 +175,14 @@ Declared styles:
|
|
|
144
175
|
- `single_table_jump`
|
|
145
176
|
- `single_table_dialog`
|
|
146
177
|
- `master_child_jump`
|
|
178
|
+
- `multi_level_dict`
|
|
147
179
|
|
|
148
180
|
## Notes
|
|
149
181
|
|
|
150
|
-
- Shared Worsoft template references live under `../template`
|
|
151
182
|
- Plugin-local runtime assets live under `assets/templates`
|
|
152
|
-
-
|
|
153
|
-
-
|
|
183
|
+
- MCP does not parse PRD, API, Markdown, or SQL design documents
|
|
184
|
+
- Upstream caller-side skills are responsible for turning documents into structured JSON metadata
|
|
185
|
+
- Support-file writes and zh-cn merge behavior can be controlled through `writeSupportFiles` and `mergeI18nZh`
|
|
154
186
|
- Menu SQL is emitted to `frontendPath/menu/`
|
|
155
187
|
|
|
156
188
|
## IDE Guide
|
|
@@ -1,56 +1,35 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="layout-padding">
|
|
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
|
-
v-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
>
|
|
34
|
-
<template #default="scope">
|
|
35
|
-
<dict-tag v-if="column.dictType" :options="getDictOptions(column.dictType)" :value="scope.row[column.prop]" />
|
|
36
|
-
<span v-else>{{ scope.row[column.prop] }}</span>
|
|
37
|
-
</template>
|
|
38
|
-
</el-table-column>
|
|
39
|
-
<el-table-column :label="t('common.action')" width="380" fixed="right">
|
|
40
|
-
<template #default="scope">
|
|
41
|
-
<el-button text type="primary" icon="view" v-auth="'{{PERMISSION_PREFIX}}_view'" @click="handleDetail(scope.row.id)">{{ t('common.viewBtn') }}</el-button>
|
|
42
|
-
<el-button icon="edit-pen" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_edit'" @click="handleEdit(scope.row.id)">{{ t('common.editBtn') }}</el-button>
|
|
43
|
-
<el-button text type="primary" icon="check" @click="handleQuickAction(scope.row, 'submit')">{{ commonActionLabel('submit') }}</el-button>
|
|
44
|
-
<el-button text type="success" icon="position" @click="handleQuickAction(scope.row, 'flow')">{{ commonActionLabel('flow') }}</el-button>
|
|
45
|
-
<el-button icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([scope.row.id])">{{ t('common.delBtn') }}</el-button>
|
|
46
|
-
</template>
|
|
47
|
-
</el-table-column>
|
|
48
|
-
</el-table>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
<div style="flex-shrink: 0; margin-top: 10px; display: flex; justify-content: flex-end;">
|
|
52
|
-
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
|
53
|
-
</div>
|
|
3
|
+
<div class="layout-padding-auto layout-padding-view flex h-full flex-col">
|
|
4
|
+
<SchemaListToolbar
|
|
5
|
+
v-bind="toolbarProps"
|
|
6
|
+
@update:keyword="state.queryForm.smartVal = $event"
|
|
7
|
+
@add="handleToolbarAdd"
|
|
8
|
+
@import="handleToolbarImport"
|
|
9
|
+
@delete="handleToolbarDelete"
|
|
10
|
+
@query="handleToolbarQuery"
|
|
11
|
+
@reset="handleToolbarReset"
|
|
12
|
+
@custom-query-confirm="handleToolbarCustomQueryConfirm"
|
|
13
|
+
@export="handleToolbarExport"
|
|
14
|
+
@refresh="handleToolbarRefresh"
|
|
15
|
+
/>
|
|
16
|
+
|
|
17
|
+
<SchemaListTable
|
|
18
|
+
v-bind="tableProps"
|
|
19
|
+
row-id-key="{{PK_ATTR}}"
|
|
20
|
+
@selection-change="handleTableSelectionChange"
|
|
21
|
+
@sort-change="handleTableSortChange"
|
|
22
|
+
@size-change="handleTableSizeChange"
|
|
23
|
+
@current-change="handleTableCurrentChange"
|
|
24
|
+
>
|
|
25
|
+
<template #actions="{ row }">
|
|
26
|
+
<el-button text type="primary" icon="view" v-auth="'{{PERMISSION_PREFIX}}_view'" @click="handleDetail(row.{{PK_ATTR}})">{{ t('common.viewBtn') }}</el-button>
|
|
27
|
+
<el-button icon="edit-pen" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_edit'" @click="handleEdit(row.{{PK_ATTR}})">{{ t('common.editBtn') }}</el-button>
|
|
28
|
+
<el-button text type="primary" icon="check" @click="handleQuickAction(row, 'submit')">{{ commonActionLabel('submit') }}</el-button>
|
|
29
|
+
<el-button text type="success" icon="position" @click="handleQuickAction(row, 'flow')">{{ commonActionLabel('flow') }}</el-button>
|
|
30
|
+
<el-button icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([row.{{PK_ATTR}}])">{{ t('common.delBtn') }}</el-button>
|
|
31
|
+
</template>
|
|
32
|
+
</SchemaListTable>
|
|
54
33
|
</div>
|
|
55
34
|
|
|
56
35
|
<upload-excel ref="excelUploadRef" :title="t('common.importBtn')" url="/{{API_PATH}}/import" temp-url="/admin/sys-file/local/file/{{FUNCTION_NAME}}.xlsx" @refreshDataList="getDataList" />
|
|
@@ -58,52 +37,83 @@
|
|
|
58
37
|
</template>
|
|
59
38
|
|
|
60
39
|
<script setup lang="ts" name="system{{CLASS_NAME}}">
|
|
61
|
-
import { BasicTableProps, useTable } from '/@/hooks/table';
|
|
62
40
|
import { fetchList, delObjs } from '/@/api/{{API_MODULE_PATH}}';
|
|
63
41
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
|
64
42
|
import { useDict } from '/@/hooks/dict';
|
|
65
43
|
import { useCrudPageMeta } from '/@/hooks/useCrudPageMeta';
|
|
44
|
+
import { useSchemaListQuery } from '/@/hooks/useSchemaListQuery';
|
|
45
|
+
import SchemaListToolbar from '/@/components/schema-list/SchemaListToolbar.vue';
|
|
46
|
+
import SchemaListTable from '/@/components/schema-list/SchemaListTable.vue';
|
|
66
47
|
import { useI18n } from 'vue-i18n';
|
|
67
|
-
import { allDictTypes, dataMasterEntity } from './options';
|
|
48
|
+
import { allDictTypes, crudSchema, dataMasterEntity } from './options';
|
|
68
49
|
|
|
69
50
|
const dictRefs = useDict(...allDictTypes);
|
|
70
51
|
const { t } = useI18n();
|
|
71
52
|
const router = useRouter();
|
|
72
53
|
|
|
73
54
|
const excelUploadRef = ref();
|
|
74
|
-
const selectObjs = ref([])
|
|
55
|
+
const selectObjs = ref<string[]>([]);
|
|
75
56
|
const multiple = ref(true);
|
|
76
57
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
queryForm: {},
|
|
58
|
+
const { state, getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, tableStyle, exportExcel: runExportExcel, resetQueryForm } = useSchemaListQuery({
|
|
59
|
+
schema: crudSchema,
|
|
80
60
|
pageList: fetchList,
|
|
61
|
+
exportUrl: '/{{API_PATH}}/export',
|
|
62
|
+
exportFileName: '{{FUNCTION_NAME}}.xlsx',
|
|
81
63
|
});
|
|
82
64
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
65
|
+
const { resolveLabel, getDictOptions, commonActionLabel, visibleTableColumns, searchKeywordTooltip, queryableDictFields } = useCrudPageMeta(dataMasterEntity, dictRefs);
|
|
66
|
+
|
|
67
|
+
const queryableDictOptions = computed(() =>
|
|
68
|
+
queryableDictFields.value.map((field) => ({
|
|
69
|
+
...field,
|
|
70
|
+
options: getDictOptions(field.dictType),
|
|
71
|
+
}))
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const tableColumns = computed(() =>
|
|
75
|
+
visibleTableColumns.value.map((column) => ({
|
|
76
|
+
prop: column.prop,
|
|
77
|
+
label: resolveLabel(column.labelKey, column.fallbackLabel),
|
|
78
|
+
width: column.width,
|
|
79
|
+
dictType: column.dictType,
|
|
80
|
+
options: column.dictType ? getDictOptions(column.dictType) : [],
|
|
81
|
+
}))
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const toolbarProps = computed(() => ({
|
|
85
|
+
keyword: state.queryForm.smartVal,
|
|
86
|
+
searchPlaceholder: searchKeywordTooltip.value,
|
|
87
|
+
queryModel: state.queryForm,
|
|
88
|
+
customQueryFields: queryableDictOptions.value,
|
|
89
|
+
selectedIds: selectObjs.value,
|
|
90
|
+
deleteDisabled: multiple.value,
|
|
91
|
+
exportPermission: '{{PERMISSION_PREFIX}}_export',
|
|
92
|
+
}));
|
|
93
|
+
|
|
94
|
+
const tableProps = computed(() => ({
|
|
95
|
+
data: state.dataList,
|
|
96
|
+
loading: !!state.loading,
|
|
97
|
+
columns: tableColumns.value,
|
|
98
|
+
pagination: state.pagination,
|
|
99
|
+
tableStyle,
|
|
100
|
+
}));
|
|
87
101
|
|
|
88
102
|
const getFormPath = () => '/{{VIEW_MODULE_PATH}}/form';
|
|
89
103
|
|
|
90
|
-
// 进入新增页
|
|
91
104
|
const handleCreate = () => {
|
|
92
105
|
router.push({ path: getFormPath(), query: { tagsViewName: t('common.addBtn') } });
|
|
93
106
|
};
|
|
94
107
|
|
|
95
|
-
// 进入详情页
|
|
96
108
|
const handleDetail = (id: string) => {
|
|
97
109
|
router.push({ path: getFormPath(), query: { id, detail: '1', tagsViewName: t('common.viewBtn') } });
|
|
98
110
|
};
|
|
99
111
|
|
|
100
|
-
// 进入编辑页
|
|
101
112
|
const handleEdit = (id: string) => {
|
|
102
113
|
router.push({ path: getFormPath(), query: { id, tagsViewName: t('common.editBtn') } });
|
|
103
114
|
};
|
|
104
115
|
|
|
105
|
-
|
|
106
|
-
const handleQuickAction = async (row: any, actionType: string) => {
|
|
116
|
+
const handleQuickAction = async (_row: any, actionType: string) => {
|
|
107
117
|
const actionName = commonActionLabel(actionType);
|
|
108
118
|
try {
|
|
109
119
|
await useMessageBox().confirm(t('common.messages.quickActionConfirm', { action: actionName }));
|
|
@@ -113,21 +123,32 @@ const handleQuickAction = async (row: any, actionType: string) => {
|
|
|
113
123
|
: t('common.messages.quickFlowSuccess')
|
|
114
124
|
);
|
|
115
125
|
getDataList();
|
|
116
|
-
} catch {
|
|
126
|
+
} catch {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
117
129
|
};
|
|
118
130
|
|
|
119
|
-
// 导出当前查询结果
|
|
120
131
|
const exportExcel = () => {
|
|
121
|
-
|
|
132
|
+
runExportExcel(selectObjs.value);
|
|
122
133
|
};
|
|
123
134
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
const handleQueryFilterConfirm = (values: Record<string, any>) => {
|
|
136
|
+
queryableDictFields.value.forEach((field) => {
|
|
137
|
+
const nextValue = values[field.prop];
|
|
138
|
+
if (Array.isArray(nextValue) && nextValue.length) {
|
|
139
|
+
state.queryForm[field.prop] = nextValue;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
delete state.queryForm[field.prop];
|
|
143
|
+
});
|
|
144
|
+
getDataList();
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const resetQuery = () => {
|
|
148
|
+
resetQueryForm();
|
|
149
|
+
getDataList();
|
|
128
150
|
};
|
|
129
151
|
|
|
130
|
-
// 删除前先进行二次确认
|
|
131
152
|
const handleDelete = async (ids: string[]) => {
|
|
132
153
|
try {
|
|
133
154
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
|
@@ -143,4 +164,53 @@ const handleDelete = async (ids: string[]) => {
|
|
|
143
164
|
useMessage().error(err.msg || t('common.delBtn'));
|
|
144
165
|
}
|
|
145
166
|
};
|
|
167
|
+
|
|
168
|
+
const handleToolbarAdd = () => {
|
|
169
|
+
handleCreate();
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const handleToolbarImport = () => {
|
|
173
|
+
excelUploadRef.value?.show();
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const handleToolbarDelete = () => {
|
|
177
|
+
handleDelete(selectObjs.value);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const handleToolbarQuery = () => {
|
|
181
|
+
getDataList();
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const handleToolbarReset = () => {
|
|
185
|
+
resetQuery();
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const handleToolbarCustomQueryConfirm = (payload: { values: Record<string, any> }) => {
|
|
189
|
+
handleQueryFilterConfirm(payload.values);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const handleToolbarExport = () => {
|
|
193
|
+
exportExcel();
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const handleToolbarRefresh = () => {
|
|
197
|
+
getDataList();
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const handleTableSelectionChange = (payload: { ids: Array<string | number> }) => {
|
|
201
|
+
selectObjs.value = payload.ids.map((id) => String(id));
|
|
202
|
+
multiple.value = !payload.ids.length;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const handleTableSortChange = (payload: { raw: any }) => {
|
|
206
|
+
sortChangeHandle(payload.raw);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const handleTableSizeChange = (payload: { size: number }) => {
|
|
210
|
+
sizeChangeHandle(payload.size);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const handleTableCurrentChange = (payload: { current: number }) => {
|
|
214
|
+
currentChangeHandle(payload.current);
|
|
215
|
+
};
|
|
146
216
|
</script>
|
|
@@ -18,6 +18,7 @@ const definition: CrudSchemaDefinition = {
|
|
|
18
18
|
// 将页面声明转换成 index/form 统一消费的 schema 结果
|
|
19
19
|
const schema = createCrudSchema(definition);
|
|
20
20
|
|
|
21
|
+
export const crudSchema = schema;
|
|
21
22
|
// 主表字段配置,供列表页和表单页使用
|
|
22
23
|
export const dataMasterEntity = schema.master;
|
|
23
24
|
// 子表字段配置,供主子表区块读取
|