worsoft-frontend-codegen-local-mcp 0.1.88 → 0.1.90
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.
|
@@ -22,15 +22,11 @@
|
|
|
22
22
|
</div>
|
|
23
23
|
</template>
|
|
24
24
|
<!-- 主子表表单:按 PRD 表单显隐和顺序渲染字段 -->
|
|
25
|
-
<el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading">
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{{FORM_FIELDS}}
|
|
29
|
-
</el-row>
|
|
30
|
-
<!-- 子表明细区:按 children 配置渲染多个子表 -->
|
|
31
|
-
<el-row :gutter="24">
|
|
25
|
+
<el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading" label-width="120px">
|
|
26
|
+
<el-collapse v-model="activeCollapseNames">
|
|
27
|
+
{{FORM_COLLAPSE_SECTIONS}}
|
|
32
28
|
{{CHILD_SECTIONS}}
|
|
33
|
-
</el-
|
|
29
|
+
</el-collapse>
|
|
34
30
|
</el-form>
|
|
35
31
|
</el-card>
|
|
36
32
|
</div>
|
|
@@ -72,6 +68,7 @@ const pageI18nKey = '{{I18N_NAMESPACE}}';
|
|
|
72
68
|
|
|
73
69
|
// 表单引用
|
|
74
70
|
const dataFormRef = ref();
|
|
71
|
+
const activeCollapseNames = ref({{ACTIVE_COLLAPSE_NAMES}});
|
|
75
72
|
// 页面加载状态
|
|
76
73
|
const loading = ref(false);
|
|
77
74
|
// 是否详情模式
|
|
@@ -22,11 +22,10 @@
|
|
|
22
22
|
</div>
|
|
23
23
|
</template>
|
|
24
24
|
<!-- 主表表单:按 PRD 表单显隐和顺序渲染字段 -->
|
|
25
|
-
<el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading">
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</el-row>
|
|
25
|
+
<el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading" label-width="120px">
|
|
26
|
+
<el-collapse v-model="activeCollapseNames">
|
|
27
|
+
{{FORM_COLLAPSE_SECTIONS}}
|
|
28
|
+
</el-collapse>
|
|
30
29
|
</el-form>
|
|
31
30
|
</el-card>
|
|
32
31
|
</div>
|
|
@@ -63,6 +62,7 @@ const { closeCurrentPage } = useCloseCurrentPage();
|
|
|
63
62
|
|
|
64
63
|
// 表单引用
|
|
65
64
|
const dataFormRef = ref();
|
|
65
|
+
const activeCollapseNames = ref({{ACTIVE_COLLAPSE_NAMES}});
|
|
66
66
|
// 页面加载状态
|
|
67
67
|
const loading = ref(false);
|
|
68
68
|
// 是否详情模式
|
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.90';
|
|
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');
|
|
@@ -1228,13 +1228,19 @@ function readUtf8File(filePath) {
|
|
|
1228
1228
|
return stripBom(fs.readFileSync(filePath, 'utf8'));
|
|
1229
1229
|
}
|
|
1230
1230
|
|
|
1231
|
-
function normalizeDictType(value) {
|
|
1232
|
-
const normalized = String(value || '').trim();
|
|
1233
|
-
if (!normalized || normalized === '-' || normalized === '/') {
|
|
1234
|
-
return null;
|
|
1235
|
-
}
|
|
1236
|
-
return normalized.replace(/^['"`]+|['"`]+$/g, '');
|
|
1237
|
-
}
|
|
1231
|
+
function normalizeDictType(value) {
|
|
1232
|
+
const normalized = String(value || '').trim();
|
|
1233
|
+
if (!normalized || normalized === '-' || normalized === '/') {
|
|
1234
|
+
return null;
|
|
1235
|
+
}
|
|
1236
|
+
return normalized.replace(/^['"`]+|['"`]+$/g, '');
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
function normalizeDictTypeFromSourceLabel(value) {
|
|
1240
|
+
const normalized = normalizeDictType(value);
|
|
1241
|
+
if (!normalized) return null;
|
|
1242
|
+
return /^[a-z][a-z0-9_]*$/.test(normalized) ? normalized : null;
|
|
1243
|
+
}
|
|
1238
1244
|
|
|
1239
1245
|
function stripDictAnnotation(label) {
|
|
1240
1246
|
const text = String(label || '').trim();
|
|
@@ -1433,29 +1439,33 @@ function normalizeStructuredField(inputField, index, contextLabel) {
|
|
|
1433
1439
|
throw new Error(contextLabel + '[' + index + '] is missing required field: type');
|
|
1434
1440
|
}
|
|
1435
1441
|
|
|
1436
|
-
const { length, scale } = normalizeStructuredLengthAndScale(inputField.length ?? inputField.maxLength, inputField.scale);
|
|
1437
|
-
const explicitFormType = normalizeStructuredFormType(inputField.formType || inputField.componentType);
|
|
1438
|
-
const formType = explicitFormType;
|
|
1439
|
-
const
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
+
const { length, scale } = normalizeStructuredLengthAndScale(inputField.length ?? inputField.maxLength, inputField.scale);
|
|
1443
|
+
const explicitFormType = normalizeStructuredFormType(inputField.formType || inputField.componentType);
|
|
1444
|
+
const formType = explicitFormType;
|
|
1445
|
+
const dictType = normalizeDictType(inputField.dictType) || normalizeDictTypeFromSourceLabel(inputField.sourceDictLabel);
|
|
1446
|
+
const explicitQueryType =
|
|
1447
|
+
inputField.queryType === undefined || inputField.queryType === null || inputField.queryType === ''
|
|
1448
|
+
? undefined
|
|
1442
1449
|
: Number.parseInt(String(inputField.queryType), 10);
|
|
1443
1450
|
const show = parseBooleanLike(inputField.show, true);
|
|
1444
|
-
const listShow = parseBooleanLike(inputField.listShow, show);
|
|
1445
|
-
const formShow = parseBooleanLike(inputField.formShow, show);
|
|
1446
|
-
const formOrder = parseOptionalOrder(inputField.formOrder, contextLabel + '[' + index + '].formOrder');
|
|
1447
|
-
|
|
1448
|
-
|
|
1451
|
+
const listShow = parseBooleanLike(inputField.listShow, show);
|
|
1452
|
+
const formShow = parseBooleanLike(inputField.formShow, show);
|
|
1453
|
+
const formOrder = parseOptionalOrder(inputField.formOrder, contextLabel + '[' + index + '].formOrder');
|
|
1454
|
+
if (formShow === false && formOrder !== undefined) {
|
|
1455
|
+
throw new Error(`${contextLabel}[${index}].formOrder must be empty when formShow=false`);
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
return {
|
|
1449
1459
|
fieldName,
|
|
1450
1460
|
attrName: toCamelCase(fieldName),
|
|
1451
1461
|
sqlType: type,
|
|
1452
1462
|
length,
|
|
1453
1463
|
scale,
|
|
1454
1464
|
comment: label,
|
|
1455
|
-
label,
|
|
1456
|
-
description: String(inputField.description || '').trim(),
|
|
1457
|
-
formType,
|
|
1458
|
-
dictType
|
|
1465
|
+
label,
|
|
1466
|
+
description: String(inputField.description || '').trim(),
|
|
1467
|
+
formType,
|
|
1468
|
+
dictType,
|
|
1459
1469
|
notNull: parseBooleanLike(inputField.required, false),
|
|
1460
1470
|
defaultValue: normalizeDefaultValue(inputField.defaultValue),
|
|
1461
1471
|
readonly: parseBooleanLike(inputField.readonly, false),
|
|
@@ -1465,13 +1475,13 @@ function normalizeStructuredField(inputField, index, contextLabel) {
|
|
|
1465
1475
|
formOrder,
|
|
1466
1476
|
width: normalizeOptionWidth(inputField.width),
|
|
1467
1477
|
smart: parseBooleanLike(inputField.smart, false),
|
|
1468
|
-
queryType: Number.isNaN(explicitQueryType)
|
|
1469
|
-
? undefined
|
|
1470
|
-
: explicitQueryType !== undefined
|
|
1471
|
-
? explicitQueryType
|
|
1472
|
-
:
|
|
1473
|
-
? 30
|
|
1474
|
-
: undefined,
|
|
1478
|
+
queryType: Number.isNaN(explicitQueryType)
|
|
1479
|
+
? undefined
|
|
1480
|
+
: explicitQueryType !== undefined
|
|
1481
|
+
? explicitQueryType
|
|
1482
|
+
: dictType && listShow
|
|
1483
|
+
? 30
|
|
1484
|
+
: undefined,
|
|
1475
1485
|
sourceKind: normalizeStructuredSourceKind(inputField.sourceKind),
|
|
1476
1486
|
primary: parseBooleanLike(inputField.primary, fieldName === 'id'),
|
|
1477
1487
|
};
|
|
@@ -1714,6 +1724,73 @@ function assertParseResultPayloadConsistency(parseResult, mcpPayload, parseResul
|
|
|
1714
1724
|
}
|
|
1715
1725
|
}
|
|
1716
1726
|
|
|
1727
|
+
function collectPayloadFieldGroups(mcpPayload) {
|
|
1728
|
+
const groups = [];
|
|
1729
|
+
if (Array.isArray(mcpPayload.fields)) {
|
|
1730
|
+
groups.push({ path: 'mcpPayload.fields', fields: mcpPayload.fields });
|
|
1731
|
+
}
|
|
1732
|
+
if (Array.isArray(mcpPayload.children)) {
|
|
1733
|
+
mcpPayload.children.forEach((child, childIndex) => {
|
|
1734
|
+
if (Array.isArray(child.fields)) {
|
|
1735
|
+
groups.push({ path: `mcpPayload.children[${childIndex}].fields`, fields: child.fields });
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
if (Array.isArray(mcpPayload.levels)) {
|
|
1740
|
+
mcpPayload.levels.forEach((level, levelIndex) => {
|
|
1741
|
+
if (!Array.isArray(level.modules)) return;
|
|
1742
|
+
level.modules.forEach((module, moduleIndex) => {
|
|
1743
|
+
if (Array.isArray(module.fields)) {
|
|
1744
|
+
groups.push({ path: `mcpPayload.levels[${levelIndex}].modules[${moduleIndex}].fields`, fields: module.fields });
|
|
1745
|
+
}
|
|
1746
|
+
});
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
return groups;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
function normalizeFieldSet(values) {
|
|
1753
|
+
if (!Array.isArray(values)) return new Set();
|
|
1754
|
+
return new Set(
|
|
1755
|
+
values
|
|
1756
|
+
.map((item) => (typeof item === 'string' ? item : item && (item.fieldName || item.name)))
|
|
1757
|
+
.filter(Boolean)
|
|
1758
|
+
.map((item) => String(item).trim())
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
function assertVisibilityMatrixConsistency(parseResult, mcpPayload, parseResultPath) {
|
|
1763
|
+
if (!parseResult.visibilityMatrix || typeof parseResult.visibilityMatrix !== 'object') return;
|
|
1764
|
+
const matrixGroups = Array.isArray(parseResult.visibilityMatrix.groups) ? parseResult.visibilityMatrix.groups : [];
|
|
1765
|
+
const fallbackVisibleFields = normalizeFieldSet(parseResult.visibilityMatrix.visibleFormFields);
|
|
1766
|
+
const fallbackHiddenFields = normalizeFieldSet(parseResult.visibilityMatrix.explicitHiddenFormFields || parseResult.visibilityMatrix.hiddenFormFields);
|
|
1767
|
+
if (!matrixGroups.length && !fallbackVisibleFields.size && !fallbackHiddenFields.size) return;
|
|
1768
|
+
|
|
1769
|
+
const issues = [];
|
|
1770
|
+
for (const group of collectPayloadFieldGroups(mcpPayload)) {
|
|
1771
|
+
const matrixGroup = matrixGroups.find((item) => item && item.path === group.path);
|
|
1772
|
+
const visibleFields = matrixGroup ? normalizeFieldSet(matrixGroup.visibleFormFields) : fallbackVisibleFields;
|
|
1773
|
+
const hiddenFields = matrixGroup ? normalizeFieldSet(matrixGroup.explicitHiddenFormFields || matrixGroup.hiddenFormFields) : fallbackHiddenFields;
|
|
1774
|
+
if (!visibleFields.size && !hiddenFields.size) continue;
|
|
1775
|
+
|
|
1776
|
+
for (const field of group.fields) {
|
|
1777
|
+
if (!field || typeof field !== 'object' || !field.fieldName) continue;
|
|
1778
|
+
const fieldName = String(field.fieldName);
|
|
1779
|
+
const expectedFormShow = visibleFields.has(fieldName) && !hiddenFields.has(fieldName);
|
|
1780
|
+
if (Boolean(field.formShow) !== expectedFormShow) {
|
|
1781
|
+
issues.push(`${group.path}.${fieldName}.formShow expected ${expectedFormShow} from visibilityMatrix, got ${field.formShow}`);
|
|
1782
|
+
}
|
|
1783
|
+
if (!expectedFormShow && field.formOrder !== undefined && field.formOrder !== null && field.formOrder !== '') {
|
|
1784
|
+
issues.push(`${group.path}.${fieldName}.formOrder must be empty when visibilityMatrix marks it hidden`);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
if (issues.length) {
|
|
1790
|
+
throw new Error(`parseResult visibilityMatrix conflicts with mcpPayload in ${parseResultPath}: ${issues.join('; ')}`);
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1717
1794
|
function resolveGenerationInput(input) {
|
|
1718
1795
|
if (!input.parseResultPath) {
|
|
1719
1796
|
return { generationInput: input, parseResultPath: '' };
|
|
@@ -1744,6 +1821,7 @@ function resolveGenerationInput(input) {
|
|
|
1744
1821
|
'moduleName',
|
|
1745
1822
|
]);
|
|
1746
1823
|
assertParseResultPayloadConsistency(parseResult, generationInput, parsed.path);
|
|
1824
|
+
assertVisibilityMatrixConsistency(parseResult, generationInput, parsed.path);
|
|
1747
1825
|
|
|
1748
1826
|
for (const key of ['frontendPath', 'moduleName', 'writeToDisk', 'overwrite', 'writeSupportFiles', 'mergeI18nZh']) {
|
|
1749
1827
|
if (Object.prototype.hasOwnProperty.call(input, key)) {
|
|
@@ -2130,13 +2208,35 @@ function buildModel(safeArgs) {
|
|
|
2130
2208
|
};
|
|
2131
2209
|
}
|
|
2132
2210
|
|
|
2133
|
-
function renderTemplate(templateText, replacements) {
|
|
2134
|
-
let output = templateText;
|
|
2135
|
-
for (const [key, value] of Object.entries(replacements)) {
|
|
2136
|
-
output = output.split('{{' + key + '}}').join(String(value));
|
|
2137
|
-
}
|
|
2138
|
-
return output;
|
|
2139
|
-
}
|
|
2211
|
+
function renderTemplate(templateText, replacements) {
|
|
2212
|
+
let output = templateText;
|
|
2213
|
+
for (const [key, value] of Object.entries(replacements)) {
|
|
2214
|
+
output = output.split('{{' + key + '}}').join(String(value));
|
|
2215
|
+
}
|
|
2216
|
+
return output;
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
function findUnresolvedTemplatePlaceholders(content) {
|
|
2220
|
+
const matches = String(content || '').match(/\{\{[A-Z][A-Z0-9_]*\}\}/g) || [];
|
|
2221
|
+
return [...new Set(matches)];
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
function assertNoUnresolvedTemplatePlaceholders(files) {
|
|
2225
|
+
const issues = files
|
|
2226
|
+
.map((file) => ({
|
|
2227
|
+
type: file.type,
|
|
2228
|
+
path: file.path,
|
|
2229
|
+
placeholders: findUnresolvedTemplatePlaceholders(file.content),
|
|
2230
|
+
}))
|
|
2231
|
+
.filter((item) => item.placeholders.length);
|
|
2232
|
+
|
|
2233
|
+
if (issues.length) {
|
|
2234
|
+
const detail = issues
|
|
2235
|
+
.map((item) => `${item.type}:${path.basename(item.path)} -> ${item.placeholders.join(', ')}`)
|
|
2236
|
+
.join('; ');
|
|
2237
|
+
throw new Error(`MCP template rendering left unresolved placeholders: ${detail}`);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2140
2240
|
|
|
2141
2241
|
function renderFormField(field) {
|
|
2142
2242
|
const label = stripDictAnnotation(field.comment).replace(/'/g, "\\'");
|
|
@@ -2344,23 +2444,24 @@ function renderChildSection(childModel, childCount) {
|
|
|
2344
2444
|
const deleteExpression = `deleteChild(obj, '${childModel.pk.attrName}')`;
|
|
2345
2445
|
|
|
2346
2446
|
return [
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
' <
|
|
2350
|
-
`
|
|
2351
|
-
' <div style="display:flex;align-items:center;gap:8px;">',
|
|
2447
|
+
` <el-collapse-item :title="childSectionTitle('${childModel.listName}')" name="child-${childModel.listName}">`,
|
|
2448
|
+
' <el-row :gutter="24">',
|
|
2449
|
+
' <el-col :span="24" class="mb20">',
|
|
2450
|
+
` <!-- 子表区域:${sanitizeHtmlComment(childModel.comment || childModel.tableName)} -->`,
|
|
2451
|
+
' <div class="mb10" style="display:flex;justify-content:flex-end;align-items:center;gap:8px;">',
|
|
2352
2452
|
` <el-button icon="Plus" type="primary" :disabled="detail" @click="handleAddChild('${childModel.listName}')">{{ t('common.addBtn') }}</el-button>`,
|
|
2353
2453
|
` <el-button icon="Delete" type="danger" plain :disabled="detail || !getSelectedChildRows('${childModel.listName}').length" @click="handleDeleteSelectedChild('${childModel.listName}', '${childModel.pk.attrName}')">{{ t('common.delBtn') }}</el-button>`,
|
|
2354
2454
|
' </div>',
|
|
2355
|
-
'
|
|
2356
|
-
'
|
|
2357
|
-
|
|
2358
|
-
' <el-table-column type="selection" width="55" :selectable="() => !detail" />',
|
|
2455
|
+
' <!-- 子表编辑表格:新增/删除按钮外置,表格内部隐藏新增、删除和序号控制列 -->',
|
|
2456
|
+
` <sc-form-table :ref="(el) => setChildTableRef('${childModel.listName}', el)" v-model="form.${childModel.listName}" :addTemplate="childTemp${childModel.className}" hide-index hide-add hide-delete @delete="(obj) => ${deleteExpression}" :placeholder="t('common.noData')" @selection-change="(rows) => handleChildSelectionChange('${childModel.listName}', rows)">`,
|
|
2457
|
+
' <el-table-column type="selection" width="55" :selectable="() => !detail" />',
|
|
2359
2458
|
childModel.visibleFields.map((field) => renderChildTableColumn(field, childModel.listName)).join('\n'),
|
|
2360
|
-
'
|
|
2361
|
-
'
|
|
2362
|
-
|
|
2363
|
-
|
|
2459
|
+
' </sc-form-table>',
|
|
2460
|
+
' </el-col>',
|
|
2461
|
+
' </el-row>',
|
|
2462
|
+
' </el-collapse-item>',
|
|
2463
|
+
].join('\n');
|
|
2464
|
+
}
|
|
2364
2465
|
|
|
2365
2466
|
function renderChildFormListDefaults(children) {
|
|
2366
2467
|
if (!children.length) return '';
|
|
@@ -2485,7 +2586,7 @@ function renderFieldCommentV2(field, indent = ' ') {
|
|
|
2485
2586
|
return indent + '<!-- ' + label + ' -->';
|
|
2486
2587
|
}
|
|
2487
2588
|
|
|
2488
|
-
function renderFormFieldV2(field) {
|
|
2589
|
+
function renderFormFieldV2(field) {
|
|
2489
2590
|
const prop = field.attrName;
|
|
2490
2591
|
const labelExpr = `getMasterFieldLabel('${prop}')`;
|
|
2491
2592
|
const dictExpr = `getMasterFieldMeta('${prop}')?.dictType`;
|
|
@@ -2584,10 +2685,58 @@ function renderFormFieldV2(field) {
|
|
|
2584
2685
|
` <el-input v-model="form.${prop}" :placeholder="formInputPlaceholder(${labelExpr}, ${disabledBool})"${maxlengthAttr}${disabledAttr} />`,
|
|
2585
2686
|
' </el-form-item>',
|
|
2586
2687
|
' </el-col>',
|
|
2587
|
-
].join('\n');
|
|
2588
|
-
}
|
|
2589
|
-
|
|
2590
|
-
|
|
2688
|
+
].join('\n');
|
|
2689
|
+
}
|
|
2690
|
+
|
|
2691
|
+
const FILL_REPORT_FIELD_NAMES = new Set(['createBy', 'createTime', 'finishedTime']);
|
|
2692
|
+
const FILL_REPORT_FIELD_ORDER = ['createBy', 'createTime', 'finishedTime'];
|
|
2693
|
+
|
|
2694
|
+
function isFillReportField(field) {
|
|
2695
|
+
return FILL_REPORT_FIELD_NAMES.has(String(field?.attrName || field?.fieldName || ''));
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
function renderBusinessFormCollapseItem(title, name, fields) {
|
|
2699
|
+
return [
|
|
2700
|
+
` <el-collapse-item title="${title}" name="${name}">`,
|
|
2701
|
+
' <el-row :gutter="24">',
|
|
2702
|
+
fields.map(renderFormFieldV2).join('\n'),
|
|
2703
|
+
' </el-row>',
|
|
2704
|
+
' </el-collapse-item>',
|
|
2705
|
+
].join('\n');
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
function splitBusinessFormFields(fields) {
|
|
2709
|
+
const fillReportFields = fields
|
|
2710
|
+
.filter(isFillReportField)
|
|
2711
|
+
.sort((left, right) => FILL_REPORT_FIELD_ORDER.indexOf(left.attrName) - FILL_REPORT_FIELD_ORDER.indexOf(right.attrName));
|
|
2712
|
+
if (!fillReportFields.length) {
|
|
2713
|
+
return { basicFields: fields, fillReportFields: [] };
|
|
2714
|
+
}
|
|
2715
|
+
return {
|
|
2716
|
+
basicFields: fields.filter((field) => !isFillReportField(field)),
|
|
2717
|
+
fillReportFields,
|
|
2718
|
+
};
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
function renderBusinessFormCollapseSections(model) {
|
|
2722
|
+
const fields = model.pageType === 'ledger' ? model.visibleFields.map(asReadonlyField) : model.visibleFields;
|
|
2723
|
+
const { basicFields, fillReportFields } = splitBusinessFormFields(fields);
|
|
2724
|
+
const sections = [renderBusinessFormCollapseItem('基本信息', '0', basicFields)];
|
|
2725
|
+
if (fillReportFields.length) {
|
|
2726
|
+
sections.push(renderBusinessFormCollapseItem('填报信息', '1', fillReportFields));
|
|
2727
|
+
}
|
|
2728
|
+
return sections.join('\n');
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
function renderActiveCollapseNames(model) {
|
|
2732
|
+
const fields = model.pageType === 'ledger' ? model.visibleFields.map(asReadonlyField) : model.visibleFields;
|
|
2733
|
+
const names = ['0'];
|
|
2734
|
+
if (fields.some(isFillReportField)) names.push('1');
|
|
2735
|
+
model.children.forEach((childModel) => names.push(`child-${childModel.listName}`));
|
|
2736
|
+
return `[${names.map((name) => `'${name}'`).join(', ')}]`;
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
function renderMultiLevelOptionField(field, model, moduleModel, dictRegistryRefs, indent = ' ') {
|
|
2591
2740
|
const parts = [
|
|
2592
2741
|
`key: '${field.attrName}'`,
|
|
2593
2742
|
`labelKey: '${buildMultiLevelFieldLabelKey(model, moduleModel, field)}'`,
|
|
@@ -4250,10 +4399,12 @@ function buildReplacements(model, sharedSupport) {
|
|
|
4250
4399
|
BUSINESS_FORM_KEEP_ALIVE_COLUMN: model.pageType === 'business' ? ', keep_alive' : '',
|
|
4251
4400
|
BUSINESS_FORM_KEEP_ALIVE_VALUE: model.pageType === 'business' ? ", '1'" : '',
|
|
4252
4401
|
BILL_CODE: deriveBillCode(model),
|
|
4253
|
-
GENERATED_AT: new Date().toISOString(),
|
|
4254
|
-
FORM_FIELDS: (model.pageType === 'ledger' ? model.visibleFields.map(asReadonlyField) : model.visibleFields).map(renderFormFieldV2).join('\n'),
|
|
4255
|
-
|
|
4256
|
-
|
|
4402
|
+
GENERATED_AT: new Date().toISOString(),
|
|
4403
|
+
FORM_FIELDS: (model.pageType === 'ledger' ? model.visibleFields.map(asReadonlyField) : model.visibleFields).map(renderFormFieldV2).join('\n'),
|
|
4404
|
+
FORM_COLLAPSE_SECTIONS: renderBusinessFormCollapseSections(model),
|
|
4405
|
+
ACTIVE_COLLAPSE_NAMES: renderActiveCollapseNames(model),
|
|
4406
|
+
TABLE_COLUMNS: model.gridFields.map((field) => renderTableColumn(field, dictRegistryRefs)).join('\n'),
|
|
4407
|
+
FORM_DEFAULTS: renderFormDefaults(model),
|
|
4257
4408
|
DICT_REGISTRY_IMPORT_BLOCK: model.dictTypes.length ? "import { DictRegistry } from '/@/enums/dict-registry';" : '',
|
|
4258
4409
|
MASTER_OPTION_FIELDS: model.optionFields.map((field) => renderOptionFieldV2(field, buildFieldLabelKey(model, field), dictRegistryRefs)).join('\n'),
|
|
4259
4410
|
CHILD_OPTION_GROUPS: model.children.map((childModel) => renderChildOptionGroupV2(model, childModel, dictRegistryRefs)).join('\n'),
|
|
@@ -4305,11 +4456,12 @@ function renderFiles(model, stylePreset, sharedSupport, localeZhSupport) {
|
|
|
4305
4456
|
},
|
|
4306
4457
|
];
|
|
4307
4458
|
|
|
4308
|
-
if (menuSqlTemplate) {
|
|
4309
|
-
files.push({ type: 'menuSql', path: path.join(menuRoot, `${model.functionName}_menu.sql`), content: renderTemplate(menuSqlTemplate, replacements) });
|
|
4310
|
-
}
|
|
4311
|
-
|
|
4312
|
-
|
|
4459
|
+
if (menuSqlTemplate) {
|
|
4460
|
+
files.push({ type: 'menuSql', path: path.join(menuRoot, `${model.functionName}_menu.sql`), content: renderTemplate(menuSqlTemplate, replacements) });
|
|
4461
|
+
}
|
|
4462
|
+
assertNoUnresolvedTemplatePlaceholders(files);
|
|
4463
|
+
return files;
|
|
4464
|
+
}
|
|
4313
4465
|
|
|
4314
4466
|
function ensureArguments(input) {
|
|
4315
4467
|
if (!input || typeof input !== 'object') throw new Error('Arguments must be an object');
|
package/package.json
CHANGED