20260728225443
This commit is contained in:
1 parent
5ec7aadef9
commit
f6b79ea09a
30 files changed
+1541
-1120
No files matched your search
@@ -4,6 +4,7 @@ import { message, Modal } from "antdv-next";
|
||||
import FmsLoadingOverlay from "@/components/FmsLoadingOverlay.vue";
|
||||
import FmsTree from "@/components/FmsTree.vue";
|
||||
import { loadDataApi, saveObjectApi, nextIdApi, describeApi } from "@/services/api";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import {
|
||||
cloneData,
|
||||
diffRows,
|
||||
@@ -30,6 +31,7 @@ import ModulePowersPanel from "./components/ModulePowersPanel.vue";
|
||||
import ModuleI18nPanel from "./components/ModuleI18nPanel.vue";
|
||||
|
||||
// ---- 状态 ----
|
||||
const appStore = useAppStore();
|
||||
const treeData = ref([]);
|
||||
const treeLoading = ref(false);
|
||||
const expandedTreeKeys = ref([]);
|
||||
@@ -80,8 +82,6 @@ const configSaving = ref(false);
|
||||
const configSyncing = ref(false);
|
||||
const i18nPanelRef = ref(null);
|
||||
const loadedModuleId = ref(null);
|
||||
let configRequestId = 0;
|
||||
let operationId = 0;
|
||||
|
||||
// 使用函数 ref,避免组件位于 TabPane 的 v-for 内时被 Vue 收集成实例数组。
|
||||
function setI18nPanelRef(instance) {
|
||||
@@ -94,10 +94,6 @@ const busy = computed(() => configLoading.value || configSaving.value || configS
|
||||
const syncDisabled = computed(
|
||||
() => busy.value || !String(selectedModule.value?.b_viewtable || "").trim(),
|
||||
);
|
||||
const isCurrentModule = computed(
|
||||
() =>
|
||||
loadedModuleId.value != null && String(loadedModuleId.value) === String(selectedModuleId.value),
|
||||
);
|
||||
// 构建受管多语言项。managedSource 提供模块/字段/权限的受管键来源,
|
||||
// plainSource 提供分组/列表标题等非受管键来源(手动填写,需即时反馈)。
|
||||
function buildI18nItems(managedSource, plainSource) {
|
||||
@@ -245,64 +241,70 @@ async function loadTree() {
|
||||
}
|
||||
|
||||
// ---- 模块配置加载 ----
|
||||
async function loadModuleConfig(moduleId, requestId) {
|
||||
async function loadModuleConfig(moduleId) {
|
||||
configLoading.value = true;
|
||||
try {
|
||||
const id = String(moduleId);
|
||||
const moduleType = findNode(id)?.b_module_type;
|
||||
const requests = [["module", loadDataApi("s_module", `b_id = ${id}`)]];
|
||||
let moduleResponse;
|
||||
let fieldsResponse;
|
||||
let groupsResponse;
|
||||
let listResponse;
|
||||
let editResponse;
|
||||
let queryResponse;
|
||||
let powersResponse;
|
||||
|
||||
if (moduleType === "data") {
|
||||
requests.push(
|
||||
["fields", loadDataApi("s_module_field", `b_module_id = ${id}`, "b_id ASC")],
|
||||
[
|
||||
"groups",
|
||||
loadDataApi("s_module_field_group", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
],
|
||||
[
|
||||
"listConfig",
|
||||
loadDataApi("s_module_field_list", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
],
|
||||
[
|
||||
"editConfig",
|
||||
loadDataApi("s_module_field_edit", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
],
|
||||
[
|
||||
"queryConfig",
|
||||
loadDataApi("s_module_field_query", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
],
|
||||
);
|
||||
const responses = await Promise.all([
|
||||
loadDataApi("s_module", `b_id = ${id}`),
|
||||
loadDataApi("s_module_field", `b_module_id = ${id}`, "b_id ASC"),
|
||||
loadDataApi("s_module_field_group", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
loadDataApi("s_module_field_list", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
loadDataApi("s_module_field_edit", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
loadDataApi("s_module_field_query", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
]);
|
||||
moduleResponse = responses[0];
|
||||
fieldsResponse = responses[1];
|
||||
groupsResponse = responses[2];
|
||||
listResponse = responses[3];
|
||||
editResponse = responses[4];
|
||||
queryResponse = responses[5];
|
||||
} else if (moduleType === "page") {
|
||||
requests.push([
|
||||
"powers",
|
||||
const responses = await Promise.all([
|
||||
loadDataApi("s_module", `b_id = ${id}`),
|
||||
loadDataApi("s_module_power", `b_module_id = ${id}`, "b_xh ASC, b_id ASC"),
|
||||
]);
|
||||
moduleResponse = responses[0];
|
||||
powersResponse = responses[1];
|
||||
} else {
|
||||
moduleResponse = await loadDataApi("s_module", `b_id = ${id}`);
|
||||
}
|
||||
const responses = Object.fromEntries(
|
||||
await Promise.all(requests.map(async ([key, request]) => [key, await request])),
|
||||
);
|
||||
|
||||
if (String(selectedModuleId.value) !== id) return;
|
||||
|
||||
const original = {
|
||||
module: responses.module.data?.[0] || null,
|
||||
fields: responses.fields?.data || [],
|
||||
groups: responses.groups?.data || [],
|
||||
listConfig: responses.listConfig?.data || [],
|
||||
editConfig: responses.editConfig?.data || [],
|
||||
queryConfig: responses.queryConfig?.data || [],
|
||||
powers: responses.powers?.data || [],
|
||||
module: moduleResponse.data?.[0] || null,
|
||||
fields: fieldsResponse ? fieldsResponse.data || [] : [],
|
||||
groups: groupsResponse ? groupsResponse.data || [] : [],
|
||||
listConfig: listResponse ? listResponse.data || [] : [],
|
||||
editConfig: editResponse ? editResponse.data || [] : [],
|
||||
queryConfig: queryResponse ? queryResponse.data || [] : [],
|
||||
powers: powersResponse ? powersResponse.data || [] : [],
|
||||
};
|
||||
if (requestId !== configRequestId) return;
|
||||
originals.value = original;
|
||||
drafts.value = cloneData(original);
|
||||
loadedModuleId.value = id;
|
||||
activeTab.value = "basic";
|
||||
} catch (e) {
|
||||
if (requestId === configRequestId) {
|
||||
if (String(selectedModuleId.value) === String(moduleId)) {
|
||||
loadedModuleId.value = null;
|
||||
drafts.value.module = null;
|
||||
message.error("模块配置加载失败:" + (e.message || e));
|
||||
}
|
||||
} finally {
|
||||
if (requestId === configRequestId) configLoading.value = false;
|
||||
if (String(selectedModuleId.value) === String(moduleId)) {
|
||||
configLoading.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,8 +317,6 @@ function onTreeSelect(keys) {
|
||||
}
|
||||
|
||||
watch(selectedModuleId, (id) => {
|
||||
const requestId = ++configRequestId;
|
||||
operationId++;
|
||||
if (!id) {
|
||||
configLoading.value = false;
|
||||
loadedModuleId.value = null;
|
||||
@@ -329,7 +329,7 @@ watch(selectedModuleId, (id) => {
|
||||
return;
|
||||
}
|
||||
loadedModuleId.value = null;
|
||||
void loadModuleConfig(id, requestId);
|
||||
void loadModuleConfig(id);
|
||||
});
|
||||
|
||||
// ---- 子面板数据变更 ----
|
||||
@@ -345,7 +345,7 @@ function onSetField(field, value) {
|
||||
|
||||
// 分组管理已自行保存到后端,同步更新 originals 和 drafts
|
||||
function onGroupsSaved(newGroups, idMapping) {
|
||||
if (idMapping?.size) {
|
||||
if (idMapping && idMapping.size) {
|
||||
remapForeignKeys(drafts.value.listConfig || [], ["b_group_id"], idMapping);
|
||||
remapForeignKeys(drafts.value.editConfig || [], ["b_group_id"], idMapping);
|
||||
}
|
||||
@@ -354,7 +354,9 @@ function onGroupsSaved(newGroups, idMapping) {
|
||||
}
|
||||
|
||||
function onI18nSaved(key) {
|
||||
void i18nPanelRef.value?.refreshKey?.(key);
|
||||
if (i18nPanelRef.value) {
|
||||
void i18nPanelRef.value.refreshKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 新增模块 ----
|
||||
@@ -442,7 +444,7 @@ function findNode(key) {
|
||||
|
||||
function hasChildNode(moduleId) {
|
||||
const node = findNode(moduleId);
|
||||
return !!node?.children?.length;
|
||||
return Boolean(node && node.children && node.children.length);
|
||||
}
|
||||
|
||||
async function onDeleteNodeById(moduleId) {
|
||||
@@ -486,9 +488,10 @@ async function onDeleteNodeById(moduleId) {
|
||||
|
||||
// ---- 统一保存 ----
|
||||
async function saveAll() {
|
||||
if (!selectedModule.value || !isCurrentModule.value || busy.value) return;
|
||||
if (!selectedModule.value || busy.value) return;
|
||||
if (loadedModuleId.value == null) return;
|
||||
if (String(loadedModuleId.value) !== String(selectedModuleId.value)) return;
|
||||
const moduleId = String(selectedModule.value.b_id);
|
||||
const currentOperationId = ++operationId;
|
||||
configSaving.value = true;
|
||||
|
||||
try {
|
||||
@@ -497,9 +500,13 @@ async function saveAll() {
|
||||
// s_module 主表
|
||||
const moduleData = drafts.value.module;
|
||||
const moduleOriginal = originals.value.module;
|
||||
const moduleCode = String(moduleData?.b_code || "").trim();
|
||||
const moduleCode = String(moduleData.b_code || "").trim();
|
||||
if (!moduleCode) {
|
||||
message.warning(`请填写${moduleData?.b_module_type === "data" ? "模块编码" : "菜单编码"}`);
|
||||
if (moduleData.b_module_type === "data") {
|
||||
message.warning("请填写模块编码");
|
||||
} else {
|
||||
message.warning("请填写菜单编码");
|
||||
}
|
||||
return;
|
||||
}
|
||||
const codeError = validateModuleCode(moduleCode);
|
||||
@@ -507,7 +514,7 @@ async function saveAll() {
|
||||
message.error(`编码格式不正确:${codeError}`);
|
||||
return;
|
||||
}
|
||||
if (!String(moduleData?.b_name || "").trim()) {
|
||||
if (!String(moduleData.b_name || "").trim()) {
|
||||
message.warning("请填写模块名称");
|
||||
return;
|
||||
}
|
||||
@@ -522,13 +529,18 @@ async function saveAll() {
|
||||
syncModuleItemI18nKeys(drafts.value.fields, "field", moduleData.b_code, "b_field");
|
||||
syncModuleItemI18nKeys(drafts.value.powers, "power", moduleData.b_code, "b_code");
|
||||
moduleData.b_i18n = buildModuleI18nKey(moduleData.b_module_type, moduleData.b_code);
|
||||
const isNew = !moduleOriginal?.b_code;
|
||||
const isNew = !moduleOriginal || !moduleOriginal.b_code;
|
||||
if (moduleData && JSON.stringify(moduleData) !== JSON.stringify(moduleOriginal)) {
|
||||
saveReqs.push({
|
||||
const moduleRequest = {
|
||||
table: "s_module",
|
||||
key_field: "b_id",
|
||||
[isNew ? "inserts" : "updates"]: [moduleData],
|
||||
});
|
||||
};
|
||||
if (isNew) {
|
||||
moduleRequest.inserts = [moduleData];
|
||||
} else {
|
||||
moduleRequest.updates = [moduleData];
|
||||
}
|
||||
saveReqs.push(moduleRequest);
|
||||
}
|
||||
|
||||
// 子表:fields, listConfig, editConfig, queryConfig, powers
|
||||
@@ -558,14 +570,13 @@ async function saveAll() {
|
||||
}
|
||||
|
||||
// 多语言:由各子面板收集变更,统一在此保存
|
||||
if (currentOperationId !== operationId || String(selectedModule.value?.b_id) !== moduleId)
|
||||
return;
|
||||
if (!selectedModule.value || String(selectedModule.value.b_id) !== moduleId) return;
|
||||
const i18nPanel = i18nPanelRef.value;
|
||||
if (i18nPanel && typeof i18nPanel.reconcileManagedRows === "function") {
|
||||
// 保存时才按最终草稿态生成受管键(模块编码/字段/权限),避免编辑过程中实时生成。
|
||||
i18nPanel.reconcileManagedRows(finalI18nItems.value);
|
||||
}
|
||||
if (typeof i18nPanel?.buildSaveRequest === "function") {
|
||||
if (i18nPanel && typeof i18nPanel.buildSaveRequest === "function") {
|
||||
const i18nReq = await i18nPanel.buildSaveRequest();
|
||||
if (i18nReq) saveReqs.push(i18nReq);
|
||||
}
|
||||
@@ -579,8 +590,11 @@ async function saveAll() {
|
||||
|
||||
// 更新 originals
|
||||
originals.value = cloneData(drafts.value);
|
||||
i18nPanelRef.value?.markSaved?.();
|
||||
if (i18nPanelRef.value) {
|
||||
i18nPanelRef.value.markSaved();
|
||||
}
|
||||
updateSavedTreeNode(moduleData);
|
||||
if (appStore.locale) await appStore.loadTranslations(appStore.locale);
|
||||
message.success("保存成功");
|
||||
} catch (e) {
|
||||
message.error("保存失败:" + (e.message || e));
|
||||
@@ -591,12 +605,16 @@ async function saveAll() {
|
||||
|
||||
// ---- 字段同步与默认配置 ----
|
||||
function configuredFieldIds(section) {
|
||||
return new Set(
|
||||
[...(originals.value[section] || []), ...(drafts.value[section] || [])]
|
||||
.map((row) => row.b_field_id)
|
||||
.filter((id) => id != null)
|
||||
.map(String),
|
||||
);
|
||||
const ids = new Set();
|
||||
const originalRows = originals.value[section] || [];
|
||||
const draftRows = drafts.value[section] || [];
|
||||
for (const row of originalRows) {
|
||||
if (row.b_field_id != null) ids.add(String(row.b_field_id));
|
||||
}
|
||||
for (const row of draftRows) {
|
||||
if (row.b_field_id != null) ids.add(String(row.b_field_id));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
function buildMissingDefaultConfigs(module, fields) {
|
||||
@@ -606,77 +624,84 @@ function buildMissingDefaultConfigs(module, fields) {
|
||||
const queryFieldIds = configuredFieldIds("queryConfig");
|
||||
const generated = { listConfig: [], editConfig: [], queryConfig: [] };
|
||||
|
||||
fields
|
||||
.filter((field) => field.b_canuse === 1)
|
||||
.forEach((field, index) => {
|
||||
const fieldId = String(field.b_id);
|
||||
const order = (index + 1) * 10;
|
||||
let orderIndex = 0;
|
||||
for (const field of fields) {
|
||||
if (field.b_canuse !== 1) continue;
|
||||
orderIndex++;
|
||||
const fieldId = String(field.b_id);
|
||||
const order = orderIndex * 10;
|
||||
|
||||
if (!listFieldIds.has(fieldId)) {
|
||||
generated.listConfig.push({
|
||||
b_id: createTempId(),
|
||||
b_module_id: moduleId,
|
||||
b_field_id: fieldId,
|
||||
b_group_id: null,
|
||||
b_title: null,
|
||||
b_i18n: field.b_i18n || null,
|
||||
b_visible: 1,
|
||||
b_xh: order,
|
||||
b_width: 100,
|
||||
b_sortable: 0,
|
||||
});
|
||||
}
|
||||
if (!listFieldIds.has(fieldId)) {
|
||||
generated.listConfig.push({
|
||||
b_id: createTempId(),
|
||||
b_module_id: moduleId,
|
||||
b_field_id: fieldId,
|
||||
b_group_id: null,
|
||||
b_title: null,
|
||||
b_i18n: field.b_i18n || null,
|
||||
b_visible: 1,
|
||||
b_xh: order,
|
||||
b_width: 100,
|
||||
b_sortable: 0,
|
||||
});
|
||||
}
|
||||
|
||||
if (!editFieldIds.has(fieldId)) {
|
||||
generated.editConfig.push({
|
||||
b_id: createTempId(),
|
||||
b_module_id: moduleId,
|
||||
b_field_id: fieldId,
|
||||
b_required: 0,
|
||||
b_readonly: 0,
|
||||
b_disabled: 0,
|
||||
b_group_id: null,
|
||||
b_xh: order,
|
||||
});
|
||||
}
|
||||
if (!editFieldIds.has(fieldId)) {
|
||||
generated.editConfig.push({
|
||||
b_id: createTempId(),
|
||||
b_module_id: moduleId,
|
||||
b_field_id: fieldId,
|
||||
b_required: 0,
|
||||
b_readonly: 0,
|
||||
b_disabled: 0,
|
||||
b_group_id: null,
|
||||
b_xh: order,
|
||||
});
|
||||
}
|
||||
|
||||
if (!queryFieldIds.has(fieldId)) {
|
||||
generated.queryConfig.push({
|
||||
b_id: createTempId(),
|
||||
b_module_id: moduleId,
|
||||
b_field_id: fieldId,
|
||||
b_component: "input",
|
||||
b_operator: "=",
|
||||
b_default_value: null,
|
||||
b_xh: order,
|
||||
b_canuse: 1,
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!queryFieldIds.has(fieldId)) {
|
||||
generated.queryConfig.push({
|
||||
b_id: createTempId(),
|
||||
b_module_id: moduleId,
|
||||
b_field_id: fieldId,
|
||||
b_component: "input",
|
||||
b_operator: "=",
|
||||
b_default_value: null,
|
||||
b_xh: order,
|
||||
b_canuse: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return generated;
|
||||
}
|
||||
|
||||
async function syncFields() {
|
||||
const module = selectedModule.value;
|
||||
const view = String(module?.b_viewtable || "").trim();
|
||||
if (!module) return;
|
||||
const view = String(module.b_viewtable || "").trim();
|
||||
if (!view || busy.value) return;
|
||||
const moduleId = String(module.b_id);
|
||||
const currentOperationId = ++operationId;
|
||||
|
||||
try {
|
||||
configSyncing.value = true;
|
||||
const res = await describeApi(view);
|
||||
if (currentOperationId !== operationId || String(selectedModule.value?.b_id) !== moduleId)
|
||||
return;
|
||||
if (!selectedModule.value || String(selectedModule.value.b_id) !== moduleId) return;
|
||||
const columns = res.data || [];
|
||||
const existingFields = drafts.value.fields || [];
|
||||
|
||||
// 构建视图列名集合
|
||||
const viewColumnSet = new Set(columns.map((c) => c.name.toLowerCase()));
|
||||
const viewColumnSet = new Set();
|
||||
for (const column of columns) {
|
||||
viewColumnSet.add(column.name.toLowerCase());
|
||||
}
|
||||
|
||||
// 已有字段映射(按字段名)
|
||||
const existingMap = new Map(existingFields.map((f) => [f.b_field?.toLowerCase(), f]));
|
||||
const existingMap = new Map();
|
||||
for (const field of existingFields) {
|
||||
if (!field.b_field) continue;
|
||||
existingMap.set(field.b_field.toLowerCase(), field);
|
||||
}
|
||||
|
||||
const mergedFields = [];
|
||||
|
||||
@@ -704,15 +729,16 @@ async function syncFields() {
|
||||
|
||||
// 视图中不存在的已有字段标记为不可用
|
||||
for (const existing of existingFields) {
|
||||
if (!viewColumnSet.has(existing.b_field?.toLowerCase())) {
|
||||
const fieldName = existing.b_field ? existing.b_field.toLowerCase() : "";
|
||||
if (!viewColumnSet.has(fieldName)) {
|
||||
mergedFields.push({ ...existing, b_canuse: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
// 多语言键始终按 field.<模块代码>.<字段编码> 自动生成。
|
||||
mergedFields.forEach((field) => {
|
||||
for (const field of mergedFields) {
|
||||
field.b_i18n = buildModuleItemI18nKey("field", module.b_code, field.b_field);
|
||||
});
|
||||
}
|
||||
|
||||
// 先为新字段分配真实 ID,后续配置通过外键引用这些 ID。
|
||||
const changes = diffRows(mergedFields, existingFields);
|
||||
@@ -725,38 +751,48 @@ async function syncFields() {
|
||||
|
||||
// 为"有 b_i18n 键"的字段生成多语言默认配置(b_i18n 草稿行),注入 i18n 面板,
|
||||
// 由顶部"保存"统一落库;已存在的键由面板去重,不覆盖用户配置。
|
||||
const candidateI18n = mergedFields
|
||||
.filter((f) => f.b_canuse === 1 && f.b_i18n)
|
||||
.map((f) => ({
|
||||
key: f.b_i18n,
|
||||
value: f.b_name || f.b_field,
|
||||
managedId: `field:${f.b_id}`,
|
||||
}));
|
||||
let primaryLocale = "zh-CN";
|
||||
const candidateI18n = [];
|
||||
for (const field of mergedFields) {
|
||||
if (field.b_canuse !== 1 || !field.b_i18n) continue;
|
||||
candidateI18n.push({
|
||||
key: field.b_i18n,
|
||||
value: field.b_name || field.b_field,
|
||||
managedId: `field:${field.b_id}`,
|
||||
});
|
||||
}
|
||||
let primaryLocale = "";
|
||||
try {
|
||||
const langRes = await loadDataApi("b_i18n_type", "b_canuse = 1", "b_xh ASC, b_id ASC");
|
||||
const langRes = await loadDataApi(
|
||||
"b_i18n_type",
|
||||
"b_canuse = 1",
|
||||
"b_default DESC, b_xh ASC, b_id ASC",
|
||||
);
|
||||
const langs = langRes.data || [];
|
||||
if (langs.length) {
|
||||
// 默认字段名翻译写到"简体中文"(zh-CN),找不到再退回排序第一的语言
|
||||
const zh = langs.find((l) => l.b_code === "zh-CN");
|
||||
primaryLocale = (zh || langs[0]).b_code;
|
||||
const defaultLanguage = langs.find((item) => Number(item.b_default) === 1);
|
||||
primaryLocale = String(defaultLanguage?.b_code || langs[0].b_code || "");
|
||||
}
|
||||
} catch {
|
||||
primaryLocale = "";
|
||||
}
|
||||
const i18nEntries = [];
|
||||
if (primaryLocale) {
|
||||
for (const item of candidateI18n) {
|
||||
i18nEntries.push({
|
||||
key: item.key,
|
||||
locale: primaryLocale,
|
||||
value: item.value,
|
||||
managedId: item.managedId,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// 取不到语言类型时回退默认值
|
||||
}
|
||||
const i18nEntries = candidateI18n.map((e) => ({
|
||||
key: e.key,
|
||||
locale: primaryLocale,
|
||||
value: e.value,
|
||||
managedId: e.managedId,
|
||||
}));
|
||||
|
||||
const generated = buildMissingDefaultConfigs(module, mergedFields);
|
||||
const generatedSections = ["listConfig", "editConfig", "queryConfig"];
|
||||
const generatedCount = generatedSections.reduce(
|
||||
(total, section) => total + generated[section].length,
|
||||
0,
|
||||
);
|
||||
let generatedCount = 0;
|
||||
for (const section of generatedSections) {
|
||||
generatedCount += generated[section].length;
|
||||
}
|
||||
|
||||
if (!hasChanges(fieldReq) && !generatedCount && !i18nEntries.length) {
|
||||
message.success("同步成功");
|
||||
@@ -765,8 +801,8 @@ async function syncFields() {
|
||||
|
||||
// 多语言默认配置注入 i18n 面板草稿;字段已预分配真实 ID(见上方 allocateTemporaryIds),
|
||||
// 列表/编辑/查询配置稍后追加到草稿。全部由顶部"保存"统一提交,期间不写库。
|
||||
if (i18nEntries.length) {
|
||||
i18nPanelRef.value?.mergeDefaults?.(i18nEntries);
|
||||
if (i18nEntries.length && i18nPanelRef.value) {
|
||||
i18nPanelRef.value.mergeDefaults(i18nEntries);
|
||||
}
|
||||
|
||||
for (const section of generatedSections) {
|
||||
@@ -850,14 +886,14 @@ void loadTree().catch((e) => message.error("模块树加载失败:" + (e.messa
|
||||
<div class="mm-header-center">
|
||||
<a-space size="middle">
|
||||
<span>启用</span>
|
||||
<a-switch
|
||||
<a-checkbox
|
||||
:checked="drafts.module?.b_canuse === 1"
|
||||
:disabled="busy"
|
||||
@update:checked="(v) => onSetField('b_canuse', v ? 1 : 0)"
|
||||
/>
|
||||
<a-divider type="vertical" />
|
||||
<span>显示菜单</span>
|
||||
<a-switch
|
||||
<a-checkbox
|
||||
:checked="drafts.module?.b_canmenu === 1"
|
||||
:disabled="busy || drafts.module?.b_module_type === 'data'"
|
||||
@update:checked="(v) => onSetField('b_canmenu', v ? 1 : 0)"
|
||||
@@ -891,6 +927,7 @@ void loadTree().catch((e) => message.error("模块树加载失败:" + (e.messa
|
||||
:fields="drafts.fields"
|
||||
:loading="busy"
|
||||
@update="(v) => onUpdate('fields', v)"
|
||||
@i18n-saved="onI18nSaved"
|
||||
/>
|
||||
<ModuleListConfigPanel
|
||||
v-else-if="tab.key === 'list'"
|
||||
|
||||
Reference in new issue
Block a user