yangg 1 жил өмнө
parent
commit
e34a969a2e

+ 2 - 1
package.json

@@ -61,7 +61,8 @@
     "vue3-number-spinner": "^0.0.9",
     "vue3-perfect-scrollbar": "^1.6.0",
     "vue3-popper": "^1.5.0",
-    "vue3-quill": "^0.2.9"
+    "vue3-quill": "^0.2.9",
+    "vuex": "^4.1.0"
   },
   "devDependencies": {
     "@intlify/vite-plugin-vue-i18n": "^6.0.3",

+ 2 - 2
src/App.vue

@@ -18,11 +18,11 @@
     import appLayout from '@/layouts/app-layout.vue';
     import authLayout from '@/layouts/auth-layout.vue';
 
-    import { useAppStore } from '@/stores/index';
+    import { useStore } from 'vuex';
     import { useMeta } from '@/composables/use-meta';
     import router from '@/router';
 
-    const store = useAppStore();
+    const store:any = useStore();
 
    const godashbord=()=>{
         router.push(({path:'/apps/applist'}))

+ 2 - 2
src/api/common.js

@@ -13,7 +13,7 @@ import Storage from '@/utils/storage'
  * @returns {string}
  */
 export function getValidateCodeUrl(scene, uuid) {//${api.admin}
-  return `https://apidoc.raycos.net/captchas/${uuid}/${scene}?rmd=${new Date().getTime()}`
+  return `http://192.168.8.101:9998/captchas/${uuid}/${scene}?rmd=${new Date().getTime()}`
 }
 
 /**
@@ -21,7 +21,7 @@ export function getValidateCodeUrl(scene, uuid) {//${api.admin}
  */
 export function getValidator() {//${api.admin}
   return request({
-    url: `https://apidoc.raycos.net/validator`,
+    url: `http://192.168.8.101:9998/validator`,
     method: 'GET',
     needToken: false
   })

+ 19 - 22
src/app-setting.ts

@@ -1,28 +1,25 @@
 import { $themeConfig } from '../theme.config';
-import { useAppStore } from '@/stores/index';
+import store from '@/stores';
 
 export default {
     init() {
-        const store = useAppStore();
-
         // set default styles
         let val: any = localStorage.getItem('theme'); // light, dark, system
         val = val || $themeConfig.theme;
-        store.toggleTheme(val);
+        store.dispatch('toggleTheme', val);
 
         val = localStorage.getItem('menu'); // vertical, collapsible-vertical, horizontal
         val = val || $themeConfig.menu;
-        store.toggleMenu(val);
+        store.dispatch('toggleMenu', val);
 
         val = localStorage.getItem('layout'); // full, boxed-layout
         val = val || $themeConfig.layout;
-        store.toggleLayout(val);
+        store.dispatch('toggleLayout', val);
 
         val = localStorage.getItem('i18n_locale'); // en, da, de, el, es, fr, hu, it, ja, pl, pt, ru, sv, tr, zh
-
         val = val || $themeConfig.locale;
 
-        const list = store.languageList;
+        const list = store.getters.languageList;
         const item = list.find((item: any) => item.code === val);
         if (item) {
             this.toggleLanguage(item);
@@ -30,58 +27,58 @@ export default {
 
         val = localStorage.getItem('rtlClass'); // rtl, ltr
         val = val || $themeConfig.rtlClass;
-        store.toggleRTL(val);
+        store.dispatch('toggleRTL', val);
 
         val = localStorage.getItem('animation'); // animate__fadeIn, animate__fadeInDown, animate__fadeInUp, animate__fadeInLeft, animate__fadeInRight, animate__slideInDown, animate__slideInLeft, animate__slideInRight, animate__zoomIn
         val = val || $themeConfig.animation;
-        store.toggleAnimation(val);
+        store.dispatch('toggleAnimation', val);
 
         val = localStorage.getItem('navbar'); // navbar-sticky, navbar-floating, navbar-static
         val = val || $themeConfig.navbar;
-        store.toggleNavbar(val);
+        store.dispatch('toggleNavbar', val);
 
         val = localStorage.getItem('semidark');
         val = val === 'true' ? true : $themeConfig.semidark;
-        store.toggleSemidark(val);
+        store.dispatch('toggleSemidark', val);
     },
 
     toggleLanguage(item: any) {
-        const store = useAppStore();
+       /*  const store = useStore(); */
         console.log(item);
         let lang: any = null;
         if (item) {
             lang = item;
         } else {
-            let code = store.locale || null;
+            let code = store.state.locale || null;
             if (!code) {
                 code = localStorage.getItem('i18n_locale');
             }
 
-            item = store.languageList.find((d: any) => d.code === code);
+            item = store.getters.languageList.find((d: any) => d.code === code);
             if (item) {
                 lang = item;
             }
         }
 
         if (!lang) {
-            lang = store.languageList.find((d: any) => d.code === 'zh');
+            lang = store.getters.languageList.find((d: any) => d.code === 'zh');
         }
         console.log(lang);
-        store.toggleLocale(lang.code);
+        store.dispatch('toggleLocale', lang.code);
         return lang;
     },
 
     changeAnimation(type = 'add') {
-        const store = useAppStore();
-        if (store.animation) {
+       /*  const store = useStore(); */
+        if (store.state.animation) {
             const eleanimation: any = document.querySelector('.animation');
             if (type === 'add') {
                 eleanimation?.classList.add('animate__animated');
-                eleanimation?.classList.add(store.animation);
+                eleanimation?.classList.add(store.state.animation);
             } else {
                 eleanimation?.classList.remove('animate__animated');
-                eleanimation?.classList.remove(store.animation);
+                eleanimation?.classList.remove(store.state.animation);
             }
         }
     },
-};
+};

+ 2 - 2
src/components/ThemeCustomizer.vue

@@ -214,12 +214,12 @@
 
 <script lang="ts" setup>
     import { ref } from 'vue';
-    import { useAppStore } from '@/stores/index';
+    import store from '@/stores';
     import IconSettings from '@/components/icon/icon-settings.vue';
     import IconX from '@/components/icon/icon-x.vue';
     import IconSun from '@/components/icon/icon-sun.vue';
     import IconMoon from '@/components/icon/icon-moon.vue';
     import IconLaptop from '@/components/icon/icon-laptop.vue';
-    const store = useAppStore();
+
     const showCustomizer = ref(false);
 </script>

+ 2 - 2
src/components/layout/Header.vue

@@ -239,7 +239,7 @@
     import appSetting from '@/app-setting';
 
     import { useRoute } from 'vue-router';
-    import { useAppStore } from '@/stores/index';
+    import { useStore } from 'vuex';
 
     import IconMenu from '@/components/icon/icon-menu.vue';
     import IconCalendar from '@/components/icon/icon-calendar.vue';
@@ -268,7 +268,7 @@
     import IconMenuPages from '@/components/icon/menu/icon-menu-pages.vue';
     import IconMenuMore from '@/components/icon/menu/icon-menu-more.vue';
 
-    const store = useAppStore();
+    const store = useStore();
     const route = useRoute();
     const search = ref(false);
 

+ 101 - 103
src/components/layout/Sidebar.vue

@@ -1,38 +1,33 @@
 <template>
-    <div :class="{ 'dark text-white-dark': store.semidark }">
-        <nav class="sidebar fixed min-h-screen h-full top-0 bottom-0 w-[260px] shadow-[5px_0_25px_0_rgba(94,92,154,0.1)] z-50 transition-all duration-300">
+    <div :class="{ 'dark text-white-dark': store.state.semidark }">
+        <nav
+            class="sidebar fixed min-h-screen h-full top-0 bottom-0 w-[260px] shadow-[5px_0_25px_0_rgba(94,92,154,0.1)] z-50 transition-all duration-300">
             <div class="bg-white dark:bg-[#0e1726] h-full">
                 <div class="flex justify-between items-center px-4 py-3">
                     <router-link to="/" class="main-logo flex items-center shrink-0">
                         <img class="w-8 ml-[5px] flex-none" src="/assets/images/logo.png" alt="" />
-                        <span class="text-2xl ltr:ml-1.5 rtl:mr-1.5 font-semibold align-middle lg:inline dark:text-white-light">V3Studio</span>
+                        <span
+                            class="text-2xl ltr:ml-1.5 rtl:mr-1.5 font-semibold align-middle lg:inline dark:text-white-light">V3Studio</span>
                     </router-link>
-                    <a
-                        href="javascript:;"
+                    <a href="javascript:;"
                         class="collapse-icon w-8 h-8 rounded-full flex items-center hover:bg-gray-500/10 dark:hover:bg-dark-light/10 dark:text-white-light transition duration-300 rtl:rotate-180 hover:text-primary"
-                        @click="store.toggleSidebar()"
-                    >
+                        @click="toggleSidebars">
                         <icon-carets-down class="m-auto rotate-90" />
                     </a>
                 </div>
-                <perfect-scrollbar
-                    :options="{
-                        swipeEasing: true,
-                        wheelPropagation: false,
-                    }"
-                    class="h-[calc(100vh-80px)] relative"
-                >
+                <perfect-scrollbar :options="{
+                    swipeEasing: true,
+                    wheelPropagation: false,
+                }" class="h-[calc(100vh-80px)] relative">
                     <ul class="relative font-semibold space-y-0.5 p-4 py-0">
                         <li class="menu nav-item">
-                            <button
-                                type="button"
-                                class="nav-link group w-full"
+                            <button type="button" class="nav-link group w-full"
                                 :class="{ active: activeDropdown === 'dashboard' }"
-                                @click="activeDropdown === 'dashboard' ? (activeDropdown = null) : (activeDropdown = 'dashboard')"
-                            >
+                                @click="activeDropdown === 'dashboard' ? (activeDropdown = null) : (activeDropdown = 'dashboard')">
                                 <div class="flex items-center">
                                     <icon-menu-dashboard class="group-hover:!text-primary shrink-0" />
-                                    <span class="ltr:pl-3 rtl:pr-3 text-black dark:text-[#506690] dark:group-hover:text-white-dark">
+                                    <span
+                                        class="ltr:pl-3 rtl:pr-3 text-black dark:text-[#506690] dark:group-hover:text-white-dark">
                                         {{ $t('dashboard') }}
                                     </span>
                                 </div>
@@ -45,8 +40,8 @@
                                     <li>
                                         <router-link to="/" @click="toggleMobileMenu">{{ $t('sales') }}</router-link>
                                     </li>
-                           
-                                    
+
+
                                 </ul>
                             </vue-collapsible>
                         </li>
@@ -55,18 +50,16 @@
 
                         <li class="nav-item">
                             <ul>
-        
+
                                 <li class="menu nav-item">
-                                    <button
-                                        type="button"
-                                        class="nav-link group w-full"
+                                    <button type="button" class="nav-link group w-full"
                                         :class="{ active: activeDropdown === 'invoice' }"
-                                        @click="activeDropdown === 'invoice' ? (activeDropdown = null) : (activeDropdown = 'invoice')"
-                                    >
-                                    <div class="flex items-center">
+                                        @click="activeDropdown === 'invoice' ? (activeDropdown = null) : (activeDropdown = 'invoice')">
+                                        <div class="flex items-center">
                                             <icon-menu-chat class="group-hover:!text-primary shrink-0" />
 
-                                            <span class="ltr:pl-3 rtl:pr-3 text-black dark:text-[#506690] dark:group-hover:text-white-dark">
+                                            <span
+                                                class="ltr:pl-3 rtl:pr-3 text-black dark:text-[#506690] dark:group-hover:text-white-dark">
                                                 应用列表
                                             </span>
                                         </div>
@@ -77,38 +70,41 @@
                                     <vue-collapsible :isOpen="activeDropdown === 'invoice'">
                                         <ul class="sub-menu text-gray-500">
                                             <li>
-                                                <router-link to="/apps/applist" @click="toggleMobileMenu">所有应用</router-link>
+                                                <router-link to="/apps/applist"
+                                                    @click="toggleMobileMenu">所有应用</router-link>
                                             </li>
                                             <li>
-                                                <router-link to="/apps/custom" @click="toggleMobileMenu">客户列表</router-link>
+                                                <router-link to="/apps/custom"
+                                                    @click="toggleMobileMenu">客户列表</router-link>
                                             </li>
                                             <li>
-                                                <router-link to="/apps/stock" @click="toggleMobileMenu">仓库列表</router-link>
+                                                <router-link to="/apps/stock"
+                                                    @click="toggleMobileMenu">仓库列表</router-link>
                                             </li>
                                             <li>
-                                                <router-link to="/apps/order" @click="toggleMobileMenu">订单列表</router-link>
+                                                <router-link to="/apps/order"
+                                                    @click="toggleMobileMenu">订单列表</router-link>
                                             </li>
                                             <li>
-                                                <router-link to="/apps/goods" @click="toggleMobileMenu">商品列表</router-link>
+                                                <router-link to="/apps/goods"
+                                                    @click="toggleMobileMenu">商品列表</router-link>
                                             </li>
                                         </ul>
                                     </vue-collapsible>
                                 </li>
 
-                              
+
                             </ul>
                         </li>
                         <li class="menu nav-item">
-                            <button
-                                type="button"
-                                class="nav-link group w-full"
+                            <button type="button" class="nav-link group w-full"
                                 :class="{ active: activeDropdown === 'users' }"
-                                @click="activeDropdown === 'users' ? (activeDropdown = null) : (activeDropdown = 'users')"
-                            >
+                                @click="activeDropdown === 'users' ? (activeDropdown = null) : (activeDropdown = 'users')">
                                 <div class="flex items-center">
                                     <icon-menu-users class="group-hover:!text-primary shrink-0" />
 
-                                    <span class="ltr:pl-3 rtl:pr-3 text-black dark:text-[#506690] dark:group-hover:text-white-dark">系统管理</span>
+                                    <span
+                                        class="ltr:pl-3 rtl:pr-3 text-black dark:text-[#506690] dark:group-hover:text-white-dark">系统管理</span>
                                 </div>
                                 <div :class="{ 'rtl:rotate-90 -rotate-90': activeDropdown == 'users' }">
                                     <icon-caret-down />
@@ -126,8 +122,8 @@
                             </vue-collapsible>
                             <vue-collapsible :isOpen="activeDropdown === 'users'">
                                 <ul class="sub-menu text-gray-500">
-                                    
-                                   
+
+
                                 </ul>
                             </vue-collapsible>
                         </li>
@@ -135,7 +131,7 @@
                             <icon-minus class="w-4 h-5 flex-none hidden" />
                             <span>{{ $t('user_interface') }}</span>
                         </h2> -->
-<!-- 
+                        <!-- 
                         <li class="menu nav-item">
                             <button
                                 type="button"
@@ -470,13 +466,13 @@
                             </vue-collapsible>
                         </li> -->
 
-                       
 
 
 
-                       
 
-                       
+
+
+
                         <!-- <h2 class="py-3 px-7 flex items-center uppercase font-extrabold bg-white-light/30 dark:bg-dark dark:bg-opacity-[0.08] -mx-4 mb-1">
                             <icon-minus class="w-4 h-5 flex-none hidden" />
                             <span>{{ $t('supports') }}</span>
@@ -501,61 +497,63 @@
 </template>
 
 <script lang="ts" setup>
-    import { ref, onMounted } from 'vue';
-
-    import { useAppStore } from '@/stores/index';
-    import VueCollapsible from 'vue-height-collapsible/vue3';
-
-    import IconCaretsDown from '@/components/icon/icon-carets-down.vue';
-    import IconMenuDashboard from '@/components/icon/menu/icon-menu-dashboard.vue';
-    import IconMinus from '@/components/icon/icon-minus.vue';
-    import IconMenuChat from '@/components/icon/menu/icon-menu-chat.vue';
-    import IconMenuMailbox from '@/components/icon/menu/icon-menu-mailbox.vue';
-    import IconMenuTodo from '@/components/icon/menu/icon-menu-todo.vue';
-    import IconMenuNotes from '@/components/icon/menu/icon-menu-notes.vue';
-    import IconMenuScrumboard from '@/components/icon/menu/icon-menu-scrumboard.vue';
-    import IconMenuContacts from '@/components/icon/menu/icon-menu-contacts.vue';
-    import IconMenuInvoice from '@/components/icon/menu/icon-menu-invoice.vue';
-    import IconCaretDown from '@/components/icon/icon-caret-down.vue';
-    import IconMenuCalendar from '@/components/icon/menu/icon-menu-calendar.vue';
-    import IconMenuComponents from '@/components/icon/menu/icon-menu-components.vue';
-    import IconMenuElements from '@/components/icon/menu/icon-menu-elements.vue';
-    import IconMenuCharts from '@/components/icon/menu/icon-menu-charts.vue';
-    import IconMenuWidgets from '@/components/icon/menu/icon-menu-widgets.vue';
-    import IconMenuFontIcons from '@/components/icon/menu/icon-menu-font-icons.vue';
-    import IconMenuDragAndDrop from '@/components/icon/menu/icon-menu-drag-and-drop.vue';
-    import IconMenuTables from '@/components/icon/menu/icon-menu-tables.vue';
-    import IconMenuDatatables from '@/components/icon/menu/icon-menu-datatables.vue';
-    import IconMenuForms from '@/components/icon/menu/icon-menu-forms.vue';
-    import IconMenuUsers from '@/components/icon/menu/icon-menu-users.vue';
-    import IconMenuPages from '@/components/icon/menu/icon-menu-pages.vue';
-    import IconMenuAuthentication from '@/components/icon/menu/icon-menu-authentication.vue';
-    import IconMenuDocumentation from '@/components/icon/menu/icon-menu-documentation.vue';
-
-    const store = useAppStore();
-    const activeDropdown: any = ref('');
-    const subActive: any = ref('');
-
-    onMounted(() => {
-        const selector = document.querySelector('.sidebar ul a[href="' + window.location.pathname + '"]');
-        if (selector) {
-            selector.classList.add('active');
-            const ul: any = selector.closest('ul.sub-menu');
-            if (ul) {
-                let ele: any = ul.closest('li.menu').querySelectorAll('.nav-link') || [];
-                if (ele.length) {
-                    ele = ele[0];
-                    setTimeout(() => {
-                        ele.click();
-                    });
-                }
+import { ref, onMounted } from 'vue';
+import { useStore } from 'vuex';
+import VueCollapsible from 'vue-height-collapsible/vue3';
+
+import IconCaretsDown from '@/components/icon/icon-carets-down.vue';
+import IconMenuDashboard from '@/components/icon/menu/icon-menu-dashboard.vue';
+import IconMinus from '@/components/icon/icon-minus.vue';
+import IconMenuChat from '@/components/icon/menu/icon-menu-chat.vue';
+import IconMenuMailbox from '@/components/icon/menu/icon-menu-mailbox.vue';
+import IconMenuTodo from '@/components/icon/menu/icon-menu-todo.vue';
+import IconMenuNotes from '@/components/icon/menu/icon-menu-notes.vue';
+import IconMenuScrumboard from '@/components/icon/menu/icon-menu-scrumboard.vue';
+import IconMenuContacts from '@/components/icon/menu/icon-menu-contacts.vue';
+import IconMenuInvoice from '@/components/icon/menu/icon-menu-invoice.vue';
+import IconCaretDown from '@/components/icon/icon-caret-down.vue';
+import IconMenuCalendar from '@/components/icon/menu/icon-menu-calendar.vue';
+import IconMenuComponents from '@/components/icon/menu/icon-menu-components.vue';
+import IconMenuElements from '@/components/icon/menu/icon-menu-elements.vue';
+import IconMenuCharts from '@/components/icon/menu/icon-menu-charts.vue';
+import IconMenuWidgets from '@/components/icon/menu/icon-menu-widgets.vue';
+import IconMenuFontIcons from '@/components/icon/menu/icon-menu-font-icons.vue';
+import IconMenuDragAndDrop from '@/components/icon/menu/icon-menu-drag-and-drop.vue';
+import IconMenuTables from '@/components/icon/menu/icon-menu-tables.vue';
+import IconMenuDatatables from '@/components/icon/menu/icon-menu-datatables.vue';
+import IconMenuForms from '@/components/icon/menu/icon-menu-forms.vue';
+import IconMenuUsers from '@/components/icon/menu/icon-menu-users.vue';
+import IconMenuPages from '@/components/icon/menu/icon-menu-pages.vue';
+import IconMenuAuthentication from '@/components/icon/menu/icon-menu-authentication.vue';
+import IconMenuDocumentation from '@/components/icon/menu/icon-menu-documentation.vue';
+
+const store = useStore();
+const activeDropdown: any = ref('');
+const subActive: any = ref('');
+
+onMounted(() => {
+    const selector = document.querySelector('.sidebar ul a[href="' + window.location.pathname + '"]');
+    if (selector) {
+        selector.classList.add('active');
+        const ul: any = selector.closest('ul.sub-menu');
+        if (ul) {
+            let ele: any = ul.closest('li.menu').querySelectorAll('.nav-link') || [];
+            if (ele.length) {
+                ele = ele[0];
+                setTimeout(() => {
+                    ele.click();
+                });
             }
         }
-    });
-
-    const toggleMobileMenu = () => {
-        if (window.innerWidth < 1024) {
-            store.toggleSidebar();
-        }
-    };
+    }
+});
+
+const toggleMobileMenu = () => {
+    if (window.innerWidth < 1024) {
+        store.dispatch('toggleSidebar');
+    }
+};
+const toggleSidebars = () => {
+    store.dispatch('toggleSidebar');
+};
 </script>

+ 12 - 8
src/layouts/app-layout.vue

@@ -2,11 +2,11 @@
     <!--  BEGIN MAIN CONTAINER  -->
     <div class="relative">
         <!-- sidebar menu overlay -->
-        <div class="fixed inset-0 bg-[black]/60 z-50 lg:hidden" :class="{ hidden: !store.sidebar }"
-            @click="store.toggleSidebar()"></div>
+        <div class="fixed inset-0 bg-[black]/60 z-50 lg:hidden" :class="{ hidden: !store.state.sidebar }"
+            @click="toggleSidebar"></div>
 
         <!-- screen loader -->
-        <div v-show="store.isShowMainLoader"
+        <div v-show="store.state.isShowMainLoader"
             class="screen_loader fixed inset-0 bg-[#fafafa] dark:bg-[#060818] z-[60] grid place-content-center animate__animated">
             <svg width="64" height="64" viewBox="0 0 135 135" xmlns="http://www.w3.org/2000/svg" fill="#4361ee">
                 <path
@@ -44,7 +44,7 @@
         <Setting />
         <!-- END APP SETTING LAUNCHER -->
 
-        <div class="main-container text-black dark:text-white-dark min-h-screen" :class="[store.navbar]">
+        <div class="main-container text-black dark:text-white-dark min-h-screen" :class="[store.state.navbar]">
             <!--  BEGIN SIDEBAR  -->
             <Sidebar />
             <!--  END SIDEBAR  -->
@@ -72,11 +72,10 @@ import { ref, onMounted } from 'vue';
 import Sidebar from '@/components/layout/Sidebar.vue';
 import Header from '@/components/layout/Header.vue';
 import Footer from '@/components/layout/Footer.vue';
-// import Setting from '@/components/ThemeCustomizer.vue';
+ import Setting from '@/components/ThemeCustomizer.vue';
 import appSetting from '@/app-setting';
 
-import { useAppStore } from '@/stores/index';
-const store = useAppStore();
+import store from '@/stores';
 const showTopButton = ref(false);
 onMounted(() => {
     window.onscroll = () => {
@@ -91,11 +90,16 @@ onMounted(() => {
     eleanimation.addEventListener('animationend', function () {
         appSetting.changeAnimation('remove');
     });
-    store.toggleMainLoader();
+    store.dispatch('toggleMainLoader');
+    /*     store.toggleMainLoader(); */
 });
 
 const goToTop = () => {
     document.body.scrollTop = 0;
     document.documentElement.scrollTop = 0;
 };
+const toggleSidebar = () => {
+    console.log(store.dispatch('toggleSidebar'));
+    store.dispatch('toggleSidebar');
+};
 </script>

+ 2 - 2
src/layouts/auth-layout.vue

@@ -47,8 +47,8 @@
 </template>
 <script setup lang="ts">
     import { ref, onMounted } from 'vue';
-    import { useAppStore } from '@/stores/index';
-    const store = useAppStore();
+    import { useStore } from 'vuex';
+    const store:any = useStore();
     const showTopButton = ref(false);
     onMounted(() => {
         window.onscroll = () => {

+ 2 - 0
src/main.ts

@@ -68,4 +68,6 @@ app.use(ElementPlus)
 /* 全局引入 */
 import './permission' 
 
+import store from './stores';
+app.use(store);
 app.mount('#app');

+ 2 - 2
src/permission.js

@@ -1,5 +1,5 @@
 import router from './router'
-import { useAppStore } from '@/stores'
+import { useStore } from 'vuex';
 /* import NProgress from 'nprogress' // Progress 进度条
 import 'nprogress/nprogress.css' // Progress 进度条样式 */
 import { ElMessage } from 'element-plus'
@@ -31,7 +31,7 @@ let toFirstRoute = function getTopRoutePath(router, next) {
 console.log(router);
 router.beforeEach(async (to, from, next) => {
 /*   NProgress.start() */
-  const store = useAppStore()
+  const store = useStore()
   console.log(store);
   const refreshToken = Storage.getItem('admin_refresh_token')
   if (refreshToken) {

+ 1 - 1
src/router/index.ts

@@ -1,5 +1,5 @@
 import { createRouter, createWebHistory, RouteRecordRaw, createWebHashHistory, Router } from 'vue-router';
-import { useAppStore } from '@/stores/index';
+import { useStore } from 'vuex';
 import appSetting from '@/app-setting';
 
 const constantRouterMap: RouteRecordRaw[] = [

+ 2 - 1
src/stores/getters.ts

@@ -8,7 +8,8 @@ const getters = {
     permission_routers: (state: { permission: { routers: any } }) => state.permission.routers,
     addRouters: (state: { permission: { addRouters: any } }) => state.permission.addRouters,
     routersAlls: (state: { permission: { routersAlls: any } }) => state.permission.routersAlls,
-    siteInfo: (state: { app: { siteInfo: any } }) => state.app.siteInfo
+    siteInfo: (state: { app: { siteInfo: any } }) => state.app.siteInfo,
+    languageList: (state: any) => state.languageList,
   }
   export default getters
   

+ 128 - 75
src/stores/index.ts

@@ -1,13 +1,20 @@
 /* import { defineStore } from 'pinia';
+import { createStore } from 'vuex';
 import i18n from '@/i18n';
 import appSetting from '@/app-setting';
-import app from './modules/app'
-import permission from './modules/permission'
-import tagsView from './modules/tagsView'
-import * as user from './modules/user'
-import getters from './getters'
+import app from './modules/app';
+import permission from './modules/permission';
+import tagsView from './modules/tagsView';
+import * as user from './modules/user';
+import getters from './getters';
 
 export const useAppStore = defineStore('app', {
+    modules: {
+        app,
+        permission,
+        tagsView,
+        user
+    },
     state: () => ({
         isDarkMode: false,
         mainLayout: 'app',
@@ -21,9 +28,7 @@ export const useAppStore = defineStore('app', {
         sidebar: false,
         languageList: [
             { code: 'zh', name: 'Chinese' },
-
             { code: 'en', name: 'English' },
-
         ],
         isShowMainLoader: true,
         semidark: false,
@@ -35,7 +40,7 @@ export const useAppStore = defineStore('app', {
 
     actions: {
         setMainLayout(payload: any = null) {
-            this.mainLayout = payload; //app , auth
+            this.mainLayout = payload; // app , auth
         },
         toggleTheme(payload: any = null) {
             payload = payload || this.theme; // light|dark|system
@@ -43,8 +48,7 @@ export const useAppStore = defineStore('app', {
             this.theme = payload;
             if (payload == 'light') {
                 this.isDarkMode = false;
-            }
-            else if (payload == 'dark') {
+            } else if (payload == 'dark') {
                 this.isDarkMode = true;
             } else if (payload == 'system') {
                 if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
@@ -62,7 +66,7 @@ export const useAppStore = defineStore('app', {
         },
         toggleMenu(payload: any = null) {
             payload = payload || this.menu; // vertical, collapsible-vertical, horizontal
-            this.sidebar = false; // reset sidebar state
+            //this.sidebar = false; // reset sidebar state
             localStorage.setItem('menu', payload);
             this.menu = payload;
         },
@@ -95,6 +99,7 @@ export const useAppStore = defineStore('app', {
             this.semidark = payload;
         },
         toggleLocale(payload: any = null) {
+            console.log(payload);
             payload = payload || this.locale;
             i18n.global.locale.value = payload;
             localStorage.setItem('i18n_locale', payload);
@@ -116,9 +121,9 @@ export const useAppStore = defineStore('app', {
         },
     },
     getters,
-});
- */
-import { defineStore } from 'pinia';
+}); */
+
+import { createStore } from 'vuex';
 import i18n from '@/i18n';
 import appSetting from '@/app-setting';
 import app from './modules/app';
@@ -127,8 +132,36 @@ import tagsView from './modules/tagsView';
 import * as user from './modules/user';
 import getters from './getters';
 
-export const useAppStore = defineStore('app', {
-    state: () => ({
+// 定义 State 类型
+export interface State {
+    isDarkMode: boolean;
+    mainLayout: string;
+    theme: string;
+    menu: string;
+    layout: string;
+    rtlClass: string;
+    animation: string;
+    navbar: string;
+    locale: string;
+    sidebar: boolean;
+    languageList: Array<{ code: string; name: string }>;
+    isShowMainLoader: boolean;
+    semidark: boolean;
+    app: typeof app;
+    permission: typeof permission;
+    tagsView: typeof tagsView;
+    user: typeof user;
+}
+
+// 创建 store
+const store = createStore<State>({
+    modules: {
+        app,
+        permission,
+        tagsView,
+        user
+    },
+    state: {
         isDarkMode: false,
         mainLayout: 'app',
         theme: 'light',
@@ -149,89 +182,109 @@ export const useAppStore = defineStore('app', {
         permission,
         tagsView,
         user
-    }),
-
-    actions: {
-        setMainLayout(payload: any = null) {
-            this.mainLayout = payload; // app , auth
+    },
+    mutations: {
+        setMainLayout(state, payload) {
+            state.mainLayout = payload;
         },
-        toggleTheme(payload: any = null) {
-            payload = payload || this.theme; // light|dark|system
+        toggleTheme(state, payload) {
+            payload = payload || state.theme;
             localStorage.setItem('theme', payload);
-            this.theme = payload;
-            if (payload == 'light') {
-                this.isDarkMode = false;
-            } else if (payload == 'dark') {
-                this.isDarkMode = true;
-            } else if (payload == 'system') {
-                if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
-                    this.isDarkMode = true;
-                } else {
-                    this.isDarkMode = false;
-                }
-            }
-
-            if (this.isDarkMode) {
-                document.querySelector('body')?.classList.add('dark');
-            } else {
-                document.querySelector('body')?.classList.remove('dark');
-            }
+            state.theme = payload;
+            state.isDarkMode = payload === 'dark' || (payload === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
+            document.querySelector('body')?.classList.toggle('dark', state.isDarkMode);
         },
-        toggleMenu(payload: any = null) {
-            payload = payload || this.menu; // vertical, collapsible-vertical, horizontal
-            //this.sidebar = false; // reset sidebar state
+        toggleMenu(state, payload) {
+            payload = payload || state.menu;
             localStorage.setItem('menu', payload);
-            this.menu = payload;
+            state.menu = payload;
         },
-        toggleLayout(payload: any = null) {
-            payload = payload || this.layout; // full, boxed-layout
+        toggleLayout(state, payload) {
+            payload = payload || state.layout;
             localStorage.setItem('layout', payload);
-            this.layout = payload;
+            state.layout = payload;
         },
-        toggleRTL(payload: any = null) {
-            payload = payload || this.rtlClass; // rtl, ltr
+        toggleRTL(state, payload) {
+            payload = payload || state.rtlClass;
             localStorage.setItem('rtlClass', payload);
-            this.rtlClass = payload;
-            document.querySelector('html')?.setAttribute('dir', this.rtlClass || 'ltr');
+            state.rtlClass = payload;
+            document.querySelector('html')?.setAttribute('dir', state.rtlClass || 'ltr');
         },
-        toggleAnimation(payload: any = null) {
-            payload = payload || this.animation; // animate__fadeIn, animate__fadeInDown, animate__fadeInUp, animate__fadeInLeft, animate__fadeInRight, animate__slideInDown, animate__slideInLeft, animate__slideInRight, animate__zoomIn
-            payload = payload?.trim();
+        toggleAnimation(state, payload) {
+            payload = payload?.trim() || state.animation;
             localStorage.setItem('animation', payload);
-            this.animation = payload;
+            state.animation = payload;
             appSetting.changeAnimation();
         },
-        toggleNavbar(payload: any = null) {
-            payload = payload || this.navbar; // navbar-sticky, navbar-floating, navbar-static
+        toggleNavbar(state, payload) {
+            payload = payload || state.navbar;
             localStorage.setItem('navbar', payload);
-            this.navbar = payload;
+            state.navbar = payload;
         },
-        toggleSemidark(payload: any = null) {
+        toggleSemidark(state, payload) {
             payload = payload || false;
             localStorage.setItem('semidark', payload);
-            this.semidark = payload;
+            state.semidark = payload;
         },
-        toggleLocale(payload: any = null) {
-            console.log(payload);
-            payload = payload || this.locale;
+        toggleLocale(state, payload) {
+            payload = payload || state.locale;
             i18n.global.locale.value = payload;
             localStorage.setItem('i18n_locale', payload);
-            this.locale = payload;
-            if (this.locale?.toLowerCase() === 'ae') {
-                this.toggleRTL('rtl');
+            state.locale = payload;
+            if (state.locale?.toLowerCase() === 'ae') {
+                state.rtlClass = 'rtl';
             } else {
-                this.toggleRTL('ltr');
+                state.rtlClass = 'ltr';
             }
+            document.querySelector('html')?.setAttribute('dir', state.rtlClass || 'ltr');
         },
-        toggleSidebar(state: boolean = false) {
-            this.sidebar = !this.sidebar;
+        toggleSidebar(state) {
+            console.log(state.sidebar);
+            state.sidebar = !state.sidebar;
         },
-        toggleMainLoader(state: boolean = false) {
-            this.isShowMainLoader = true;
+        toggleMainLoader(state) {
+            state.isShowMainLoader = true;
             setTimeout(() => {
-                this.isShowMainLoader = false;
+                state.isShowMainLoader = false;
             }, 500);
+        }
+    },
+    actions: {
+        setMainLayout({ commit }, payload) {
+            commit('setMainLayout', payload);
         },
+        toggleTheme({ commit }, payload) {
+            commit('toggleTheme', payload);
+        },
+        toggleMenu({ commit }, payload) {
+            commit('toggleMenu', payload);
+        },
+        toggleLayout({ commit }, payload) {
+            commit('toggleLayout', payload);
+        },
+        toggleRTL({ commit }, payload) {
+            commit('toggleRTL', payload);
+        },
+        toggleAnimation({ commit }, payload) {
+            commit('toggleAnimation', payload);
+        },
+        toggleNavbar({ commit }, payload) {
+            commit('toggleNavbar', payload);
+        },
+        toggleSemidark({ commit }, payload) {
+            commit('toggleSemidark', payload);
+        },
+        toggleLocale({ commit }, payload) {
+            commit('toggleLocale', payload);
+        },
+        toggleSidebar({ commit }) {
+            commit('toggleSidebar');
+        },
+        toggleMainLoader({ commit }) {
+            commit('toggleMainLoader');
+        }
     },
-    getters,
-});
+    getters
+});
+
+export default store;

+ 2 - 0
src/stores/modules/user.js

@@ -30,6 +30,7 @@ export const mutations = {
    */
   SET_ACCESS_TOKEN: (state, token) => {
     const expires = new Date(jwt_decode(token).exp * 1000)
+    console.log(112,expires);
     Storage.setItem('admin_access_token', token, { expires })
   },
   /**
@@ -91,6 +92,7 @@ export const actions = {
       } else {
         API_Login.loginByFranchise(params).then(response => {
           const { access_token, refresh_token, ...user } = response
+          console.log(113);
           commit('SET_USER', user)
           commit('SET_ACCESS_TOKEN', access_token)
           commit('SET_REFRESH_TOKEN', refresh_token)

+ 6 - 6
src/utils/checkToken.js

@@ -3,7 +3,7 @@
  */
 
 import Storage from './storage'
-import {useAppStore} from '../stores/index'
+import { useStore } from 'vuex';
 import router from '@/router'
 import * as API_Common from '@/api/common'
 import { ElMessageBox  } from 'element-plus'
@@ -43,7 +43,7 @@ export default function checkToken(options) {
      * 说明登录已失效、或者cookie有问题,需要重新登录。
      */
     if (!refreshToken || !user) {
-        useAppStore.dispatch('fedLogoutAction')
+        useStore.dispatch('fedLogoutAction')
       ElMessageBox.alert('您的登录状态已失效,请重新登录!', '权限错误', {
         type: 'error',
         callback: () => {
@@ -71,14 +71,14 @@ export default function checkToken(options) {
           ? API_Common.refreshFranchiseToken
           : API_Common.refreshToken
         refreshTokenFunc().then(response => {
-            useAppStore.dispatch('setAccessTokenAction', response.accessToken)
-            useAppStore.dispatch('setRefreshTokenAction', response.refreshToken)
+            useStore.dispatch('setAccessTokenAction', response.accessToken)
+            useStore.dispatch('setRefreshTokenAction', response.refreshToken)
           window.__refreshTokenLock__ = null
           // console.log(options.url + ' | 已拿到新的token。')
           resolve()
         }).catch(() => {
           window.__refreshTokenLock__ = undefined
-          useAppStore.dispatch('fedLogoutAction')
+          useStore.dispatch('fedLogoutAction')
           window.location.replace(loginPath)
         })
       } else {
@@ -90,7 +90,7 @@ export default function checkToken(options) {
             // console.log(options.url + ' | 是否已拿到新的token:', __RTK__ === null)
             if (__RTK__ === undefined) {
               // console.log('登录已失效了,不用再等待了...')
-              useAppStore.dispatch('fedLogoutAction')
+              useStore.dispatch('fedLogoutAction')
               window.location.replace(loginPath)
               return
             }

+ 4 - 4
src/utils/request.js

@@ -1,7 +1,7 @@
 import * as Vue from 'vue';
 import { ElLoading  } from 'element-plus'
 import axios from 'axios'
-import {useAppStore} from '@/stores'
+import { useStore } from 'vuex';
 import router from '@/router'
 import Storage from '@/utils/storage'
 /* import https from 'https' */
@@ -15,7 +15,7 @@ import * as qs from 'qs'
 
 // 创建axios实例
 const service = axios.create({
-  baseURL: 'http://192.168.8.107:9999',
+  baseURL: 'http://192.168.8.101:9998',
   timeout: 5000,
 
   paramsSerializer: params => qs.stringify(params, { arrayFormat: 'repeat' })
@@ -49,7 +49,7 @@ service.interceptors.request.use(config => {
     config.headers['Authorization'] = accessToken
   }
   // 如果是上传接口,不限制超时时间${api.admin}
-  if (config.url === `http://192.168.8.107:9999/uploaders`) {
+  if (config.url === `http://192.168.8.101:9998/uploaders`) {
     config.timeout = 0
   }
   return config
@@ -69,7 +69,7 @@ service.interceptors.response.use(
     const error_data = error_response.data || {}
     if (error_response.status === 403) {
       if (!Storage.getItem('admin_refresh_token')) return
-      useAppStore.dispatch('fedLogoutAction')
+      useStore.dispatch('fedLogoutAction')
       let to = Storage.getItem('admin_franchise') ? '/franchise/login' : '/login'
       window.location.replace(router.resolve(to).href)
       return

+ 41 - 38
src/utils/storage.js

@@ -1,12 +1,6 @@
-/**
- * Created by Andste on 2021/12/25.
- */
-
-import Cookies from 'js-cookie'
+import Cookies from 'js-cookie';
 
-import psl from 'psl';
-
-const cookieKeys = ['admin_uuid', 'admin_uid']
+const cookieKeys = ['admin_uuid', 'admin_uid'];
 
 /**
  * 判断是否需要储存为Cookie
@@ -14,7 +8,7 @@ const cookieKeys = ['admin_uuid', 'admin_uid']
  * @returns {boolean}
  */
 function isCookieKey(key) {
-  return cookieKeys.indexOf(key) !== -1
+  return cookieKeys.indexOf(key) !== -1;
 }
 
 /**
@@ -24,12 +18,13 @@ function isCookieKey(key) {
  * @param options
  */
 function setItem(key, value, options = {}) {
+  console.log(`Setting item: ${key}, value: ${value}, options:`, options); // 添加日志
   if (options.expires === undefined) {
-    options.expires = 365 * 10
+    options.expires = 365 * 10;
   }
   return isCookieKey(key)
     ? setCookieItem(key, value, options)
-    : setLocalItem(key, value, options)
+    : setLocalItem(key, value, options);
 }
 
 /**
@@ -40,7 +35,7 @@ function setItem(key, value, options = {}) {
 function getItem(key) {
   return isCookieKey(key)
     ? getCookieItem(key)
-    : getLocalItem(key)
+    : getLocalItem(key);
 }
 
 /**
@@ -51,7 +46,7 @@ function getItem(key) {
 function removeItem(key, options) {
   return isCookieKey(key)
     ? removeCookieItem(key, options)
-    : removeLocalItem(key)
+    : removeLocalItem(key);
 }
 
 // ========== LocalStorage ========== //
@@ -63,17 +58,17 @@ function removeItem(key, options) {
  * @param options
  */
 function setLocalItem(key, value, options = {}) {
-  let { expires } = options
+  let { expires } = options;
   if (typeof expires === 'number') {
-    expires = new Date().getTime() + expires * 86400 * 1000
+    expires = new Date().getTime() + expires * 86400 * 1000;
   } else if (typeof expires === 'object') {
-    expires = expires.getTime()
+    expires = expires.getTime();
   }
   value = JSON.stringify({
     expires,
     data: value
-  })
-  localStorage.setItem(key, value)
+  });
+  localStorage.setItem(key, value);
 }
 
 /**
@@ -82,15 +77,15 @@ function setLocalItem(key, value, options = {}) {
  * @returns {string}
  */
 function getLocalItem(key) {
-  let object = localStorage.getItem(key)
-  if (!object) return ''
-  object = JSON.parse(object)
-  const { expires } = object
+  let object = localStorage.getItem(key);
+  if (!object) return '';
+  object = JSON.parse(object);
+  const { expires } = object;
   if (typeof expires === 'number' && expires <= Date.now()) {
-    localStorage.removeItem(key)
-    return ''
+    localStorage.removeItem(key);
+    return '';
   }
-  return object.data
+  return object.data;
 }
 
 /**
@@ -98,11 +93,23 @@ function getLocalItem(key) {
  * @param key
  */
 function removeLocalItem(key) {
-  localStorage.removeItem(key)
+  localStorage.removeItem(key);
 }
 
 // ========== Cookie ========== //
 
+/**
+ * 获取根域名
+ * @returns {string}
+ */
+function getRootDomain() {
+  const parts = document.domain.split('.').reverse();
+  if (parts.length >= 2) {
+    return parts[1] + '.' + parts[0];
+  }
+  return document.domain;
+}
+
 /**
  * 设置CookieItem
  * @param key
@@ -110,11 +117,9 @@ function removeLocalItem(key) {
  * @param options
  */
 function setCookieItem(key, value, options = {}) {
-  const p_psl = psl.parse(document.domain)
-  let domain = p_psl.domain
-  if (/\d+\.\d+\.\d+\.\d+/.test(p_psl.input)) domain = p_psl.input
-  options = { domain, ...options }
-  Cookies.set(key, value, options)
+  const domain = getRootDomain();
+  options = { domain, ...options };
+  Cookies.set(key, value, options);
 }
 
 /**
@@ -123,7 +128,7 @@ function setCookieItem(key, value, options = {}) {
  * @returns {*}
  */
 function getCookieItem(key) {
-  return Cookies.get(key)
+  return Cookies.get(key);
 }
 
 /**
@@ -132,15 +137,13 @@ function getCookieItem(key) {
  * @param options
  */
 function removeCookieItem(key, options = {}) {
-  const p_psl = psl.parse(document.domain)
-  let domain = p_psl.domain
-  if (/\d+\.\d+\.\d+\.\d+/.test(p_psl.input)) domain = p_psl.input
-  options = { domain, ...options }
-  Cookies.remove(key, options)
+  const domain = getRootDomain();
+  options = { domain, ...options };
+  Cookies.remove(key, options);
 }
 
 export default {
   setItem,
   getItem,
   removeItem
-}
+};

+ 44 - 35
src/views/auth/boxed-signin.vue

@@ -58,7 +58,7 @@
                                 登录
                             </button>
                         </form> -->
-                        <el-form :model="loginForm" ref="loginFormRef" class="login-input">
+                        <el-form :model="loginForm" :rules="loginRules" ref="loginFormRef" class="login-input">
                             <el-form-item prop="username">
                                 <el-input v-model="loginForm.username" :placeholder="$t('username')" autofocus
                                     clearable>
@@ -115,17 +115,18 @@
 </template>
 <script lang="ts" setup>
 import { computed, onMounted, reactive, ref } from 'vue';
-import Vue from 'vue'
+
 import { useI18n } from 'vue-i18n';
 import appSetting from '@/app-setting';
-import { useAppStore } from '@/stores/index';
+import { useStore } from 'vuex';
 import { useRouter, useRoute } from 'vue-router';
 import { useMeta } from '@/composables/use-meta';
 import Storage from '@/utils/storage'
 import * as API_common from '@/api/common'
 import { v4 as uuidv4 } from "uuid";
 import AliyunAfs from '@/composables/AliyunAfs'
-import type { FormInstance } from 'element-plus'
+import { ElMessage, FormInstance } from 'element-plus'
+import app from '@/stores/modules/app';
 
 
 const loading: any = ref(false)
@@ -133,10 +134,11 @@ const loginForm = reactive({
     username: '',
     password: '',
     scene: 'LOGIN',
-    validcode: ''
+    validcode: '',
+    company_name: 'aslkf'
 });
 const { t } = useI18n();
-/* const loginRules = reactive({
+const loginRules = reactive({
     username: [
         { required: true, message: t('val_username'), trigger: 'blur' }
     ],
@@ -146,7 +148,7 @@ const { t } = useI18n();
     validcode: [
         { required: true, message: t('val_validcode'), trigger: 'blur' }
     ]
-}); */
+});
 // 验证信息
 const validateInFO: any = ref({})
 let validcodeImg: any = ref('')
@@ -169,7 +171,7 @@ const loginFormRef = ref<FormInstance>()
 useMeta({ title: 'Login Boxed' });
 const router = useRouter();
 const route = useRoute()
-const store = useAppStore();
+const store = useStore();
 // multi language
 const i18n = reactive(useI18n());
 console.log(i18n);
@@ -222,34 +224,40 @@ const MixinClone = (obj) => {
 
 /** 登录处理 */
 const dispatchLoginAction = (params) => {
-    loading = true
+    loading.value = true;
     return new Promise((resolve, reject) => {
-        useAppStore.dispatch('loginAction', params).then((res) => {
-            loading = false
-            if (res && api.adminWS) {
+        console.log(store.dispatch);
+        store.dispatch('loginAction', params).then((res: any) => {
+            loading.value = false;
+            console.log(res);
+            if (res) {
                 try {
-                    const WS = new WebSocket(api.adminWS, res.access_token)
-                    Vue.prototype.$WS = WS
+                    const WS = new WebSocket(res.access_token);
+                    // 使用 provide/inject 或其他方式在 Vue 3 中共享 WebSocket 实例
+                    app.provide('websocket', WS);
                 } catch (error) {
-                    console.log('websocket 实例化失败:', error)
+                    console.log('websocket 实例化失败:', error);
                 }
             }
-            const forward = route.query.forward
+            const forward = route.query.forward;
             console.log(forward);
-            let query = JSON.parse(JSON.stringify(route.query))
-
+            let query = JSON.parse(JSON.stringify(route.query));
             //delete query.forward
-            router.push({ path: '/', query }).catch(() => { })//forward ||
+            router.replace({
+                name: 'dashboard'
+            });
+           // router.push({ path: 'dashboard', query }).catch(() => { }); //forward ||
         }).catch(() => {
-            loading = false
-            reject()
-        })
-    })
+            loading.value = false;
+            reject();
+        });
+    });
 }
 
 const submitLogin = (formEl: FormInstance | undefined) => {
     if (!accountAfsSuccess) return
-    if (afs) {
+    console.log(!afs);
+    if (!afs) {
         const params = MixinClone(loginForm)
         params.c_sessionid = afsParam.c_sessionid
         params.sig = afsParam.sig
@@ -257,24 +265,25 @@ const submitLogin = (formEl: FormInstance | undefined) => {
         delete params.validcode
         delete params.scene
         dispatchLoginAction(params).catch(() => {
-            // this.afs.reload()
             accountAfsSuccess.value = false
         })
     } else {
-        formEl.validate((valid) => {
+        formEl?.validate((valid: boolean) => {
             if (valid) {
-                const params = MixinClone(loginForm)
-                params.uuid = uuid
-                params.captcha = params.validcode
-                delete params.validcode
+                const params = MixinClone(loginForm);
+                params.uuid = uuid;
+                params.captcha = params.validcode;
+                delete params.validcode;
+                console.log(params);
                 dispatchLoginAction(params).catch(() => {
-                    changeValidcode()
-                })
+                    changeValidcode();
+                });
             } else {
-                //this.$message.error(this.translateKey('val_form'))
-                return false
+                // 使用 Element Plus 的消息提示
+                ElMessage.error(t('val_form'));
+                return false;
             }
-        })
+        });
     }
 }
 

+ 8 - 1
yarn.lock

@@ -809,7 +809,7 @@
     "@vue/compiler-dom" "3.4.29"
     "@vue/shared" "3.4.29"
 
-"@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.5.1":
+"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.5.1":
   version "6.6.3"
   resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.3.tgz#b23a588154cba8986bba82b6e1d0248bde3fd1a0"
   integrity sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==
@@ -3370,6 +3370,13 @@ vue@^3.0.0, vue@^3.0.11, vue@^3.2.37:
     "@vue/server-renderer" "3.4.29"
     "@vue/shared" "3.4.29"
 
+vuex@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.npmmirror.com/vuex/-/vuex-4.1.0.tgz#aa1b3ea5c7385812b074c86faeeec2217872e36c"
+  integrity sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==
+  dependencies:
+    "@vue/devtools-api" "^6.0.0-beta.11"
+
 which@^2.0.1:
   version "2.0.2"
   resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"