worsoft-frontend-codegen-local-mcp 0.1.7 → 0.1.8

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.
@@ -5,14 +5,14 @@
5
5
  <div style="display: flex; justify-content: space-between; align-items: center;">
6
6
  <span style="font-size: 16px; font-weight: bold;">{{ form.{{PK_ATTR}} ? (detail ? t('common.viewBtn') : t('common.editBtn')) : t('common.addBtn') }}</span>
7
7
  <div v-if="!detail">
8
- <el-button @click="onSubmit('save')" :disabled="loading" icon="document">{{ actionLabel('save') }}</el-button>
9
- <el-button @click="onSubmit('flow')" :disabled="loading" plain type="success" icon="position">{{ actionLabel('flow') }}</el-button>
10
- <el-button @click="onSubmit('submit')" :disabled="loading" type="primary" icon="check">{{ actionLabel('submit') }}</el-button>
8
+ <el-button @click="onSubmit('save')" :disabled="loading" icon="document">{{ commonActionLabel('save') }}</el-button>
9
+ <el-button @click="onSubmit('flow')" :disabled="loading" plain type="success" icon="position">{{ commonActionLabel('flow') }}</el-button>
10
+ <el-button @click="onSubmit('submit')" :disabled="loading" type="primary" icon="check">{{ commonActionLabel('submit') }}</el-button>
11
11
  <el-divider direction="vertical" />
12
12
  <el-button @click="handleBack" icon="close">{{ t('common.cancelButtonText') }}</el-button>
13
13
  </div>
14
14
  <div v-else>
15
- <el-button @click="handleBack" icon="back">{{ actionLabel('back') }}</el-button>
15
+ <el-button @click="handleBack" icon="back">{{ commonActionLabel('back') }}</el-button>
16
16
  </div>
17
17
  </div>
18
18
  </template>
@@ -71,10 +71,10 @@ const getChildFieldLabel = (groupName: string, prop: string) => {
71
71
  };
72
72
  const childSectionTitle = (groupName: string) => t(`${pageI18nKey}.children.${groupName}.title`);
73
73
  const getDictOptions = (dictType?: string) => (dictType ? dictRefs[dictType]?.value || [] : []);
74
- const inputPlaceholder = (label: string) => t(`${pageI18nKey}.placeholders.input`, { label });
75
- const selectPlaceholder = (label: string) => t(`${pageI18nKey}.placeholders.select`, { label });
76
- const fieldRequiredMessage = (prop: string) => t(`${pageI18nKey}.messages.required`, { label: getMasterFieldLabel(prop) });
77
- const actionLabel = (action: string) => t(`${pageI18nKey}.actions.${action}`);
74
+ const inputPlaceholder = (label: string) => t('common.placeholders.input', { label });
75
+ const selectPlaceholder = (label: string) => t('common.placeholders.select', { label });
76
+ const fieldRequiredMessage = (prop: string) => t('common.messages.required', { label: getMasterFieldLabel(prop) });
77
+ const commonActionLabel = (action: string) => t('common.actions.' + action);
78
78
 
