diff --git a/code/fms/fms-api/config/migrations/036_add_module_icon.sql b/code/fms/fms-api/config/migrations/036_add_module_icon.sql
new file mode 100644
index 00000000..b96cc31a
--- /dev/null
+++ b/code/fms/fms-api/config/migrations/036_add_module_icon.sql
@@ -0,0 +1,16 @@
+/*
+ Add b_icon column to s_module so directory/page modules can assign a
+ Lucide icon for sidebar menu display.
+*/
+SET NOCOUNT ON;
+SET XACT_ABORT ON;
+
+IF DB_NAME() <> N'FMS'
+ THROW 53600, N'This migration can only run against the FMS database.', 1;
+
+IF COL_LENGTH(N'dbo.s_module', N'b_icon') IS NOT NULL
+ THROW 53601, N'Column b_icon already exists on s_module.', 1;
+
+ALTER TABLE dbo.s_module ADD b_icon VARCHAR(50) NULL;
+
+PRINT N'Migration 036 applied: added s_module.b_icon.';
diff --git a/code/fms/fms-vue/src/App.vue b/code/fms/fms-vue/src/App.vue
index 731a7104..56374d02 100644
--- a/code/fms/fms-vue/src/App.vue
+++ b/code/fms/fms-vue/src/App.vue
@@ -2,29 +2,6 @@
import zhCN from "antdv-next/locale/zh_CN";
const themeConfig = {
- token: {
- controlHeight: 32,
- borderRadius: 6,
- colorPrimary: '#0a0a0a',
- colorBgContainer: '#ffffff',
- colorBgLayout: '#fafafa',
- colorBorder: '#e4e4e7',
- colorText: '#0a0a0a',
- colorTextSecondary: '#71717a',
- fontSize: 14,
- },
- components: {
- Splitter: {
- splitBarSize: 1,
- },
- Button: {
- contentFontSize: 14,
- },
- Tree: {
- nodeSelectedBg: '#0a0a0a',
- nodeSelectedColor: '#fafafa',
- },
- },
};
diff --git a/code/fms/fms-vue/src/components/FmsTree.vue b/code/fms/fms-vue/src/components/FmsTree.vue
index 3d691487..9b3abe18 100644
--- a/code/fms/fms-vue/src/components/FmsTree.vue
+++ b/code/fms/fms-vue/src/components/FmsTree.vue
@@ -19,6 +19,7 @@ const handledEventAttrs = new Set([
"onDragEnd",
"onDragend",
"onRightClick",
+ "onSelect",
"onUpdate:expandedKeys",
]);
@@ -35,6 +36,7 @@ const props = defineProps({
expandedKeys: { type: Array, default: undefined },
blockNode: { type: Boolean, default: true },
virtual: { type: Boolean, default: true },
+ showLine: { type: Boolean, default: false },
draggable: { type: [Boolean, Function, Object], default: false },
allowDrop: { type: Function, default: null },
rootKey: { type: [String, Number], default: "__fms_tree_root__" },
@@ -86,6 +88,7 @@ const emit = defineEmits([
"dragOver",
"dragEnd",
"rightClick",
+ "select",
"update:expandedKeys",
]);
@@ -121,7 +124,21 @@ function onMenuClick({ key }) {
if (node) emit("menuClick", { key, node });
}
+const selectSuppress = ref(false);
+
+function onSelect(keys, info) {
+ // 点击有子节点的父节点时,阻止 a-tree 内部自动触发展开
+ if (info?.node?.children?.length) {
+ selectSuppress.value = true;
+ }
+ emit("select", keys, info);
+}
+
function onExpandedKeysChange(keys) {
+ if (selectSuppress.value) {
+ selectSuppress.value = false;
+ return;
+ }
emit("update:expandedKeys", keys);
}
@@ -141,10 +158,11 @@ function onExpandedKeysChange(keys) {
:default-expanded-keys="[rootKey]"
:block-node="blockNode"
:virtual="effectiveVirtual"
- show-line
+ :show-line="showLine"
:draggable="draggable"
:allow-drop="allowDrop"
@right-click="onTreeRightClick"
+ @select="onSelect"
@drop="$emit('drop', $event)"
@dragstart="$emit('dragStart', $event)"
@dragenter="$emit('dragEnter', $event)"
@@ -167,9 +185,10 @@ function onExpandedKeysChange(keys) {
:default-expanded-keys="[rootKey]"
:block-node="blockNode"
:virtual="effectiveVirtual"
- show-line
+ :show-line="showLine"
:draggable="draggable"
:allow-drop="allowDrop"
+ @select="onSelect"
@drop="$emit('drop', $event)"
@dragstart="$emit('dragStart', $event)"
@dragenter="$emit('dragEnter', $event)"
diff --git a/code/fms/fms-vue/src/layouts/DefaultLayout.vue b/code/fms/fms-vue/src/layouts/DefaultLayout.vue
index 180d1eef..114ef238 100644
--- a/code/fms/fms-vue/src/layouts/DefaultLayout.vue
+++ b/code/fms/fms-vue/src/layouts/DefaultLayout.vue
@@ -77,7 +77,7 @@ const routeInstanceKey = computed(
border-radius: 8px;
box-shadow: 0 0 0 1px rgb(0 0 0 / 4%), 0 1px 3px rgb(0 0 0 / 4%), 0 4px 12px rgb(0 0 0 / 3%);
background: #ffffff;
- padding: 8px;
+ padding: 0 16px;
}
.app-content {
@@ -86,7 +86,7 @@ const routeInstanceKey = computed(
min-height: 0;
overflow-x: hidden;
overflow-y: auto;
- padding: 6px;
+ padding: 6px 0;
background: #ffffff;
}
diff --git a/code/fms/fms-vue/src/layouts/components/AppSidebar.vue b/code/fms/fms-vue/src/layouts/components/AppSidebar.vue
index d416c073..2e643243 100644
--- a/code/fms/fms-vue/src/layouts/components/AppSidebar.vue
+++ b/code/fms/fms-vue/src/layouts/components/AppSidebar.vue
@@ -1,30 +1,23 @@
@@ -216,11 +199,7 @@ onMounted(() => permissionStore.load().catch(() => {}));
-
-
+
-