worsoft-frontend-codegen-local-mcp 0.1.71 → 0.1.76

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.
@@ -48,6 +48,7 @@ import { fetchList, delObjs{{DICT_API_IMPORTS}} } from '/@/api/{{API_MODULE_PATH
48
48
  import { useMessage, useMessageBox } from '/@/hooks/message';
49
49
  // 字典数据加载
50
50
  import { useDict } from '/@/hooks/dict';
51
+ {{DICT_SEMANTIC_IMPORT_BLOCK}}
51
52
  // 列表页字段元数据能力
52
53
  import { useCrudPageMeta } from '/@/hooks/useCrudPageMeta';
53
54
  // 列表页查询与分页状态
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.71';
8
+ const SERVER_VERSION = '0.1.76';
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');
@@ -243,6 +243,11 @@ export const DictSemanticValues = {
243
243
  terminated: '3',
244
244
  completed: '4',
245
245
  },
246
+ addStartStop: {
247
+ added: '0',
248
+ started: '1',
249
+ disabled: '2',
250
+ },
246
251
  } as const;
247
252
  `;
248
253
 
@@ -794,12 +799,6 @@ function buildLocaleLeaf(model) {
794
799
  fields: Object.fromEntries(model.optionFields.map((field) => [field.attrName, stripDictAnnotation(field.comment)])),
795
800
  };
796
801
 
797
- if (hasBusinessBillStateEditControl(model)) {
798
- leaf.messages = {
799
- completedCannotDelete: '单据状态为已完成的数据不能删除',
800
- };
801
- }
802
-
803
802
  if (model.children.length) {
804
803
  leaf.children = Object.fromEntries(
805
804
  model.children.map((childModel) => [
@@ -1404,8 +1403,8 @@ function normalizeStructuredField(inputField, index, contextLabel) {
1404
1403
  }
1405
1404
 
1406
1405
  const { length, scale } = normalizeStructuredLengthAndScale(inputField.length ?? inputField.maxLength, inputField.scale);
1407
- const explicitFormType = normalizeStructuredFormType(inputField.formType || inputField.componentType);
1408
- const formType = type === 'DATE' && explicitFormType === 'datetime' ? 'date' : explicitFormType;
1406
+ const explicitFormType = normalizeStructuredFormType(inputField.formType || inputField.componentType);
1407
+ const formType = explicitFormType;
1409
1408
  const explicitQueryType =
1410
1409
  inputField.queryType === undefined || inputField.queryType === null || inputField.queryType === ''
1411
1410
  ? undefined
@@ -1428,7 +1427,7 @@ function normalizeStructuredField(inputField, index, contextLabel) {
1428
1427
  dictType: normalizeDictType(inputField.dictType),
1429
1428
  notNull: parseBooleanLike(inputField.required, false),
1430
1429
  defaultValue: normalizeDefaultValue(inputField.defaultValue),
1431
- readonly: parseBooleanLike(inputField.readonly ?? inputField.disabled, false),
1430
+ readonly: parseBooleanLike(inputField.readonly, false),
1432
1431
  show,
1433
1432
  listShow,
1434
1433
  formShow,
@@ -2107,15 +2106,17 @@ function renderFilterType(field) {
2107
2106
  return ` ${field.attrName}: 30,`;
2108
2107
  }
2109
2108
 
2110
- function renderDefaultLine(field) {
2111
- if (field.attrName === 'createUserId') return ` ${field.attrName}: Session.getUserId(),`;
2112
- if (field.attrName === 'createUser') return ` ${field.attrName}: Session.getUsername(),`;
2113
- if (field.attrName === 'billDate') return ` ${field.attrName}: moment(new Date()).format('YYYY-MM-DD'),`;
2114
- if (field.attrName === 'billStateId' || field.fieldName === 'bill_state_id') return ` ${field.attrName}: '0',`;
2115
- if (field.attrName === 'createTime') return ` ${field.attrName}: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'),`;
2116
- if (field.formType === 'number' || field.formType === 'microme-operator') return ` ${field.attrName}: 0,`;
2117
- return ` ${field.attrName}: '',`;
2118
- }
2109
+ function renderDefaultLine(field, options = {}) {
2110
+ if (field.attrName === 'createUserId') return ` ${field.attrName}: Session.getUserId(),`;
2111
+ if (field.attrName === 'createUser') return ` ${field.attrName}: Session.getUsername(),`;
2112
+ if (field.attrName === 'billDate') return ` ${field.attrName}: moment(new Date()).format('YYYY-MM-DD'),`;
2113
+ if (field.attrName === 'billStateId' || field.fieldName === 'bill_state_id') {
2114
+ return options.useDictSemantic ? ` ${field.attrName}: DictSemanticValues.billState.editing,` : ` ${field.attrName}: '',`;
2115
+ }
2116
+ if (field.attrName === 'createTime') return ` ${field.attrName}: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'),`;
2117
+ if (field.formType === 'number' || field.formType === 'microme-operator') return ` ${field.attrName}: 0,`;
2118
+ return ` ${field.attrName}: '',`;
2119
+ }
2119
2120
 
