worsoft-frontend-codegen-local-mcp 0.1.70 → 0.1.72
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.
|
@@ -51,6 +51,7 @@ import { useDict } from '/@/hooks/dict';
|
|
|
51
51
|
import { useCrudPageMeta } from '/@/hooks/useCrudPageMeta';
|
|
52
52
|
// 国际化能力
|
|
53
53
|
import { useI18n } from 'vue-i18n';
|
|
54
|
+
{{BUSINESS_FORM_STATUS_IMPORTS}}
|
|
54
55
|
// 当前页面的字段配置
|
|
55
56
|
import { allDictTypes, childFieldGroups, dataMasterEntity } from './options';
|
|
56
57
|
|
|
@@ -165,7 +166,8 @@ const onSubmit = async (actionType?: string) => {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
try {
|
|
168
|
-
|
|
169
|
+
const submitData = Object.assign({}, form{{BUSINESS_SUBMIT_STATUS_ASSIGNMENT}});
|
|
170
|
+
form.{{PK_ATTR}} ? await putObj(submitData) : await addObj(submitData);
|
|
169
171
|
|
|
170
172
|
let msg = form.{{PK_ATTR}} ? t('common.editSuccessText') : t('common.addSuccessText');
|
|
171
173
|
if (actionType === 'submit') msg = t('common.messages.quickSubmitSuccess');
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<!-- 流转{{FEATURE_TITLE}} -->
|
|
38
38
|
<el-button text type="success" icon="position" @click="handleQuickAction(row, 'flow')">{{ commonActionLabel('flow') }}</el-button>
|
|
39
39
|
<!-- 删除{{FEATURE_TITLE}} -->
|
|
40
|
-
<el-button icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([row.{{PK_ATTR}}])">{{ t('common.delBtn') }}</el-button>
|
|
40
|
+
<el-button{{BUSINESS_DELETE_IF}} icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([row.{{PK_ATTR}}]{{BUSINESS_DELETE_ROW_ARG}})">{{ t('common.delBtn') }}</el-button>
|
|
41
41
|
</template>
|
|
42
42
|
</SchemaListTable>
|
|
43
43
|
</div>
|
|
@@ -80,6 +80,7 @@ const router = useRouter();
|
|
|
80
80
|
const excelUploadRef = ref();
|
|
81
81
|
// 列表勾选主键集合
|
|
82
82
|
const selectObjs = ref<string[]>([]);
|
|
83
|
+
{{BUSINESS_SELECTED_ROWS_DECLARATION}}
|
|
83
84
|
// 批量删除按钮状态
|
|
84
85
|
const multiple = ref(true);
|
|
85
86
|
|
|
@@ -120,7 +121,7 @@ const toolbarProps = computed(() => ({
|
|
|
120
121
|
queryModel: state.queryForm,
|
|
121
122
|
customQueryFields: queryableDictOptions.value,
|
|
122
123
|
selectedIds: selectObjs.value,
|
|
123
|
-
deleteDisabled: multiple.value,
|
|
124
|
+
deleteDisabled: multiple.value{{BUSINESS_DELETE_DISABLED_EXPR}},
|
|
124
125
|
exportPermission: '{{PERMISSION_PREFIX}}_export',
|
|
125
126
|
}));
|
|
126
127
|
|
|
@@ -195,7 +196,8 @@ const resetQuery = () => {
|
|
|
195
196
|
};
|
|
196
197
|
|
|
197
198
|
// 删除列表数据
|
|
198
|
-
const handleDelete = async (ids: string[]) => {
|
|
199
|
+
const handleDelete = async (ids: string[]{{BUSINESS_DELETE_ROWS_PARAM}}) => {
|
|
200
|
+
{{BUSINESS_DELETE_GUARD}}
|
|
199
201
|
try {
|
|
200
202
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
|
201
203
|
} catch {
|
|
@@ -223,7 +225,7 @@ const handleToolbarImport = () => {
|
|
|
223
225
|
|
|
224
226
|
// 工具栏批量删除事件
|
|
225
227
|
const handleToolbarDelete = () => {
|
|
226
|
-
handleDelete(selectObjs.value);
|
|
228
|
+
handleDelete(selectObjs.value{{BUSINESS_SELECTED_ROWS_ARG}});
|
|
227
229
|
};
|
|
228
230
|
|
|
229
231
|
// 工具栏查询事件
|
|
@@ -252,7 +254,8 @@ const handleToolbarRefresh = () => {
|
|
|
252
254
|
};
|
|
253
255
|
|
|
254
256
|
// 表格勾选变化事件
|
|
255
|
-
const handleTableSelectionChange = (payload: { ids: Array<string | number> }) => {
|
|
257
|
+
const handleTableSelectionChange = (payload: { rows: any[]; ids: Array<string | number> }) => {
|
|
258
|
+
{{BUSINESS_SELECTED_ROWS_ASSIGNMENT}}
|
|
256
259
|
selectObjs.value = payload.ids.map((id) => String(id));
|
|
257
260
|
multiple.value = !payload.ids.length;
|
|
258
261
|
};
|
|
@@ -47,6 +47,7 @@ import { useDict } from '/@/hooks/dict';
|
|
|
47
47
|
import { useCrudPageMeta } from '/@/hooks/useCrudPageMeta';
|
|
48
48
|
// 国际化能力
|
|
49
49
|
import { useI18n } from 'vue-i18n';
|
|
50
|
+
{{BUSINESS_FORM_STATUS_IMPORTS}}
|
|
50
51
|
// 当前页面的字段配置
|
|
51
52
|
import { allDictTypes, dataMasterEntity } from './options';
|
|
52
53
|
|
|
@@ -147,7 +148,8 @@ const onSubmit = async (actionType?: string) => {
|
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
try {
|
|
150
|
-
|
|
151
|
+
const submitData = Object.assign({}, form{{BUSINESS_SUBMIT_STATUS_ASSIGNMENT}});
|
|
152
|
+
form.{{PK_ATTR}} ? await putObj(submitData) : await addObj(submitData);
|
|
151
153
|
|
|
152
154
|
let msg = form.{{PK_ATTR}} ? t('common.editSuccessText') : t('common.addSuccessText');
|
|
153
155
|
if (actionType === 'submit') msg = t('common.messages.quickSubmitSuccess');
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<!-- 编辑{{FEATURE_TITLE}}:业务单据编辑态控制按需生效 -->
|
|
35
35
|
<el-button{{BUSINESS_EDIT_IF}} icon="edit-pen" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_edit'" @click="handleEdit(row.{{PK_ATTR}})">{{ t('common.editBtn') }}</el-button>
|
|
36
36
|
<!-- 删除{{FEATURE_TITLE}} -->
|
|
37
|
-
<el-button icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([row.{{PK_ATTR}}])">{{ t('common.delBtn') }}</el-button>
|
|
37
|
+
<el-button{{BUSINESS_DELETE_IF}} icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([row.{{PK_ATTR}}]{{BUSINESS_DELETE_ROW_ARG}})">{{ t('common.delBtn') }}</el-button>
|
|
38
38
|
</template>
|
|
39
39
|
</SchemaListTable>
|
|
40
40
|
</div>
|
|
@@ -77,6 +77,7 @@ const router = useRouter();
|
|
|
77
77
|
const excelUploadRef = ref();
|
|
78
78
|
// 列表勾选主键集合
|
|
79
79
|
const selectObjs = ref<string[]>([]);
|
|
80
|
+
{{BUSINESS_SELECTED_ROWS_DECLARATION}}
|
|
80
81
|
// 批量删除按钮状态
|
|
81
82
|
const multiple = ref(true);
|
|
82
83
|
|
|
@@ -117,7 +118,7 @@ const toolbarProps = computed(() => ({
|
|
|
117
118
|
queryModel: state.queryForm,
|
|
118
119
|
customQueryFields: queryableDictOptions.value,
|
|
119
120
|
selectedIds: selectObjs.value,
|
|
120
|
-
deleteDisabled: multiple.value,
|
|
121
|
+
deleteDisabled: multiple.value{{BUSINESS_DELETE_DISABLED_EXPR}},
|
|
121
122
|
addPermission: '{{PERMISSION_PREFIX}}_add',
|
|
122
123
|
importPermission: '{{PERMISSION_PREFIX}}_add',
|
|
123
124
|
deletePermission: '{{PERMISSION_PREFIX}}_del',
|
|
@@ -179,7 +180,8 @@ const resetQuery = () => {
|
|
|
179
180
|
};
|
|
180
181
|
|
|
181
182
|
// 删除列表数据
|
|
182
|
-
const handleDelete = async (ids: string[]) => {
|
|
183
|
+
const handleDelete = async (ids: string[]{{BUSINESS_DELETE_ROWS_PARAM}}) => {
|
|
184
|
+
{{BUSINESS_DELETE_GUARD}}
|
|
183
185
|
try {
|
|
184
186
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
|
185
187
|
} catch {
|
|
@@ -207,7 +209,7 @@ const handleToolbarImport = () => {
|
|
|
207
209
|
|
|
208
210
|
// 工具栏批量删除事件
|
|
209
211
|
const handleToolbarDelete = () => {
|
|
210
|
-
handleDelete(selectObjs.value);
|
|
212
|
+
handleDelete(selectObjs.value{{BUSINESS_SELECTED_ROWS_ARG}});
|
|
211
213
|
};
|
|
212
214
|
|
|
213
215
|
// 工具栏查询事件
|
|
@@ -236,7 +238,8 @@ const handleToolbarRefresh = () => {
|
|
|
236
238
|
};
|
|
237
239
|
|
|
238
240
|
// 表格勾选变化事件
|
|
239
|
-
const handleTableSelectionChange = (payload: { ids: Array<string | number> }) => {
|
|
241
|
+
const handleTableSelectionChange = (payload: { rows: any[]; ids: Array<string | number> }) => {
|
|
242
|
+
{{BUSINESS_SELECTED_ROWS_ASSIGNMENT}}
|
|
240
243
|
selectObjs.value = payload.ids.map((id) => String(id));
|
|
241
244
|
multiple.value = !payload.ids.length;
|
|
242
245
|
};
|
package/mcp_server.js
CHANGED
|
@@ -5,7 +5,7 @@ const fs = require('fs');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
7
|
const SERVER_NAME = 'worsoft-codegen-local';
|
|
8
|
-
const SERVER_VERSION = '0.1.
|
|
8
|
+
const SERVER_VERSION = '0.1.72';
|
|
9
9
|
const PROTOCOL_VERSION = '2024-11-05';
|
|
10
10
|
const TOOL_NAME = 'worsoft_codegen_local_generate_frontend';
|
|
11
11
|
const STYLE_CATALOG_PATH = path.join(__dirname, 'assets', 'style-catalog.json');
|
|
@@ -204,9 +204,9 @@ export const createCrudApi = (baseUrl: string, overrides: CrudApiPathOverrides =
|
|
|
204
204
|
});
|
|
205
205
|
`;
|
|
206
206
|
|
|
207
|
-
const DEFAULT_CLOSE_CURRENT_PAGE_TEMPLATE = `import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
|
208
|
-
import { useRoute } from 'vue-router';
|
|
209
|
-
import mittBus from '/@/utils/mitt';
|
|
207
|
+
const DEFAULT_CLOSE_CURRENT_PAGE_TEMPLATE = `import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
|
208
|
+
import { useRoute } from 'vue-router';
|
|
209
|
+
import mittBus from '/@/utils/mitt';
|
|
210
210
|
|
|
211
211
|
export const closeCurrentRoutePage = (route: RouteLocationNormalizedLoaded) => {
|
|
212
212
|
\tmittBus.emit('onCurrentContextmenuClick', {
|
|
@@ -229,8 +229,22 @@ export function useCloseCurrentPage() {
|
|
|
229
229
|
\treturn {
|
|
230
230
|
\t\tcloseCurrentPage,
|
|
231
231
|
\t};
|
|
232
|
-
}
|
|
233
|
-
`;
|
|
232
|
+
}
|
|
233
|
+
`;
|
|
234
|
+
|
|
235
|
+
const DEFAULT_DICT_SEMANTIC_TEMPLATE = `// This file is hand-maintained. Do NOT overwrite during dict-registry sync.
|
|
236
|
+
// Add semantic keys here for dictionaries that have meaningful state values.
|
|
237
|
+
|
|
238
|
+
export const DictSemanticValues = {
|
|
239
|
+
billState: {
|
|
240
|
+
editing: '0',
|
|
241
|
+
processing: '1',
|
|
242
|
+
paused: '2',
|
|
243
|
+
terminated: '3',
|
|
244
|
+
completed: '4',
|
|
245
|
+
},
|
|
246
|
+
} as const;
|
|
247
|
+
`;
|
|
234
248
|
|
|
235
249
|
const TOOL_SCHEMA = {
|
|
236
250
|
type: 'object',
|
|
@@ -590,22 +604,9 @@ function renderDictRegistryContent(entries) {
|
|
|
590
604
|
'',
|
|
591
605
|
'export type DictRegistryKey = keyof typeof DictRegistry;',
|
|
592
606
|
'export type DictType = (typeof DictRegistry)[DictRegistryKey];',
|
|
593
|
-
'',
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
" editing: '0',",
|
|
597
|
-
" processing: '1',",
|
|
598
|
-
" paused: '2',",
|
|
599
|
-
" terminated: '3',",
|
|
600
|
-
" completed: '4',",
|
|
601
|
-
' },',
|
|
602
|
-
'} as const;',
|
|
603
|
-
'',
|
|
604
|
-
'export const isBillStateEditing = (value: unknown): boolean =>',
|
|
605
|
-
" String(value ?? '') === DictSemanticValues.billState.editing;",
|
|
606
|
-
'',
|
|
607
|
-
].join('\n');
|
|
608
|
-
}
|
|
607
|
+
'',
|
|
608
|
+
].join('\n');
|
|
609
|
+
}
|
|
609
610
|
|
|
610
611
|
function patchDictRegistryContent(fileContent, entriesToAdd) {
|
|
611
612
|
const source = String(fileContent || '');
|
|
@@ -626,28 +627,9 @@ function patchDictRegistryContent(fileContent, entriesToAdd) {
|
|
|
626
627
|
return source.replace(block, nextBlock);
|
|
627
628
|
}
|
|
628
629
|
|
|
629
|
-
|
|
630
|
-
''
|
|
631
|
-
|
|
632
|
-
' billState: {',
|
|
633
|
-
" editing: '0',",
|
|
634
|
-
" processing: '1',",
|
|
635
|
-
" paused: '2',",
|
|
636
|
-
" terminated: '3',",
|
|
637
|
-
" completed: '4',",
|
|
638
|
-
' },',
|
|
639
|
-
'} as const;',
|
|
640
|
-
'',
|
|
641
|
-
'export const isBillStateEditing = (value: unknown): boolean =>',
|
|
642
|
-
" String(value ?? '') === DictSemanticValues.billState.editing;",
|
|
643
|
-
'',
|
|
644
|
-
].join('\n');
|
|
645
|
-
|
|
646
|
-
function ensureDictRegistrySemanticHelpers(fileContent) {
|
|
647
|
-
const source = String(fileContent || '').replace(/\s*$/, '\n');
|
|
648
|
-
if (source.includes('export const isBillStateEditing')) return source;
|
|
649
|
-
return `${source}${DICT_REGISTRY_SEMANTIC_HELPERS}`;
|
|
650
|
-
}
|
|
630
|
+
function ensureDictRegistrySemanticHelpers(fileContent) {
|
|
631
|
+
return String(fileContent || '').replace(/\s*$/, '\n');
|
|
632
|
+
}
|
|
651
633
|
|
|
652
634
|
function isPlainObject(value) {
|
|
653
635
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
@@ -807,12 +789,12 @@ function buildLocaleLeaf(model) {
|
|
|
807
789
|
};
|
|
808
790
|
}
|
|
809
791
|
|
|
810
|
-
const leaf = {
|
|
811
|
-
title: model.tableComment,
|
|
812
|
-
fields: Object.fromEntries(model.optionFields.map((field) => [field.attrName, stripDictAnnotation(field.comment)])),
|
|
813
|
-
};
|
|
814
|
-
|
|
815
|
-
if (model.children.length) {
|
|
792
|
+
const leaf = {
|
|
793
|
+
title: model.tableComment,
|
|
794
|
+
fields: Object.fromEntries(model.optionFields.map((field) => [field.attrName, stripDictAnnotation(field.comment)])),
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
if (model.children.length) {
|
|
816
798
|
leaf.children = Object.fromEntries(
|
|
817
799
|
model.children.map((childModel) => [
|
|
818
800
|
childModel.listName,
|
|
@@ -953,24 +935,39 @@ function ensureCrudFactorySupportFile(frontendPath) {
|
|
|
953
935
|
};
|
|
954
936
|
}
|
|
955
937
|
|
|
956
|
-
function ensureCloseCurrentPageSupportFile(frontendPath) {
|
|
957
|
-
const hookPath = path.join(frontendPath, 'src', 'hooks', 'useCloseCurrentPage.ts');
|
|
958
|
-
const exists = fs.existsSync(hookPath);
|
|
959
|
-
const currentContent = exists ? readUtf8File(hookPath) : '';
|
|
960
|
-
const isCompatible = !exists || currentContent.includes('export function useCloseCurrentPage');
|
|
938
|
+
function ensureCloseCurrentPageSupportFile(frontendPath) {
|
|
939
|
+
const hookPath = path.join(frontendPath, 'src', 'hooks', 'useCloseCurrentPage.ts');
|
|
940
|
+
const exists = fs.existsSync(hookPath);
|
|
941
|
+
const currentContent = exists ? readUtf8File(hookPath) : '';
|
|
942
|
+
const isCompatible = !exists || currentContent.includes('export function useCloseCurrentPage');
|
|
961
943
|
|
|
962
944
|
return {
|
|
963
945
|
path: hookPath,
|
|
964
946
|
content: DEFAULT_CLOSE_CURRENT_PAGE_TEMPLATE,
|
|
965
947
|
exists,
|
|
966
948
|
isCompatible,
|
|
967
|
-
needsWrite: !exists,
|
|
968
|
-
};
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
function
|
|
972
|
-
|
|
973
|
-
|
|
949
|
+
needsWrite: !exists,
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
function ensureDictSemanticSupportFile(frontendPath) {
|
|
954
|
+
const semanticPath = path.join(frontendPath, 'src', 'enums', 'dict-semantic.ts');
|
|
955
|
+
const exists = fs.existsSync(semanticPath);
|
|
956
|
+
const currentContent = exists ? readUtf8File(semanticPath) : '';
|
|
957
|
+
const isCompatible = !exists || currentContent.includes('export const DictSemanticValues');
|
|
958
|
+
|
|
959
|
+
return {
|
|
960
|
+
path: semanticPath,
|
|
961
|
+
content: DEFAULT_DICT_SEMANTIC_TEMPLATE,
|
|
962
|
+
exists,
|
|
963
|
+
isCompatible,
|
|
964
|
+
needsWrite: !exists,
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
function ensureDirectory(filePath) {
|
|
969
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
970
|
+
}
|
|
974
971
|
|
|
975
972
|
function writeSupportFile(filePath, content) {
|
|
976
973
|
ensureDirectory(filePath);
|
|
@@ -1015,24 +1012,36 @@ function prepareSharedSupport(frontendPath, dictTypes, writeSupportFiles) {
|
|
|
1015
1012
|
writeEnabled: false,
|
|
1016
1013
|
};
|
|
1017
1014
|
const closeCurrentPagePath = path.join(frontendPath, 'src', 'hooks', 'useCloseCurrentPage.ts');
|
|
1018
|
-
const closeCurrentPage = writeSupportFiles
|
|
1019
|
-
? ensureCloseCurrentPageSupportFile(frontendPath)
|
|
1020
|
-
: {
|
|
1021
|
-
path: closeCurrentPagePath,
|
|
1022
|
-
content: DEFAULT_CLOSE_CURRENT_PAGE_TEMPLATE,
|
|
1015
|
+
const closeCurrentPage = writeSupportFiles
|
|
1016
|
+
? ensureCloseCurrentPageSupportFile(frontendPath)
|
|
1017
|
+
: {
|
|
1018
|
+
path: closeCurrentPagePath,
|
|
1019
|
+
content: DEFAULT_CLOSE_CURRENT_PAGE_TEMPLATE,
|
|
1023
1020
|
exists: fs.existsSync(closeCurrentPagePath),
|
|
1024
1021
|
isCompatible: true,
|
|
1025
|
-
needsWrite: false,
|
|
1026
|
-
writeEnabled: false,
|
|
1027
|
-
};
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1022
|
+
needsWrite: false,
|
|
1023
|
+
writeEnabled: false,
|
|
1024
|
+
};
|
|
1025
|
+
const dictSemanticPath = path.join(frontendPath, 'src', 'enums', 'dict-semantic.ts');
|
|
1026
|
+
const dictSemantic = writeSupportFiles
|
|
1027
|
+
? ensureDictSemanticSupportFile(frontendPath)
|
|
1028
|
+
: {
|
|
1029
|
+
path: dictSemanticPath,
|
|
1030
|
+
content: DEFAULT_DICT_SEMANTIC_TEMPLATE,
|
|
1031
|
+
exists: fs.existsSync(dictSemanticPath),
|
|
1032
|
+
isCompatible: true,
|
|
1033
|
+
needsWrite: false,
|
|
1034
|
+
writeEnabled: false,
|
|
1035
|
+
};
|
|
1036
|
+
return {
|
|
1037
|
+
dictRegistry,
|
|
1038
|
+
crudSchema,
|
|
1039
|
+
crudFactory,
|
|
1040
|
+
closeCurrentPage,
|
|
1041
|
+
dictSemantic,
|
|
1042
|
+
writeEnabled: Boolean(writeSupportFiles),
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1036
1045
|
|
|
1037
1046
|
function maybeWriteSharedSupport(sharedSupport, writeToDisk) {
|
|
1038
1047
|
if (!writeToDisk || !sharedSupport.writeEnabled) return;
|
|
@@ -1061,25 +1070,35 @@ function maybeWriteSharedSupport(sharedSupport, writeToDisk) {
|
|
|
1061
1070
|
writeSupportFile(sharedSupport.dictRegistry.path, sharedSupport.dictRegistry.content);
|
|
1062
1071
|
}
|
|
1063
1072
|
|
|
1064
|
-
if (sharedSupport.closeCurrentPage.needsWrite) {
|
|
1065
|
-
if (!sharedSupport.closeCurrentPage.isCompatible) {
|
|
1066
|
-
throw new Error(
|
|
1067
|
-
'Detected an existing src/hooks/useCloseCurrentPage.ts that MCP could not merge safely. ' +
|
|
1068
|
-
'Please align the useCloseCurrentPage export manually before enabling writeSupportFiles.'
|
|
1073
|
+
if (sharedSupport.closeCurrentPage.needsWrite) {
|
|
1074
|
+
if (!sharedSupport.closeCurrentPage.isCompatible) {
|
|
1075
|
+
throw new Error(
|
|
1076
|
+
'Detected an existing src/hooks/useCloseCurrentPage.ts that MCP could not merge safely. ' +
|
|
1077
|
+
'Please align the useCloseCurrentPage export manually before enabling writeSupportFiles.'
|
|
1069
1078
|
);
|
|
1070
|
-
}
|
|
1071
|
-
writeSupportFile(sharedSupport.closeCurrentPage.path, sharedSupport.closeCurrentPage.content);
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1079
|
+
}
|
|
1080
|
+
writeSupportFile(sharedSupport.closeCurrentPage.path, sharedSupport.closeCurrentPage.content);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
if (sharedSupport.dictSemantic.needsWrite) {
|
|
1084
|
+
if (!sharedSupport.dictSemantic.isCompatible) {
|
|
1085
|
+
throw new Error(
|
|
1086
|
+
'Detected an existing src/enums/dict-semantic.ts that MCP could not merge safely. ' +
|
|
1087
|
+
'Please align the DictSemanticValues export manually before enabling writeSupportFiles.'
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
writeSupportFile(sharedSupport.dictSemantic.path, sharedSupport.dictSemantic.content);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1074
1093
|
|
|
1075
1094
|
function buildSupportNote(sharedSupport, localeZhSupport) {
|
|
1076
1095
|
const notes = [];
|
|
1077
1096
|
|
|
1078
|
-
if (!sharedSupport.writeEnabled) {
|
|
1079
|
-
notes.push(
|
|
1080
|
-
'Shared support file writing is disabled. Generated code still references src/utils/crudSchema.ts, src/api/common/crudFactory.ts, src/hooks/useCloseCurrentPage.ts and may reference src/enums/dict-registry.ts, so those helpers must already exist in the target project.'
|
|
1081
|
-
);
|
|
1082
|
-
}
|
|
1097
|
+
if (!sharedSupport.writeEnabled) {
|
|
1098
|
+
notes.push(
|
|
1099
|
+
'Shared support file writing is disabled. Generated code still references src/utils/crudSchema.ts, src/api/common/crudFactory.ts, src/hooks/useCloseCurrentPage.ts, src/enums/dict-semantic.ts and may reference src/enums/dict-registry.ts, so those helpers must already exist in the target project.'
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1083
1102
|
|
|
1084
1103
|
if (sharedSupport.crudSchema.exists && !sharedSupport.crudSchema.isCompatible) {
|
|
1085
1104
|
notes.push(
|
|
@@ -1095,12 +1114,19 @@ function buildSupportNote(sharedSupport, localeZhSupport) {
|
|
|
1095
1114
|
);
|
|
1096
1115
|
}
|
|
1097
1116
|
|
|
1098
|
-
if (sharedSupport.dictRegistry.exists && !sharedSupport.dictRegistry.isCompatible) {
|
|
1099
|
-
notes.push(
|
|
1100
|
-
'Detected an existing src/enums/dict-registry.ts that MCP could not merge safely. ' +
|
|
1101
|
-
'MCP preserved the existing file and did not overwrite it.'
|
|
1102
|
-
);
|
|
1103
|
-
}
|
|
1117
|
+
if (sharedSupport.dictRegistry.exists && !sharedSupport.dictRegistry.isCompatible) {
|
|
1118
|
+
notes.push(
|
|
1119
|
+
'Detected an existing src/enums/dict-registry.ts that MCP could not merge safely. ' +
|
|
1120
|
+
'MCP preserved the existing file and did not overwrite it.'
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
if (sharedSupport.dictSemantic.exists && !sharedSupport.dictSemantic.isCompatible) {
|
|
1125
|
+
notes.push(
|
|
1126
|
+
'Detected an existing src/enums/dict-semantic.ts that does not expose DictSemanticValues. ' +
|
|
1127
|
+
'MCP preserved the existing file and did not overwrite it.'
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1104
1130
|
|
|
1105
1131
|
if (localeZhSupport.exists && !localeZhSupport.isCompatible) {
|
|
1106
1132
|
notes.push(
|
|
@@ -3303,24 +3329,45 @@ function renderSingleTableDialogDictApiFunctions(model) {
|
|
|
3303
3329
|
].join('\n');
|
|
3304
3330
|
}
|
|
3305
3331
|
|
|
3306
|
-
function hasBusinessBillStateEditControl(model) {
|
|
3307
|
-
return model.pageType === 'business' && !!model.statusField && model.statusDictType === 'bill_state';
|
|
3308
|
-
}
|
|
3309
|
-
|
|
3310
|
-
function renderBusinessStatusImports(model) {
|
|
3311
|
-
return hasBusinessBillStateEditControl(model)
|
|
3312
|
-
? "//
|
|
3313
|
-
: '';
|
|
3314
|
-
}
|
|
3315
|
-
|
|
3316
|
-
function renderBusinessStatusHelpers(model) {
|
|
3317
|
-
if (!hasBusinessBillStateEditControl(model)) return '';
|
|
3318
|
-
const statusAttr = toCamelCase(model.statusField);
|
|
3319
|
-
return [
|
|
3320
|
-
'//
|
|
3321
|
-
`const showEditAction = (row: any): boolean =>
|
|
3322
|
-
|
|
3323
|
-
|
|
3332
|
+
function hasBusinessBillStateEditControl(model) {
|
|
3333
|
+
return model.pageType === 'business' && !!model.statusField && model.statusDictType === 'bill_state';
|
|
3334
|
+
}
|
|
3335
|
+
|
|
3336
|
+
function renderBusinessStatusImports(model) {
|
|
3337
|
+
return hasBusinessBillStateEditControl(model)
|
|
3338
|
+
? "// 业务单据状态枚举\nimport { DictSemanticValues } from '/@/enums/dict-semantic';"
|
|
3339
|
+
: '';
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
function renderBusinessStatusHelpers(model) {
|
|
3343
|
+
if (!hasBusinessBillStateEditControl(model)) return '';
|
|
3344
|
+
const statusAttr = toCamelCase(model.statusField);
|
|
3345
|
+
return [
|
|
3346
|
+
'// 控制业务单据编辑按钮显隐:仅编辑中允许编辑',
|
|
3347
|
+
`const showEditAction = (row: any): boolean => String(row?.${statusAttr} ?? '') === DictSemanticValues.billState.editing;`,
|
|
3348
|
+
'',
|
|
3349
|
+
'// 控制业务单据删除按钮显隐:已完成不允许删除',
|
|
3350
|
+
`const showDeleteAction = (row: any): boolean => String(row?.${statusAttr} ?? '') !== DictSemanticValues.billState.completed;`,
|
|
3351
|
+
].join('\n');
|
|
3352
|
+
}
|
|
3353
|
+
|
|
3354
|
+
function renderBusinessDeleteGuard(model) {
|
|
3355
|
+
if (!hasBusinessBillStateEditControl(model)) return '';
|
|
3356
|
+
const i18nNamespace = buildI18nNamespace(model);
|
|
3357
|
+
return [
|
|
3358
|
+
' if (rows.some((row) => !showDeleteAction(row))) {',
|
|
3359
|
+
" useMessage().warning(t('common.messages.completedBillCannotDelete'));",
|
|
3360
|
+
' return;',
|
|
3361
|
+
' }',
|
|
3362
|
+
'',
|
|
3363
|
+
].join('\n');
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
function renderBusinessSubmitStatusAssignment(model) {
|
|
3367
|
+
if (!hasBusinessBillStateEditControl(model)) return '';
|
|
3368
|
+
const statusAttr = toCamelCase(model.statusField);
|
|
3369
|
+
return `, actionType === 'submit' ? { ${statusAttr}: DictSemanticValues.billState.completed } : {}`;
|
|
3370
|
+
}
|
|
3324
3371
|
|
|
3325
3372
|
function sanitizeComment(value) {
|
|
3326
3373
|
return String(value || '').replace(/\*\//g, '* /').replace(/\r?\n/g, ' ').trim();
|
|
@@ -3417,11 +3464,21 @@ function buildReplacements(model, sharedSupport) {
|
|
|
3417
3464
|
LIST_ACTIONS: renderSingleTableDialogActions(model, permissionPrefix),
|
|
3418
3465
|
DICT_API_IMPORTS: model.pageType === 'dict' && model.statusField ? ', enableObj, disableObj' : '',
|
|
3419
3466
|
DICT_LIST_HELPERS: renderSingleTableDialogDictHelpers(model),
|
|
3420
|
-
DICT_API_FUNCTIONS: renderSingleTableDialogDictApiFunctions(model),
|
|
3421
|
-
BUSINESS_STATUS_IMPORTS: renderBusinessStatusImports(model),
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3467
|
+
DICT_API_FUNCTIONS: renderSingleTableDialogDictApiFunctions(model),
|
|
3468
|
+
BUSINESS_STATUS_IMPORTS: renderBusinessStatusImports(model),
|
|
3469
|
+
BUSINESS_FORM_STATUS_IMPORTS: renderBusinessStatusImports(model),
|
|
3470
|
+
BUSINESS_EDIT_IF: hasBusinessBillStateEditControl(model) ? ' v-if="showEditAction(row)"' : '',
|
|
3471
|
+
BUSINESS_DELETE_IF: hasBusinessBillStateEditControl(model) ? ' v-if="showDeleteAction(row)"' : '',
|
|
3472
|
+
BUSINESS_DELETE_ROW_ARG: hasBusinessBillStateEditControl(model) ? ', [row]' : '',
|
|
3473
|
+
BUSINESS_SELECTED_ROWS_DECLARATION: hasBusinessBillStateEditControl(model) ? 'const selectedRows = ref<any[]>([]);' : '',
|
|
3474
|
+
BUSINESS_DELETE_DISABLED_EXPR: hasBusinessBillStateEditControl(model) ? ' || selectedRows.value.some((row) => !showDeleteAction(row))' : '',
|
|
3475
|
+
BUSINESS_DELETE_ROWS_PARAM: hasBusinessBillStateEditControl(model) ? ', rows: any[] = []' : '',
|
|
3476
|
+
BUSINESS_DELETE_GUARD: renderBusinessDeleteGuard(model),
|
|
3477
|
+
BUSINESS_SELECTED_ROWS_ARG: hasBusinessBillStateEditControl(model) ? ', selectedRows.value' : '',
|
|
3478
|
+
BUSINESS_SELECTED_ROWS_ASSIGNMENT: hasBusinessBillStateEditControl(model) ? ' selectedRows.value = payload.rows;' : '',
|
|
3479
|
+
BUSINESS_STATUS_HELPERS: renderBusinessStatusHelpers(model),
|
|
3480
|
+
BUSINESS_SUBMIT_STATUS_ASSIGNMENT: renderBusinessSubmitStatusAssignment(model),
|
|
3481
|
+
API_REQUEST_IMPORT: renderApiRequestImport(model),
|
|
3425
3482
|
EXTRA_API_FUNCTIONS: renderExtraApiFunctionsV2(model),
|
|
3426
3483
|
CUSTOM_QUERY_FIELDS_EXPR: model.pageType === 'dict' ? '[]' : 'queryableDictOptions.value',
|
|
3427
3484
|
SHOW_RIGHT_TOOLS: model.pageType === 'dict' ? 'false' : 'true',
|
package/package.json
CHANGED