20260804173126

This commit is contained in:
oneao committed 2026-08-04 17:31:27 +08:00
1 parent e17bbe9db3
commit 75b1ccaa6d
36 files changed
+3521 -718

No files matched your search

@@ -1,9 +1,10 @@
<script setup>
import { h, onMounted, ref } from "vue";
import { message, Modal } from "antdv-next";
import { Boxes, LayoutPanelTop, Network } from "@lucide/vue";
import { Boxes, LayoutPanelTop, Network, SlidersHorizontal, Workflow } from "@lucide/vue";
import { useAppStore } from "@/stores/app";
import { usePermissionStore } from "@/stores/permissions";
import BusinessStructurePanel from "./components/BusinessStructurePanel.vue";
import FunctionStructurePanel from "./components/FunctionStructurePanel.vue";
import PageCompositionPanel from "./components/PageCompositionPanel.vue";
import ModuleResourcePanel from "./components/ModuleResourcePanel.vue";
@@ -14,7 +15,8 @@ import { useModuleResources } from "./composables/useModuleResources";
const appStore = useAppStore();
const permissionStore = usePermissionStore();
const canManage = (actionCode) => permissionStore.canAction("m_metadata", actionCode);
const activeArea = ref("function");
const activeMode = ref("structure");
const advancedArea = ref("function");
const loadedAreas = new Set();
const functionController = useFunctionStructure(appStore, canManage);
const pageController = usePageComposition(appStore, canManage);
@@ -28,51 +30,92 @@ const controllers = {
async function loadArea(area) {
if (loadedAreas.has(area)) return;
try {
await controllers[area].load();
loadedAreas.add(area);
if (area === "structure") {
await Promise.all(Object.values(controllers).map((controller) => controller.load()));
loadedAreas.add("structure");
for (const key of Object.keys(controllers)) loadedAreas.add(key);
} else {
await controllers[area].load();
loadedAreas.add(area);
}
} catch (error) {
message.error(error.message || String(error));
}
}
function changeArea(area) {
if (area === activeArea.value) return;
if (activeArea.value === "resource" && resourceController.isDirty.value) {
function changeContext(nextMode, nextArea = advancedArea.value) {
const currentUsesResource = activeMode.value === "structure" || advancedArea.value === "resource";
const nextUsesResource = nextMode === "structure" || nextArea === "resource";
const apply = async () => {
activeMode.value = nextMode;
advancedArea.value = nextArea;
await loadArea(nextMode === "structure" ? "structure" : nextArea);
};
if (currentUsesResource && !nextUsesResource && resourceController.isDirty.value) {
Modal.confirm({
title: "当前模块有未保存修改",
content: "切换维护区域将放弃这些修改。",
okText: "放弃并切换",
cancelText: "继续编辑",
onOk: async () => {
activeArea.value = area;
await loadArea(area);
await resourceController.load();
await apply();
},
});
return;
}
activeArea.value = area;
loadArea(area);
apply();
}
onMounted(() => loadArea(activeArea.value));
function changeMode(mode) {
if (mode === activeMode.value) return;
changeContext(mode);
}
function changeAdvancedArea(area) {
if (area === advancedArea.value) return;
changeContext("advanced", area);
}
onMounted(() => loadArea("structure"));
</script>
<template>
<div class="module-management-page">
<header class="area-switcher">
<a-segmented
:value="activeArea"
:value="activeMode"
:options="[
{ value: 'structure', label: '目录与页面', icon: () => h(Workflow, { size: 15 }) },
{ value: 'advanced', label: '高级维护', icon: () => h(SlidersHorizontal, { size: 15 }) },
]"
@change="changeMode"
/>
<a-segmented
v-if="activeMode === 'advanced'"
class="advanced-switcher"
:value="advancedArea"
:options="[
{ value: 'function', label: '功能结构', icon: () => h(Network, { size: 15 }) },
{ value: 'page', label: '页面编排', icon: () => h(LayoutPanelTop, { size: 15 }) },
{ value: 'resource', label: '模块资源', icon: () => h(Boxes, { size: 15 }) },
]"
@change="changeArea"
@change="changeAdvancedArea"
/>
</header>
<section class="area-content">
<FunctionStructurePanel v-if="activeArea === 'function'" :controller="functionController" />
<PageCompositionPanel v-else-if="activeArea === 'page'" :controller="pageController" />
<BusinessStructurePanel
v-if="activeMode === 'structure'"
:app-store="appStore"
:function-controller="functionController"
:page-controller="pageController"
:resource-controller="resourceController"
/>
<FunctionStructurePanel
v-else-if="advancedArea === 'function'"
:controller="functionController"
/>
<PageCompositionPanel v-else-if="advancedArea === 'page'" :controller="pageController" />
<ModuleResourcePanel v-else :controller="resourceController" />
</section>
</div>
@@ -97,9 +140,24 @@ onMounted(() => loadArea(activeArea.value));
padding: 10px 12px;
border-bottom: 1px solid var(--fms-border);
}
.advanced-switcher {
margin-left: auto;
}
.area-content {
flex: 1;
min-height: 0;
overflow: hidden;
}
@media (max-width: 720px) {
.area-switcher {
align-items: stretch;
flex-direction: column;
gap: 8px;
}
.advanced-switcher {
margin-left: 0;
}
}
</style>