From 30be8f8eecbe25854691b4dd0ed0808a97ee450a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=90=AC=E6=B5=B7?= <445436867@qq.com>
Date: Tue, 11 Apr 2023 15:38:51 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dlayout=E8=8F=9C?=
 =?UTF-8?q?=E5=8D=95=E6=8A=98=E5=8F=A0=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=8A=B6?=
 =?UTF-8?q?=E6=80=81=E9=97=AE=E9=A2=98=20(#184)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* fix: 修复layout菜单折叠不更新状态问题

* fix: 修复accessApi.setAccess['/403']执行多次问题

* feat: 手动切换当前路由,菜单也会自动展开

* fix: 修复menu问题
---
 .../fes-plugin-access/src/runtime/core.tpl    | 20 +++----
 .../src/runtime/helpers/pluginAccess.js       | 21 +++----
 .../src/runtime/helpers/pluginLocale.js       |  2 +-
 .../fes-plugin-layout/src/runtime/runtime.js  |  5 +-
 .../src/runtime/views/Menu.vue                | 57 ++++++++++++-------
 .../fes-plugin-locale/src/runtime/core.tpl    | 10 ++--
 .../fes-plugin-locale/src/runtime/runtime.js  |  4 +-
 7 files changed, 64 insertions(+), 55 deletions(-)

diff --git a/packages/fes-plugin-access/src/runtime/core.tpl b/packages/fes-plugin-access/src/runtime/core.tpl
index 12d5f794..5164b130 100644
--- a/packages/fes-plugin-access/src/runtime/core.tpl
+++ b/packages/fes-plugin-access/src/runtime/core.tpl
@@ -3,8 +3,6 @@ import createDirective from "./createDirective";
 import createComponent from "./createComponent";
 import {isPlainObject} from "{{{ lodashPath }}}";
 
-const accessKey = Symbol("plugin-access");
-
 function isPromise(obj) {
     return (
         !!obj &&
@@ -132,14 +130,6 @@ const hasAccess = async (path) => {
 };
 
 export const install = (app) => {
-    const allowPageIds = computed(getAllowAccessIds);
-    const useAccess = (path) => {
-        const result = computed(() => {
-            return match(unref(path), allowPageIds.value);
-        });
-        return result;
-    };
-    app.provide(accessKey, useAccess);
     app.directive("access", createDirective(useAccess));
     app.component("Access", createComponent(useAccess));
 };
@@ -153,6 +143,14 @@ export const access = {
     getAccess: getAllowAccessIds,
 };
 
+export const hasAccessSync = (path) => {
+    return match(unref(path), getAllowAccessIds());
+}
+
 export const useAccess = (path) => {
-    return inject(accessKey)(path);
+    const allowPageIds = computed(getAllowAccessIds);
+    const result = computed(() => {
+        return match(unref(path), allowPageIds.value);
+    });
+    return result;
 };
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js b/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
index a18b90bd..23f52022 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
@@ -1,32 +1,29 @@
-import { computed, ref } from 'vue';
 // eslint-disable-next-line
-import { useAccess } from '../../plugin-access/core';
+import { hasAccessSync } from '../../plugin-access/core';
 
-if (!useAccess) {
+if (!hasAccessSync) {
     throw new Error('[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!');
 }
 
 export const hasAccessByMenuItem = (item) => {
     const hasChild = item.children && item.children.length;
     if (item.path && !hasChild) {
-        return useAccess(item.path);
+        return hasAccessSync(item.path);
     }
     if (hasChild) {
-        return computed(() =>
-            item.children.some((child) => {
-                const rst = hasAccessByMenuItem(child);
-                return rst && rst.value;
-            }),
-        );
+        return item.children.some((child) => {
+            const rst = hasAccessByMenuItem(child);
+            return rst;
+        });
     }
-    return ref(true);
+    return true;
 };
 
 export const transform = (menus) =>
     menus
         .map((menu) => {
             const hasAccess = hasAccessByMenuItem(menu);
-            if (!hasAccess.value) {
+            if (!hasAccess) {
                 return false;
             }
             if (menu.children) {
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js b/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
index fc2a6693..0691f188 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
@@ -6,7 +6,7 @@ export const transTitle = (name) => {
     }
     const sharedLocale = plugin.getShared('locale');
     if (sharedLocale) {
-        const { t } = sharedLocale.useI18n();
+        const { t } = sharedLocale.locale;
         return t(name.slice(1));
     }
     return name;
diff --git a/packages/fes-plugin-layout/src/runtime/runtime.js b/packages/fes-plugin-layout/src/runtime/runtime.js
index de9ab180..e5022259 100644
--- a/packages/fes-plugin-layout/src/runtime/runtime.js
+++ b/packages/fes-plugin-layout/src/runtime/runtime.js
@@ -7,10 +7,11 @@ if (!accessApi) {
     throw new Error('[plugin-layout]: plugin-layout depends on plugin-access,please install plugin-access first!');
 }
 
+const accessIds = accessApi.getAccess();
+accessApi.setAccess(accessIds.concat(['/403', '/404']));
+
 export const access = (memo) => {
     const runtimeConfig = getConfig();
-    const accessIds = accessApi.getAccess();
-    accessApi.setAccess(accessIds.concat(['/403', '/404']));
     return {
         unAccessHandler({ router, to, from, next }) {
             if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
diff --git a/packages/fes-plugin-layout/src/runtime/views/Menu.vue b/packages/fes-plugin-layout/src/runtime/views/Menu.vue
index ef4e2d75..0e4ba224 100644
--- a/packages/fes-plugin-layout/src/runtime/views/Menu.vue
+++ b/packages/fes-plugin-layout/src/runtime/views/Menu.vue
@@ -1,7 +1,7 @@
 <template>
     <f-menu
+        v-model:expandedKeys="expandedKeysRef"
         :modelValue="activePath"
-        :expandedKeys="defaultExpandMenu"
         :inverted="inverted"
         :mode="mode"
         :options="transformedMenus"
@@ -12,7 +12,7 @@
 </template>
 
 <script>
-import { computed, h } from 'vue';
+import { computed, h, ref, watch } from 'vue';
 import { FMenu } from '@fesjs/fes-design';
 import { useRoute, useRouter } from '@@/core/coreExports';
 import { transform as transformByAccess } from '../helpers/pluginAccess';
@@ -20,12 +20,12 @@ import { transform as transformByLocale } from '../helpers/pluginLocale';
 import { flatNodes } from '../helpers/utils';
 import MenuIcon from './MenuIcon.vue';
 
-const transform = (menus) =>
-    menus.map((menu) => {
+const transform = (menus, level = 1) =>
+    menus.map((menu, index) => {
         const copy = {
             ...menu,
             label: menu.title,
-            value: menu.path || Date.now(),
+            value: menu.path || `${level}_${index}`,
         };
         if (menu.icon) {
             copy.icon = () =>
@@ -34,7 +34,7 @@ const transform = (menus) =>
                 });
         }
         if (menu.children) {
-            copy.children = transform(menu.children);
+            copy.children = transform(menu.children, level + 1);
         }
         return copy;
     });
@@ -94,22 +94,34 @@ export default {
             }
             return matchMenus[0].path;
         });
-        const defaultExpandMenu = computed(() => {
-            let index = menuArray.value.findIndex((item) => item.value === activePath.value);
-            if (index === -1) {
-                return props.expandedKeys;
-            }
-            const activeMenu = menuArray.value[index];
-            const arr = [activeMenu];
-            while (index > 0) {
-                index = index - 1;
-                const lastMenu = menuArray.value[index];
-                if (lastMenu.children && lastMenu.children.indexOf(arr[arr.length - 1]) !== -1) {
-                    arr.push(lastMenu);
+
+        const expandedKeysRef = ref(props.expandedKeys);
+
+        watch(
+            [menuArray, activePath],
+            () => {
+                let index = menuArray.value.findIndex((item) => item.value === activePath.value);
+                if (index === -1) {
+                    return;
                 }
-            }
-            return props.expandedKeys.concat(arr.map((item) => item.value));
-        });
+                const activeMenu = menuArray.value[index];
+                const arr = [activeMenu];
+                while (index > 0) {
+                    index = index - 1;
+                    const lastMenu = menuArray.value[index];
+                    if (lastMenu.children && lastMenu.children.indexOf(arr[arr.length - 1]) !== -1) {
+                        arr.push(lastMenu);
+                    }
+                }
+                expandedKeysRef.value = expandedKeysRef.value.concat(
+                    arr.filter((item) => !expandedKeysRef.value.includes(item.value)).map((item) => item.value),
+                );
+            },
+            {
+                immediate: true,
+            },
+        );
+
         const onMenuClick = (e) => {
             const path = e.value;
             if (/^https?:\/\//.test(path)) {
@@ -120,9 +132,10 @@ export default {
                 console.warn('[plugin-layout]: 菜单的path只能使以http(s)开头的网址或者路由地址');
             }
         };
+
         return {
             activePath,
-            defaultExpandMenu,
+            expandedKeysRef,
             transformedMenus,
             onMenuClick,
         };
diff --git a/packages/fes-plugin-locale/src/runtime/core.tpl b/packages/fes-plugin-locale/src/runtime/core.tpl
index 0e4b6f26..72b876f8 100644
--- a/packages/fes-plugin-locale/src/runtime/core.tpl
+++ b/packages/fes-plugin-locale/src/runtime/core.tpl
@@ -85,19 +85,19 @@ const getAllLocales = () => {
 };
 
 const install = (app) => {
-    const runtimeConfig = plugin.applyPlugins({
-        key: "locale",
-        type: ApplyPluginsType.modify,
-        initialValue: {},
-    });
     app.use(i18n);
 };
 
+const t = (key) => {
+    return i18n.global.t(key)
+}
+
 const locale = {
     setLocale,
     addLocale,
     getAllLocales,
     messages,
+    t
 };
 
 export { useI18n, locale, install };
diff --git a/packages/fes-plugin-locale/src/runtime/runtime.js b/packages/fes-plugin-locale/src/runtime/runtime.js
index c642d7e7..a555ea87 100644
--- a/packages/fes-plugin-locale/src/runtime/runtime.js
+++ b/packages/fes-plugin-locale/src/runtime/runtime.js
@@ -1,10 +1,10 @@
 import { plugin } from '@@/core/coreExports';
 // eslint-disable-next-line import/extensions
-import { useI18n, install } from './core';
+import { useI18n, locale, install } from './core';
 import SelectLang from './views/SelectLang.vue';
 
 // 共享出去
-plugin.share('locale', { useI18n, SelectLang });
+plugin.share('locale', { useI18n, locale, SelectLang });
 
 export function onAppCreated({ app }) {
     install(app);