79
79
  const form = reactive({
80
80
  {{FORM_DEFAULTS}}
@@ -93,7 +93,7 @@ const get{{CLASS_NAME}}Data = async (id: string) => {
93
93
  const { data } = await getObj({ {{PK_ATTR}}: id });
94
94
  Object.assign(form, data[0] || {});
95
95
  } catch (error) {
96
- useMessage().error(t(`${pageI18nKey}.messages.fetchError`));
96
+ useMessage().error(t('common.messages.fetchError'));
97
97
  } finally {
98
98
  loading.value = false;
99
99
  }
@@ -143,14 +143,14 @@ const onSubmit = async (actionType?: string) => {
143
143
  try {
144
144
  form.{{PK_ATTR}} ? await putObj(form) : await addObj(form);
145
145
 
146
- let msg = form.{{PK_ATTR}} ? t(`${pageI18nKey}.messages.updateSuccess`) : t(`${pageI18nKey}.messages.createSuccess`);
147
- if (actionType === 'submit') msg = t(`${pageI18nKey}.messages.quickSubmitSuccess`);
148
- if (actionType === 'flow') msg = t(`${pageI18nKey}.messages.quickFlowSuccess`);
146
+ let msg = form.{{PK_ATTR}} ? t('common.editSuccessText') : t('common.addSuccessText');
147
+ if (actionType === 'submit') msg = t('common.messages.quickSubmitSuccess');
148
+ if (actionType === 'flow') msg = t('common.messages.quickFlowSuccess');
149
149
 
150
150
  useMessage().success(msg);
151
151
  closeCurrentPage();
152
152
  } catch (err: any) {
153
- useMessage().error(err.msg || t(`${pageI18nKey}.messages.submitError`));
153
+ useMessage().error(err.msg || t('common.messages.submitError'));
154
154
  } finally {
155
155
  loading.value = false;
156
156
  }
@@ -39,8 +39,8 @@
39
39
  <template #default="scope">
40
40
  <el-button text type="primary" icon="view" v-auth="'{{PERMISSION_PREFIX}}_view'" @click="handleDetail(scope.row.id)">{{ t('common.viewBtn') }}</el-button>
41
41
  <el-button icon="edit-pen" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_edit'" @click="handleEdit(scope.row.id)">{{ t('common.editBtn') }}</el-button>
42
- <el-button text type="primary" icon="check" @click="handleQuickAction(scope.row, 'submit')">{{ actionLabel('submit') }}</el-button>
43
- <el-button text type="success" icon="position" @click="handleQuickAction(scope.row, 'flow')">{{ actionLabel('flow') }}</el-button>
42
+ <el-button text type="primary" icon="check" @click="handleQuickAction(scope.row, 'submit')">{{ commonActionLabel('submit') }}</el-button>
43
+ <el-button text type="success" icon="position" @click="handleQuickAction(scope.row, 'flow')">{{ commonActionLabel('flow') }}</el-button>
44
44
  <el-button icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([scope.row.id])">{{ t('common.delBtn') }}</el-button>
45
45
  </template>
46
46
  </el-table-column>
@@ -67,7 +67,6 @@ import { allDictTypes, dataMasterEntity } from './options';
67
67
  const dictRefs = useDict(...allDictTypes);
68
68
  const { t } = useI18n();
69
69
  const router = useRouter();
70
- const pageI18nKey = '{{I18N_NAMESPACE}}';
71
70
 
72
71
  const excelUploadRef = ref();
73
72
  const showSearch = ref(true);
@@ -85,7 +84,7 @@ const resolveLabel = (labelKey?: string, fallback = '') => {
85
84
  return translated === labelKey ? fallback : translated;
86
85
  };
87
86
 
88
- const actionLabel = (action: string) => t(`${pageI18nKey}.actions.${action}`);
87
+ const commonActionLabel = (action: string) => t('common.actions.' + action);
89
88
 
90
89
  const visibleTableColumns = computed(() =>
91
90
  Object.entries(dataMasterEntity)
@@ -118,13 +117,13 @@ const handleEdit = (id: string) => {
118
117
  };
119
118
 
120
119
  const handleQuickAction = async (row: any, actionType: string) => {
121
- const actionName = actionLabel(actionType);
120
+ const actionName = commonActionLabel(actionType);
122
121
  try {
123
- await useMessageBox().confirm(t(`${pageI18nKey}.messages.quickActionConfirm`, { action: actionName }));
122
+ await useMessageBox().confirm(t('common.messages.quickActionConfirm', { action: actionName }));
124
123
  useMessage().success(
125
124
  actionType === 'submit'
126
- ? t(`${pageI18nKey}.messages.quickSubmitSuccess`)
127
- : t(`${pageI18nKey}.messages.quickFlowSuccess`)
125
+ ? t('common.messages.quickSubmitSuccess')
126
+ : t('common.messages.quickFlowSuccess')
128
127
  );
129
128
  getDataList();
130
129
  } catch {}
@@ -23,7 +23,6 @@ import { allDictTypes, dataMasterEntity } from './options';
23
23
 
24
24
  const dictRefs = useDict(...allDictTypes);
25
25
  const { t } = useI18n();
26
- const pageI18nKey = '{{I18N_NAMESPACE}}';
27
26
  const emit = defineEmits(['refresh']);
28
27
 
29
28
  const dataFormRef = ref();
@@ -47,9 +46,9 @@ const getMasterFieldLabel = (prop: string) => {
47
46
  return resolveLabel(config?.labelKey, config?.label || prop);
48
47
  };
49
48
  const getDictOptions = (dictType?: string) => (dictType ? dictRefs[dictType]?.value || [] : []);
50
- const inputPlaceholder = (label: string) => t(`${pageI18nKey}.placeholders.input`, { label });
51
- const selectPlaceholder = (label: string) => t(`${pageI18nKey}.placeholders.select`, { label });
52
- const fieldRequiredMessage = (prop: string) => t(`${pageI18nKey}.messages.required`, { label: getMasterFieldLabel(prop) });
49
+ const inputPlaceholder = (label: string) => t('common.placeholders.input', { label });
50
+ const selectPlaceholder = (label: string) => t('common.placeholders.select', { label });
51
+ const fieldRequiredMessage = (prop: string) => t('common.messages.required', { label: getMasterFieldLabel(prop) });
53
52
 
54
53
  const form = reactive({
55
54
  {{FORM_DEFAULTS}}
@@ -65,7 +64,7 @@ const get{{CLASS_NAME}}Data = async (id: string) => {
65
64
  const { data } = await getObj({ {{PK_ATTR}}: id });
66
65
  Object.assign(form, data[0] || {});
67
66
  } catch (error) {
68
- useMessage().error(t(`${pageI18nKey}.messages.fetchError`));
67
+ useMessage().error(t('common.messages.fetchError'));
69
68
  } finally {
70
69
  loading.value = false;
71
70
  }
@@ -101,11 +100,11 @@ const onSubmit = async () => {
101
100
 
102
101
  try {
103
102
  form.{{PK_ATTR}} ? await putObj(form) : await addObj(form);
104
- useMessage().success(form.{{PK_ATTR}} ? t(`${pageI18nKey}.messages.updateSuccess`) : t(`${pageI18nKey}.messages.createSuccess`));
103
+ useMessage().success(form.{{PK_ATTR}} ? t('common.editSuccessText') : t('common.addSuccessText'));
105
104
  visible.value = false;
106
105
  emit('refresh');
107
106
  } catch (err: any) {
108
- useMessage().error(err.msg || t(`${pageI18nKey}.messages.submitError`));
107
+ useMessage().error(err.msg || t('common.messages.submitError'));
109
108
  } finally {
110
109
  loading.value = false;
111
110
  }
@@ -29,7 +29,6 @@ const dictRefs = useDict(...allDictTypes);
29
29
  const { t } = useI18n();
30
30
  const route = useRoute();
31
31
  const router = useRouter();
32
- const pageI18nKey = '{{I18N_NAMESPACE}}';
33
32
 
34
33
  const dataFormRef = ref();
35
34
  const loading = ref(false);
@@ -52,9 +51,9 @@ const getMasterFieldLabel = (prop: string) => {
52
51
  return resolveLabel(config?.labelKey, config?.label || prop);
53
52
  };
54
53
  const getDictOptions = (dictType?: string) => (dictType ? dictRefs[dictType]?.value || [] : []);
55
- const inputPlaceholder = (label: string) => t(`${pageI18nKey}.placeholders.input`, { label });
56
- const selectPlaceholder = (label: string) => t(`${pageI18nKey}.placeholders.select`, { label });
57
- const fieldRequiredMessage = (prop: string) => t(`${pageI18nKey}.messages.required`, { label: getMasterFieldLabel(prop) });
54
+ const inputPlaceholder = (label: string) => t('common.placeholders.input', { label });
55
+ const selectPlaceholder = (label: string) => t('common.placeholders.select', { label });
56
+ const fieldRequiredMessage = (prop: string) => t('common.messages.required', { label: getMasterFieldLabel(prop) });
58
57
 
59
58
  const form = reactive({
60
59
  {{FORM_DEFAULTS}}
@@ -70,7 +69,7 @@ const get{{CLASS_NAME}}Data = async (id: string) => {
70
69
  const { data } = await getObj({ {{PK_ATTR}}: id });
71
70
  Object.assign(form, data[0] || {});
72
71
  } catch (error) {
73
- useMessage().error(t(`${pageI18nKey}.messages.fetchError`));
72
+ useMessage().error(t('common.messages.fetchError'));
74
73
  } finally {
75
74
  loading.value = false;
76
75
  }
@@ -117,10 +116,10 @@ const onSubmit = async () => {
117
116
 
118
117
  try {
119
118
  form.{{PK_ATTR}} ? await putObj(form) : await addObj(form);
120
- useMessage().success(form.{{PK_ATTR}} ? t(`${pageI18nKey}.messages.updateSuccess`) : t(`${pageI18nKey}.messages.createSuccess`));
119
+ useMessage().success(form.{{PK_ATTR}} ? t('common.editSuccessText') : t('common.addSuccessText'));
121
120
  closeCurrentPage();
122
121
  } catch (err: any) {
123
- useMessage().error(err.msg || t(`${pageI18nKey}.messages.submitError`));
122
+ useMessage().error(err.msg || t('common.messages.submitError'));
124
123
  } finally {
125
124
  loading.value = false;
126
125
  }
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.7';
8
+ const SERVER_VERSION = '0.1.8';
9
9
  const PROTOCOL_VERSION = '2024-11-05';
10
10
  const TOOL_NAME = 'worsoft_codegen_local_generate_frontend';
11
11
  const TEMPLATE_LIBRARY_ROOT = path.resolve(__dirname, '..', 'template');
@@ -324,6 +324,30 @@ function buildI18nNamespace(model) {
324
324
  return buildI18nNamespaceSegments(model).join('.');
325
325
  }
326
326
 
327
+ function removeFeatureCommonLocaleSections(localeObject, model) {
328
+ if (!isPlainObject(localeObject)) {
329
+ return localeObject;
330
+ }
331
+
332
+ const segments = buildI18nNamespaceSegments(model);
333
+ let cursor = localeObject;
334
+ for (let index = 0; index < segments.length; index += 1) {
335
+ const segment = segments[index];
336
+ if (!isPlainObject(cursor[segment])) {
337
+ return localeObject;
338
+ }
339
+ if (index === segments.length - 1) {
340
+ delete cursor[segment].placeholders;
341
+ delete cursor[segment].actions;
342
+ delete cursor[segment].messages;
343
+ return localeObject;
344
+ }
345
+ cursor = cursor[segment];
346
+ }
347
+
348
+ return localeObject;
349
+ }
350
+
327
351
  function buildFieldLabelKey(model, field) {
328
352
  return `${buildI18nNamespace(model)}.fields.${field.attrName}`;
329
353
  }
@@ -340,26 +364,6 @@ function buildLocaleLeaf(model) {
340
364
  const leaf = {
341
365
  title: model.tableComment,
342
366
  fields: Object.fromEntries(model.visibleFields.map((field) => [field.attrName, stripDictAnnotation(field.comment)])),
343
- placeholders: {
344
- input: '请输入{label}',
345
- select: '请选择{label}',
346
- },
347
- actions: {
348
- save: '保存',
349
- submit: '提交',
350
- flow: '流转',
351
- back: '返回',
352
- },
353
- messages: {
354
- required: '{label}不能为空',
355
- fetchError: '获取数据失败',
356
- submitError: '提交失败',
357
- createSuccess: '添加成功',
358
- updateSuccess: '修改成功',
359
- quickSubmitSuccess: '提交操作成功',
360
- quickFlowSuccess: '流转操作成功',
361
- quickActionConfirm: '确定要{action}该记录吗?',
362
- },
363
367
  };
364
368
 
365
369
  if (model.children.length) {
@@ -399,7 +403,8 @@ function prepareZhCnLocaleFile(model) {
399
403
  const currentObject = exists ? parseExportDefaultObject(currentContent) : null;
400
404
  const generatedObject = buildZhCnLocaleObject(model);
401
405
  const isCompatible = !exists || isPlainObject(currentObject);
402
- const mergedObject = isCompatible ? deepMergeMissing(currentObject || {}, generatedObject) : null;
406
+ const sanitizedCurrentObject = isCompatible ? removeFeatureCommonLocaleSections(currentObject || {}, model) : null;
407
+ const mergedObject = isCompatible ? deepMergeMissing(sanitizedCurrentObject || {}, generatedObject) : null;
403
408
 
404
409
  return {
405
410
  path: localePath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worsoft-frontend-codegen-local-mcp",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Worsoft frontend local-template code generation MCP server.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "worsoft <sw@worsoft.vip>",