worsoft-frontend-codegen-local-mcp 0.1.70 → 0.1.71
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.71';
|
|
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,18 @@ 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
|
|
792
|
+
const leaf = {
|
|
793
|
+
title: model.tableComment,
|
|
794
|
+
fields: Object.fromEntries(model.optionFields.map((field) => [field.attrName, stripDictAnnotation(field.comment)])),
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
if (hasBusinessBillStateEditControl(model)) {
|
|
798
|
+
leaf.messages = {
|
|
799
|
+
completedCannotDelete: '单据状态为已完成的数据不能删除',
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (model.children.length) {
|
|
816
804
|
leaf.children = Object.fromEntries(
|
|
817
805
|
model.children.map((childModel) => [
|
|
818
806
|
childModel.listName,
|
|
@@ -953,24 +941,39 @@ function ensureCrudFactorySupportFile(frontendPath) {
|
|
|
953
941
|
};
|
|
954
942
|
}
|
|
955
943
|
|
|
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');
|
|
944
|
+
function ensureCloseCurrentPageSupportFile(frontendPath) {
|
|
945
|
+
const hookPath = path.join(frontendPath, 'src', 'hooks', 'useCloseCurrentPage.ts');
|
|
946
|
+
const exists = fs.existsSync(hookPath);
|
|
947
|
+
const currentContent = exists ? readUtf8File(hookPath) : '';
|
|
948
|
+
const isCompatible = !exists || currentContent.includes('export function useCloseCurrentPage');
|
|
961
949
|
|
|
962
950
|
return {
|
|
963
951
|
path: hookPath,
|
|
964
952
|
content: DEFAULT_CLOSE_CURRENT_PAGE_TEMPLATE,
|
|
965
953
|
exists,
|
|
966
954
|
isCompatible,
|
|
967
|
-
needsWrite: !exists,
|
|
968
|
-
};
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
function
|
|
972
|
-
|
|
973
|
-
|
|
955
|
+
needsWrite: !exists,
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
function ensureDictSemanticSupportFile(frontendPath) {
|
|
960
|
+
const semanticPath = path.join(frontendPath, 'src', 'enums', 'dict-semantic.ts');
|
|
961
|
+
const exists = fs.existsSync(semanticPath);
|
|
962
|
+
const currentContent = exists ? readUtf8File(semanticPath) : '';
|
|
963
|
+
const isCompatible = !exists || currentContent.includes('export const DictSemanticValues');
|
|
964
|
+
|
|
965
|
+
return {
|
|
966
|
+
path: semanticPath,
|
|
967
|
+
content: DEFAULT_DICT_SEMANTIC_TEMPLATE,
|
|
968
|
+
exists,
|
|
969
|
+
isCompatible,
|
|
970
|
+
needsWrite: !exists,
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
function ensureDirectory(filePath) {
|
|
975
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
976
|
+
}
|
|
974
977
|
|
|
975
978
|
function writeSupportFile(filePath, content) {
|
|
976
979
|
ensureDirectory(filePath);
|
|
@@ -1015,24 +1018,36 @@ function prepareSharedSupport(frontendPath, dictTypes, writeSupportFiles) {
|
|
|
1015
1018
|
writeEnabled: false,
|
|
1016
1019
|
};
|
|
1017
1020
|
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,
|
|
1021
|
+
const closeCurrentPage = writeSupportFiles
|
|
1022
|
+
? ensureCloseCurrentPageSupportFile(frontendPath)
|
|
1023
|
+
: {
|
|
1024
|
+
path: closeCurrentPagePath,
|
|
1025
|
+
content: DEFAULT_CLOSE_CURRENT_PAGE_TEMPLATE,
|
|
1023
1026
|
exists: fs.existsSync(closeCurrentPagePath),
|
|
1024
1027
|
isCompatible: true,
|
|
1025
|
-
needsWrite: false,
|
|
1026
|
-
writeEnabled: false,
|
|
1027
|
-
};
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1028
|
+
needsWrite: false,
|
|
1029
|
+
writeEnabled: false,
|
|
1030
|
+
};
|
|
1031
|
+
const dictSemanticPath = path.join(frontendPath, 'src', 'enums', 'dict-semantic.ts');
|
|
1032
|
+
const dictSemantic = writeSupportFiles
|
|
1033
|
+
? ensureDictSemanticSupportFile(frontendPath)
|
|
1034
|
+
: {
|
|
1035
|
+
path: dictSemanticPath,
|
|
1036
|
+
content: DEFAULT_DICT_SEMANTIC_TEMPLATE,
|
|
1037
|
+
exists: fs.existsSync(dictSemanticPath),
|
|
1038
|
+
isCompatible: true,
|
|
1039
|
+
needsWrite: false,
|
|
1040
|
+
writeEnabled: false,
|
|
1041
|
+
};
|
|
1042
|
+
return {
|
|
1043
|
+
dictRegistry,
|
|
1044
|
+
crudSchema,
|
|
1045
|
+
crudFactory,
|
|
1046
|
+
closeCurrentPage,
|
|
1047
|
+
dictSemantic,
|
|
1048
|
+
writeEnabled: Boolean(writeSupportFiles),
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1036
1051
|
|
|
1037
1052
|
function maybeWriteSharedSupport(sharedSupport, writeToDisk) {
|
|
1038
1053
|
if (!writeToDisk || !sharedSupport.writeEnabled) return;
|
|
@@ -1061,25 +1076,35 @@ function maybeWriteSharedSupport(sharedSupport, writeToDisk) {
|
|
|
1061
1076
|
writeSupportFile(sharedSupport.dictRegistry.path, sharedSupport.dictRegistry.content);
|
|
1062
1077
|
}
|
|
1063
1078
|
|
|
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.'
|
|
1079
|
+
if (sharedSupport.closeCurrentPage.needsWrite) {
|
|
1080
|
+
if (!sharedSupport.closeCurrentPage.isCompatible) {
|
|
1081
|
+
throw new Error(
|
|
1082
|
+
'Detected an existing src/hooks/useCloseCurrentPage.ts that MCP could not merge safely. ' +
|
|
1083
|
+
'Please align the useCloseCurrentPage export manually before enabling writeSupportFiles.'
|
|
1069
1084
|
);
|
|
1070
|
-
}
|
|
1071
|
-
writeSupportFile(sharedSupport.closeCurrentPage.path, sharedSupport.closeCurrentPage.content);
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1085
|
+
}
|
|
1086
|
+
writeSupportFile(sharedSupport.closeCurrentPage.path, sharedSupport.closeCurrentPage.content);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
if (sharedSupport.dictSemantic.needsWrite) {
|
|
1090
|
+
if (!sharedSupport.dictSemantic.isCompatible) {
|
|
1091
|
+
throw new Error(
|
|
1092
|
+
'Detected an existing src/enums/dict-semantic.ts that MCP could not merge safely. ' +
|
|
1093
|
+
'Please align the DictSemanticValues export manually before enabling writeSupportFiles.'
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
writeSupportFile(sharedSupport.dictSemantic.path, sharedSupport.dictSemantic.content);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1074
1099
|
|
|
1075
1100
|
function buildSupportNote(sharedSupport, localeZhSupport) {
|
|
1076
1101
|
const notes = [];
|
|
1077
1102
|
|
|
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
|
-
}
|
|
1103
|
+
if (!sharedSupport.writeEnabled) {
|
|
1104
|
+
notes.push(
|
|
1105
|
+
'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.'
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1083
1108
|
|
|
1084
1109
|
if (sharedSupport.crudSchema.exists && !sharedSupport.crudSchema.isCompatible) {
|
|
1085
1110
|
notes.push(
|
|
@@ -1095,12 +1120,19 @@ function buildSupportNote(sharedSupport, localeZhSupport) {
|
|
|
1095
1120
|
);
|
|
1096
1121
|
}
|
|
1097
1122
|
|
|
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
|
-
}
|
|
1123
|
+
if (sharedSupport.dictRegistry.exists && !sharedSupport.dictRegistry.isCompatible) {
|
|
1124
|
+
notes.push(
|
|
1125
|
+
'Detected an existing src/enums/dict-registry.ts that MCP could not merge safely. ' +
|
|
1126
|
+
'MCP preserved the existing file and did not overwrite it.'
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
if (sharedSupport.dictSemantic.exists && !sharedSupport.dictSemantic.isCompatible) {
|
|
1131
|
+
notes.push(
|
|
1132
|
+
'Detected an existing src/enums/dict-semantic.ts that does not expose DictSemanticValues. ' +
|
|
1133
|
+
'MCP preserved the existing file and did not overwrite it.'
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1104
1136
|
|
|
1105
1137
|
if (localeZhSupport.exists && !localeZhSupport.isCompatible) {
|
|
1106
1138
|
notes.push(
|
|
@@ -3303,24 +3335,45 @@ function renderSingleTableDialogDictApiFunctions(model) {
|
|
|
3303
3335
|
].join('\n');
|
|
3304
3336
|
}
|
|
3305
3337
|
|
|
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
|
-
|
|
3338
|
+
function hasBusinessBillStateEditControl(model) {
|
|
3339
|
+
return model.pageType === 'business' && !!model.statusField && model.statusDictType === 'bill_state';
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
function renderBusinessStatusImports(model) {
|
|
3343
|
+
return hasBusinessBillStateEditControl(model)
|
|
3344
|
+
? "// 业务单据状态枚举\nimport { DictSemanticValues } from '/@/enums/dict-semantic';"
|
|
3345
|
+
: '';
|
|
3346
|
+
}
|
|
3347
|
+
|
|
3348
|
+
function renderBusinessStatusHelpers(model) {
|
|
3349
|
+
if (!hasBusinessBillStateEditControl(model)) return '';
|
|
3350
|
+
const statusAttr = toCamelCase(model.statusField);
|
|
3351
|
+
return [
|
|
3352
|
+
'// 控制业务单据编辑按钮显隐:仅编辑中允许编辑',
|
|
3353
|
+
`const showEditAction = (row: any): boolean => String(row?.${statusAttr} ?? '') === DictSemanticValues.billState.editing;`,
|
|
3354
|
+
'',
|
|
3355
|
+
'// 控制业务单据删除按钮显隐:已完成不允许删除',
|
|
3356
|
+
`const showDeleteAction = (row: any): boolean => String(row?.${statusAttr} ?? '') !== DictSemanticValues.billState.completed;`,
|
|
3357
|
+
].join('\n');
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
function renderBusinessDeleteGuard(model) {
|
|
3361
|
+
if (!hasBusinessBillStateEditControl(model)) return '';
|
|
3362
|
+
const i18nNamespace = buildI18nNamespace(model);
|
|
3363
|
+
return [
|
|
3364
|
+
' if (rows.some((row) => !showDeleteAction(row))) {',
|
|
3365
|
+
` useMessage().warning(t('${i18nNamespace}.messages.completedCannotDelete'));`,
|
|
3366
|
+
' return;',
|
|
3367
|
+
' }',
|
|
3368
|
+
'',
|
|
3369
|
+
].join('\n');
|
|
3370
|
+
}
|
|
3371
|
+
|
|
3372
|
+
function renderBusinessSubmitStatusAssignment(model) {
|
|
3373
|
+
if (!hasBusinessBillStateEditControl(model)) return '';
|
|
3374
|
+
const statusAttr = toCamelCase(model.statusField);
|
|
3375
|
+
return `, actionType === 'submit' ? { ${statusAttr}: DictSemanticValues.billState.completed } : {}`;
|
|
3376
|
+
}
|
|
3324
3377
|
|
|
3325
3378
|
function sanitizeComment(value) {
|
|
3326
3379
|
return String(value || '').replace(/\*\//g, '* /').replace(/\r?\n/g, ' ').trim();
|
|
@@ -3417,11 +3470,21 @@ function buildReplacements(model, sharedSupport) {
|
|
|
3417
3470
|
LIST_ACTIONS: renderSingleTableDialogActions(model, permissionPrefix),
|
|
3418
3471
|
DICT_API_IMPORTS: model.pageType === 'dict' && model.statusField ? ', enableObj, disableObj' : '',
|
|
3419
3472
|
DICT_LIST_HELPERS: renderSingleTableDialogDictHelpers(model),
|
|
3420
|
-
DICT_API_FUNCTIONS: renderSingleTableDialogDictApiFunctions(model),
|
|
3421
|
-
BUSINESS_STATUS_IMPORTS: renderBusinessStatusImports(model),
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3473
|
+
DICT_API_FUNCTIONS: renderSingleTableDialogDictApiFunctions(model),
|
|
3474
|
+
BUSINESS_STATUS_IMPORTS: renderBusinessStatusImports(model),
|
|
3475
|
+
BUSINESS_FORM_STATUS_IMPORTS: renderBusinessStatusImports(model),
|
|
3476
|
+
BUSINESS_EDIT_IF: hasBusinessBillStateEditControl(model) ? ' v-if="showEditAction(row)"' : '',
|
|
3477
|
+
BUSINESS_DELETE_IF: hasBusinessBillStateEditControl(model) ? ' v-if="showDeleteAction(row)"' : '',
|
|
3478
|
+
BUSINESS_DELETE_ROW_ARG: hasBusinessBillStateEditControl(model) ? ', [row]' : '',
|
|
3479
|
+
BUSINESS_SELECTED_ROWS_DECLARATION: hasBusinessBillStateEditControl(model) ? 'const selectedRows = ref<any[]>([]);' : '',
|
|
3480
|
+
BUSINESS_DELETE_DISABLED_EXPR: hasBusinessBillStateEditControl(model) ? ' || selectedRows.value.some((row) => !showDeleteAction(row))' : '',
|
|
3481
|
+
BUSINESS_DELETE_ROWS_PARAM: hasBusinessBillStateEditControl(model) ? ', rows: any[] = []' : '',
|
|
3482
|
+
BUSINESS_DELETE_GUARD: renderBusinessDeleteGuard(model),
|
|
3483
|
+
BUSINESS_SELECTED_ROWS_ARG: hasBusinessBillStateEditControl(model) ? ', selectedRows.value' : '',
|
|
3484
|
+
BUSINESS_SELECTED_ROWS_ASSIGNMENT: hasBusinessBillStateEditControl(model) ? ' selectedRows.value = payload.rows;' : '',
|
|
3485
|
+
BUSINESS_STATUS_HELPERS: renderBusinessStatusHelpers(model),
|
|
3486
|
+
BUSINESS_SUBMIT_STATUS_ASSIGNMENT: renderBusinessSubmitStatusAssignment(model),
|
|
3487
|
+
API_REQUEST_IMPORT: renderApiRequestImport(model),
|
|
3425
3488
|
EXTRA_API_FUNCTIONS: renderExtraApiFunctionsV2(model),
|
|
3426
3489
|
CUSTOM_QUERY_FIELDS_EXPR: model.pageType === 'dict' ? '[]' : 'queryableDictOptions.value',
|
|
3427
3490
|
SHOW_RIGHT_TOOLS: model.pageType === 'dict' ? 'false' : 'true',
|
package/package.json
CHANGED