2120
2121
  function renderFormRulesV2(fields) {
2121
2122
  return fields
@@ -2124,13 +2125,14 @@ function renderFormRulesV2(fields) {
2124
2125
  .join('\n');
2125
2126
  }
2126
2127
 
2127
- function renderFormDefaults(model) {
2128
- const lines = [` ${model.pk.attrName}: '',`];
2129
- for (const field of model.fields.filter((item) => item.fieldName !== model.pk.fieldName && !item.isAudit)) lines.push(renderDefaultLine(field));
2130
- lines.push(` version: 1,`);
2131
- lines.push(` tenantId: Session.getTenant(),`);
2132
- return lines.join('\n');
2133
- }
2128
+ function renderFormDefaults(model) {
2129
+ const lines = [` ${model.pk.attrName}: '',`];
2130
+ const useDictSemantic = hasBusinessBillStateEditControl(model);
2131
+ for (const field of model.fields.filter((item) => item.fieldName !== model.pk.fieldName && !item.isAudit)) lines.push(renderDefaultLine(field, { useDictSemantic }));
2132
+ lines.push(` version: 1,`);
2133
+ lines.push(` tenantId: Session.getTenant(),`);
2134
+ return lines.join('\n');
2135
+ }
2134
2136
 
2135
2137
  function renderChildTempDefaults(childModel) {
2136
2138
  if (!childModel) return '';
@@ -2842,9 +2844,9 @@ function renderMultiLevelSchemaListSlot(levelVarName, activeKeyVarName, activeMo
2842
2844
  ' <!-- 删除当前字典数据 -->',
2843
2845
  ` <el-button v-if="showModuleAction(${activeModuleVarName}.key, 'delete', row)" icon="delete" text type="primary" @click="handleDelete(${activeModuleVarName}.key, row)">{{ t('common.delBtn') }}</el-button>`,
2844
2846
  ' <!-- 启用当前字典数据 -->',
2845
- ` <el-button v-if="showModuleAction(${activeModuleVarName}.key, 'enable', row)" icon="circle-check" text type="primary" @click="handleEnable(${activeModuleVarName}.key, row)">闁告凹鍨抽弫?/el-button>`,
2847
+ ` <el-button v-if="showModuleAction(${activeModuleVarName}.key, 'enable', row)" icon="circle-check" text type="primary" @click="handleEnable(${activeModuleVarName}.key, row)">{{ t('common.actions.enable') }}</el-button>`,
2846
2848
  ' <!-- 禁用当前字典数据 -->',
2847
- ` <el-button v-if="showModuleAction(${activeModuleVarName}.key, 'disable', row)" icon="remove" text type="primary" @click="handleDisable(${activeModuleVarName}.key, row)">缂佸倷鑳堕弫?/el-button>`,
2849
+ ` <el-button v-if="showModuleAction(${activeModuleVarName}.key, 'disable', row)" icon="remove" text type="primary" @click="handleDisable(${activeModuleVarName}.key, row)">{{ t('common.actions.disable') }}</el-button>`,
2848
2850
  ` </template>`,
2849
2851
  ` </SchemaListTable>`,
2850
2852
  ' </div>',
@@ -2987,10 +2989,12 @@ ${formComponents}
2987
2989
  <script setup lang="ts" name="system${model.className}">
2988
2990
  // 通用消息与确认弹窗
2989
2991
  import { useMessage, useMessageBox } from '/@/hooks/message';
2990
- // 字典数据加载
2991
- import { useDict } from '/@/hooks/dict';
2992
- // 多层字典元数据能力
2993
- import { useMultiLevelDictMeta } from '/@/hooks/useMultiLevelDictMeta';
2992
+ // 字典数据加载
2993
+ import { useDict } from '/@/hooks/dict';
2994
+ // 字典语义值
2995
+ import { DictSemanticValues } from '/@/enums/dict-semantic';
2996
+ // 多层字典元数据能力
2997
+ import { useMultiLevelDictMeta } from '/@/hooks/useMultiLevelDictMeta';
2994
2998
  // 多层字典页面状态能力
2995
2999
  import { useMultiLevelDictPage } from '/@/hooks/useMultiLevelDictPage';
2996
3000
  // 统一列表工具栏组件
@@ -3043,10 +3047,12 @@ const {
3043
3047
  const resolveModuleTitle = (moduleConfig: any) => resolveLabel(moduleConfig?.titleKey, moduleConfig?.key || '');
3044
3048
  // 读取字典选项
3045
3049
  const getDictOptions = (dictType?: string) => (dictType ? dictRefs[dictType]?.value || [] : []);
3046
- // 判断状态是否为启用
3047
- const isStatusEnabled = (value: any) => ['1', 1, true, 'true', 'enable', 'enabled'].includes(value);
3048
- const isStatusNew = (value: any) => ['0', 0, false, 'false', 'new', '閺傛澘顤?].includes(value);
3049
- const isStatusNewOrDisabled = (value: any) => ['0', 0, false, 'false', 'new', '閺傛澘顤?, '2', '缁備胶鏁?, 'disabled'].includes(value);
3050
+ // 规范化字典状态值
3051
+ const normalizeStatusValue = (value: any) => String(value ?? '');
3052
+ // 判断状态是否为启用
3053
+ const isStatusEnabled = (value: any) => normalizeStatusValue(value) === DictSemanticValues.addStartStop.started;
3054
+ const isStatusNew = (value: any) => normalizeStatusValue(value) === DictSemanticValues.addStartStop.added;
3055
+ const isStatusNewOrDisabled = (value: any) => [DictSemanticValues.addStartStop.added, DictSemanticValues.addStartStop.disabled].includes(normalizeStatusValue(value));
3050
3056
  // 控制行内动作按钮显隐
3051
3057
  const showModuleAction = (moduleKey: string, action: 'edit' | 'delete' | 'enable' | 'disable', row: any): boolean => {
3052
3058
  const moduleConfig = moduleConfigs[moduleKey];
@@ -3268,14 +3274,16 @@ function renderSingleTableDialogActions(model, permissionPrefix) {
3268
3274
  return lines.join('\n');
3269
3275
  }
3270
3276
 
3271
- function renderSingleTableDialogDictHelpers(model) {
3272
- if (model.pageType !== 'dict' || !model.statusField) return '';
3273
- const statusField = model.statusField;
3274
- return [
3275
- "// 判断状态是否为启用",
3276
- "const isStatusEnabled = (value: any) => ['1', 1, true, 'true', 'enable', 'enabled'].includes(value);",
3277
- "const isStatusNew = (value: any) => ['0', 0, false, 'false', 'new', '閺傛澘顤?].includes(value);",
3278
- "const isStatusNewOrDisabled = (value: any) => ['0', 0, false, 'false', 'new', '閺傛澘顤?, '2', '缁備胶鏁?, 'disabled'].includes(value);",
3277
+ function renderSingleTableDialogDictHelpers(model) {
3278
+ if (model.pageType !== 'dict' || !model.statusField) return '';
3279
+ const statusField = model.statusField;
3280
+ return [
3281
+ "// 规范化字典状态值",
3282
+ "const normalizeStatusValue = (value: any) => String(value ?? '');",
3283
+ "// 判断状态是否为启用",
3284
+ "const isStatusEnabled = (value: any) => normalizeStatusValue(value) === DictSemanticValues.addStartStop.started;",
3285
+ "const isStatusNew = (value: any) => normalizeStatusValue(value) === DictSemanticValues.addStartStop.added;",
3286
+ "const isStatusNewOrDisabled = (value: any) => [DictSemanticValues.addStartStop.added, DictSemanticValues.addStartStop.disabled].includes(normalizeStatusValue(value));",
3279
3287
  '',
3280
3288
  "// 控制字典列表动作按钮显隐",
3281
3289
  "const showDictAction = (action: 'edit' | 'delete' | 'enable' | 'disable', row: any): boolean => {",
@@ -3362,7 +3370,7 @@ function renderBusinessDeleteGuard(model) {
3362
3370
  const i18nNamespace = buildI18nNamespace(model);
3363
3371
  return [
3364
3372
  ' if (rows.some((row) => !showDeleteAction(row))) {',
3365
- ` useMessage().warning(t('${i18nNamespace}.messages.completedCannotDelete'));`,
3373
+ " useMessage().warning(t('common.messages.completedBillCannotDelete'));",
3366
3374
  ' return;',
3367
3375
  ' }',
3368
3376
  '',
@@ -3467,9 +3475,10 @@ function buildReplacements(model, sharedSupport) {
3467
3475
  I18N_NAMESPACE: i18nNamespace,
3468
3476
  PERMISSION_PREFIX: permissionPrefix,
3469
3477
  ACTION_COLUMN_WIDTH: model.pageType === 'dict' && model.statusField ? 300 : 180,
3470
- LIST_ACTIONS: renderSingleTableDialogActions(model, permissionPrefix),
3471
- DICT_API_IMPORTS: model.pageType === 'dict' && model.statusField ? ', enableObj, disableObj' : '',
3472
- DICT_LIST_HELPERS: renderSingleTableDialogDictHelpers(model),
3478
+ LIST_ACTIONS: renderSingleTableDialogActions(model, permissionPrefix),
3479
+ DICT_API_IMPORTS: model.pageType === 'dict' && model.statusField ? ', enableObj, disableObj' : '',
3480
+ DICT_SEMANTIC_IMPORT_BLOCK: model.pageType === 'dict' && model.statusField ? "// 字典语义值\nimport { DictSemanticValues } from '/@/enums/dict-semantic';" : '',
3481
+ DICT_LIST_HELPERS: renderSingleTableDialogDictHelpers(model),
3473
3482
  DICT_API_FUNCTIONS: renderSingleTableDialogDictApiFunctions(model),
3474
3483
  BUSINESS_STATUS_IMPORTS: renderBusinessStatusImports(model),
3475
3484
  BUSINESS_FORM_STATUS_IMPORTS: renderBusinessStatusImports(model),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worsoft-frontend-codegen-local-mcp",
3
- "version": "0.1.71",
3
+ "version": "0.1.76",
4
4
  "description": "Worsoft frontend local-template code generation MCP server.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "worsoft <sw@worsoft.vip>",