Your Name
2022-06-28 999935f3e7a6ff1cf286bedfdbb7ccd64bed556a
'lct'
已修改11个文件
1449 ■■■■ 文件已修改
.env.development 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/backEnd.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/frontEnd.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/interface/index.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/userInfo.ts 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.ts 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/index.vue 247 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/component/account.vue 285 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.vue 290 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/menu/component/menuDialog.vue 345 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/menu/index.vue 157 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.development
@@ -2,7 +2,7 @@
ENV = 'development'
# 本地环境接口地址
VITE_API_URL = 'http://192.168.0.35:8009'
VITE_API_URL = 'http://192.168.0.35:8008'
# VITE_API_URL = 'http://192.168.0.8:8008'
# VITE_API_URL = 'http://192.168.0.10:8008'
src/router/backEnd.ts
@@ -29,14 +29,12 @@
export async function initBackEndControlRoutes() {
    if (window.nextLoading === undefined) NextLoading.start();
    if (!Session.get('token')) return false;
    useUserInfo().setUserInfos();
    // if(Session.get('ifMenu'))
    const res = await getBackEndControlRoutes(Session.get('projectId'));
    useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data.data)));
    dynamicRoutes[0].children = await backEndComponent(res.data.data);
    await setAddRoute();
    await setFilterMenuAndCacheTagsViewRoutes();
    }
}
export function setFilterMenuAndCacheTagsViewRoutes() {
@@ -67,9 +65,9 @@
export async function getBackEndControlRoutes(value : string) {
    const stores = useUserInfo(pinia);
    const { userInfos } = storeToRefs(stores);
    const auth = userInfos.value.roles[0];
    // const stores = useUserInfo(pinia);
    // const { userInfos } = storeToRefs(stores);
    // const auth = userInfos.value.roles[0];
    return menuApi.getMenuAdmin(value);
}
src/router/frontEnd.ts
@@ -13,7 +13,7 @@
export async function initFrontEndControlRoutes() {
    if (window.nextLoading === undefined) NextLoading.start();
    if (!Session.get('token')) return false;
    useUserInfo(pinia).setUserInfos();
    // useUserInfo(pinia).setUserInfos();
    await setAddRoute();
    await setFilterMenuAndCacheTagsViewRoutes();
}
src/stores/interface/index.ts
@@ -10,7 +10,8 @@
    roles: string[];
    time: number;
    userName: string;
    sign:string;
    uid:string;
    projectId:string;
}
export interface UserInfosStates {
    userInfos: UserInfosState;
@@ -41,6 +42,14 @@
    projectId:string,
}
export interface loginInfoState {
    loginUser:{
        projectId:string,
        token:string,
        uid:string,
    }
}
// 布局配置
export interface ThemeConfigState {
    isDrawer: boolean;
src/stores/userInfo.ts
@@ -15,51 +15,57 @@
            time: 0,
            roles: [],
            authBtnList: [],
            sign:'',
            uid:'',
            projectId:''
        },
    }),
    actions: {
        async setUserInfos() {
            const userName = Cookies.get('userName');
            // 模拟数据
            let defaultRoles: Array<string> = [];
            let defaultAuthBtnList: Array<string> = [];
            // admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
            let adminRoles: Array<string> = ['admin'];
            // admin 按钮权限标识
            let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link'];
            // test 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
            let testRoles: Array<string> = ['common'];
            // test 按钮权限标识
            let testAuthBtnList: Array<string> = ['btn.add', 'btn.link'];
            // 不同用户模拟不同的用户权限
            if (userName === 'admin') {
                defaultRoles = adminRoles;
                defaultAuthBtnList = adminAuthBtnList;
            } else {
                defaultRoles = testRoles;
                defaultAuthBtnList = testAuthBtnList;
            }
            // 用户信息模拟数据
            const userInfos = {
                userName: userName,
                photo:
                    userName === 'admin'
                        ? 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg'
                        : 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=317673774,2961727727&fm=26&gp=0.jpg',
                time: new Date().getTime(),
                roles: defaultRoles,
                authBtnList: defaultAuthBtnList,
                sign:'',
            };
            // 存储用户信息到浏览器缓存
            Session.set('userInfo', userInfos);
            if (Session.get('userInfo')) {
                this.userInfos = Session.get('userInfo');
            } else {
                this.userInfos = userInfos;
            }
        async setUserInfos(value: any) {
            debugger
            this.userInfos.userName = value.username
            this.userInfos.uid = value.id
            this.userInfos.roles = value.role
            // const userName = Cookies.get('userName');
            // // 模拟数据
            // let defaultRoles: Array<string> = [];
            // let defaultAuthBtnList: Array<string> = [];
            // // admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
            // let adminRoles: Array<string> = ['admin'];
            // // admin 按钮权限标识
            // let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link'];
            // // test 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
            // let testRoles: Array<string> = ['common'];
            // // test 按钮权限标识
            // let testAuthBtnList: Array<string> = ['btn.add', 'btn.link'];
            // // 不同用户模拟不同的用户权限
            // if (userName === 'admin') {
            //     defaultRoles = adminRoles;
            //     defaultAuthBtnList = adminAuthBtnList;
            // } else {
            //     defaultRoles = testRoles;
            //     defaultAuthBtnList = testAuthBtnList;
            // }
            // // 用户信息模拟数据
            // const userInfos = {
            //     userName: userName,
            //     photo:
            //         userName === 'admin'
            //             ? 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg'
            //             : 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=317673774,2961727727&fm=26&gp=0.jpg',
            //     time: new Date().getTime(),
            //     roles: defaultRoles,
            //     authBtnList: defaultAuthBtnList,
            //     uid:'',
            //     projectId:'',
            // };
            // // 存储用户信息到浏览器缓存
            // Session.set('userInfo', userInfos);
            //
            // if (Session.get('userInfo')) {
            //     this.userInfos = Session.get('userInfo');
            // } else {
            //     this.userInfos = userInfos;
            // }
        },
    },
});
src/utils/request.ts
@@ -1,6 +1,8 @@
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Session } from '/@/utils/storage';
import {useUserInfo} from "/@/stores/userInfo";
import {storeToRefs} from "pinia";
// 配置新建一个 axios 实例
const service = axios.create({
@@ -13,8 +15,10 @@
    (config) => {
        // 在发送请求之前做些什么 token
        if (Session.get('token')) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
            (<any>config.headers).common['Authorization'] = `${Session.get('token')}`;
            (<any>config.headers).common['uid'] = `${Session.get('sign')}`;
            (<any>config.headers).common['uid'] = `${Session.get('uid')}`;
        }
        return config;
    },
@@ -28,13 +32,13 @@
    (response) => {
        // 对响应数据做点什么
        if(response.data.code && (response.data.code ==='A0215' || response.data.code === 'A0214')){
        if(response.data.code && (response.data.code ==='A0215' || response.data.code === 'A0214' || response.data.code === 'A0213')){
            Session.clear()
            window.location.href = '/'
            return Promise.reject(response)
        }
        // if(response.data.code && response.data.code !== '200'){
            return Promise.resolve(response)
        return Promise.resolve(response)
        // }
        // Session.clear()
        // window.location.href = '/'
src/views/home/index.vue
@@ -2,14 +2,14 @@
    <div class="home-container">
        <el-row :gutter="15" class="home-card-one mb15">
            <el-col
                :xs="24"
                :sm="12"
                :md="12"
                :lg="4"
                :xl="4"
                v-for="(v, k) in homeOne"
                :key="k"
                :class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }"
                    :xs="24"
                    :sm="12"
                    :md="12"
                    :lg="4"
                    :xl="4"
                    v-for="(v, k) in homeOne"
                    :key="k"
                    :class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }"
            >
                <div class="home-card-item flex" >
                    <el-button @click="renderMenu(v.id)">{{v.name}}</el-button>
@@ -50,142 +50,133 @@
</template>
<script lang="ts">
import { toRefs, reactive, defineComponent, onMounted, ref, watch, nextTick, onActivated } from 'vue';
import * as echarts from 'echarts';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { initBackEndControlRoutes } from '/@/router/backEnd';
import {Session} from "/@/utils/storage";
import {useRoutesList} from "/@/stores/routesList";
import pinia from "/@/stores";
    import { toRefs, reactive, defineComponent, } from 'vue';
    import { storeToRefs } from 'pinia';
    import { initBackEndControlRoutes } from '/@/router/backEnd';
    import {useUserInfo} from "/@/stores/userInfo";
    import { Session } from '/@/utils/storage';
    let global: any = {
        homeChartOne: null,
        homeChartTwo: null,
        homeCharThree: null,
        dispose: [null, '', undefined],
    };
let global: any = {
    homeChartOne: null,
    homeChartTwo: null,
    homeCharThree: null,
    dispose: [null, '', undefined],
};
interface stateType {
    projectId:string,
    homeOne: Array <type>
}
interface type {
    id:number,
    name: string
}
export default defineComponent({
    name: 'home',
    setup() {
        const storesRoutesList = useRoutesList(pinia);
        const { routesList } = storeToRefs(storesRoutesList);
        // const storesTagsViewRoutes = useTagsViewRoutes();
        // const storesThemeConfig = useThemeConfig();
        const state  = reactive<stateType>({
            projectId:'',
            homeOne:[{id:1,name:'基础数据权限管理系统'},{id:2,name:'系统1'},{id:3,name:'系统2'},{id:4,name:'系统3'},{id:5,name:'系统4'}],
        });
        // 折线图
        const renderMenu = async (value: string) => {
            state.projectId = value
            Session.set('projectId',value)
            await initBackEndControlRoutes();
        };
        return {
            renderMenu,
            ...toRefs(state),
        };
    },
});
    interface stateType {
        homeOne: Array <type>
    }
    interface type {
        id:number,
        name: string
    }
    export default defineComponent({
        name: 'home',
        setup() {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
            const state  = reactive<stateType>({
                homeOne:[{id:1,name:'基础数据权限管理系统'},{id:2,name:'系统1'},{id:3,name:'系统2'},{id:4,name:'系统3'},{id:5,name:'系统4'}],
            });
            // 折线图
            const renderMenu = async (value: string) => {
                Session.set('projectId',value)
                userInfos.value.projectId = value
                await initBackEndControlRoutes();
            };
            return {
                renderMenu,
                ...toRefs(state),
            };
        },
    });
</script>
<style scoped lang="scss">
$homeNavLengh: 8;
.home-container {
    overflow: hidden;
    .home-card-one,
    .home-card-two,
    .home-card-three {
        .home-card-item {
            width: 100%;
            height: 130px;
            border-radius: 4px;
            transition: all ease 0.3s;
            padding: 20px;
            overflow: hidden;
            background: var(--el-color-white);
            color: var(--el-text-color-primary);
            border: 1px solid var(--next-border-color-light);
            &:hover {
                box-shadow: 0 2px 12px var(--next-color-dark-hover);
    $homeNavLengh: 8;
    .home-container {
        overflow: hidden;
        .home-card-one,
        .home-card-two,
        .home-card-three {
            .home-card-item {
                width: 100%;
                height: 130px;
                border-radius: 4px;
                transition: all ease 0.3s;
            }
            &-icon {
                width: 70px;
                height: 70px;
                border-radius: 100%;
                flex-shrink: 1;
                i {
                    color: var(--el-text-color-placeholder);
                padding: 20px;
                overflow: hidden;
                background: var(--el-color-white);
                color: var(--el-text-color-primary);
                border: 1px solid var(--next-border-color-light);
                &:hover {
                    box-shadow: 0 2px 12px var(--next-color-dark-hover);
                    transition: all ease 0.3s;
                }
                &-icon {
                    width: 70px;
                    height: 70px;
                    border-radius: 100%;
                    flex-shrink: 1;
                    i {
                        color: var(--el-text-color-placeholder);
                    }
                }
                &-title {
                    font-size: 15px;
                    font-weight: bold;
                    height: 30px;
                }
            }
            &-title {
                font-size: 15px;
                font-weight: bold;
                height: 30px;
        }
        .home-card-one {
            @for $i from 0 through 3 {
                .home-one-animation#{$i} {
                    opacity: 0;
                    animation-name: error-num;
                    animation-duration: 0.5s;
                    animation-fill-mode: forwards;
                    animation-delay: calc($i/10) + s;
                }
            }
        }
    }
    .home-card-one {
        @for $i from 0 through 3 {
            .home-one-animation#{$i} {
                opacity: 0;
                animation-name: error-num;
                animation-duration: 0.5s;
                animation-fill-mode: forwards;
                animation-delay: calc($i/10) + s;
            }
        }
    }
    .home-card-two,
    .home-card-three {
        .home-card-item {
            height: 400px;
            width: 100%;
            overflow: hidden;
            .home-monitor {
                height: 100%;
                .flex-warp-item {
                    width: 25%;
                    height: 111px;
                    display: flex;
                    .flex-warp-item-box {
                        margin: auto;
                        text-align: center;
                        color: var(--el-text-color-primary);
        .home-card-two,
        .home-card-three {
            .home-card-item {
                height: 400px;
                width: 100%;
                overflow: hidden;
                .home-monitor {
                    height: 100%;
                    .flex-warp-item {
                        width: 25%;
                        height: 111px;
                        display: flex;
                        border-radius: 5px;
                        background: var(--next-bg-color);
                        cursor: pointer;
                        transition: all 0.3s ease;
                        &:hover {
                            background: var(--el-color-primary-light-9);
                        .flex-warp-item-box {
                            margin: auto;
                            text-align: center;
                            color: var(--el-text-color-primary);
                            display: flex;
                            border-radius: 5px;
                            background: var(--next-bg-color);
                            cursor: pointer;
                            transition: all 0.3s ease;
                            &:hover {
                                background: var(--el-color-primary-light-9);
                                transition: all 0.3s ease;
                            }
                        }
                    }
                    @for $i from 0 through $homeNavLengh {
                        .home-animation#{$i} {
                            opacity: 0;
                            animation-name: error-num;
                            animation-duration: 0.5s;
                            animation-fill-mode: forwards;
                            animation-delay: calc($i/10) + s;
                        @for $i from 0 through $homeNavLengh {
                            .home-animation#{$i} {
                                opacity: 0;
                                animation-name: error-num;
                                animation-duration: 0.5s;
                                animation-fill-mode: forwards;
                                animation-delay: calc($i/10) + s;
                            }
                        }
                    }
                }
            }
        }
    }
}
</style>
src/views/login/component/account.vue
@@ -9,19 +9,19 @@
        </el-form-item>
        <el-form-item class="login-animation2">
            <el-input
                :type="isShowPassword ? 'text' : 'password'"
                :placeholder="$t('message.account.accountPlaceholder2')"
                v-model="ruleForm.password"
                autocomplete="off"
                    :type="isShowPassword ? 'text' : 'password'"
                    :placeholder="$t('message.account.accountPlaceholder2')"
                    v-model="ruleForm.password"
                    autocomplete="off"
            >
                <template #prefix>
                    <el-icon class="el-input__icon"><ele-Unlock /></el-icon>
                </template>
                <template #suffix>
                    <i
                        class="iconfont el-input__icon login-content-password"
                        :class="isShowPassword ? 'icon-yincangmima' : 'icon-xianshimima'"
                        @click="isShowPassword = !isShowPassword"
                            class="iconfont el-input__icon login-content-password"
                            :class="isShowPassword ? 'icon-yincangmima' : 'icon-xianshimima'"
                            @click="isShowPassword = !isShowPassword"
                    >
                    </i>
                </template>
@@ -30,12 +30,12 @@
        <el-form-item class="login-animation3">
            <el-col :span="15">
                <el-input
                    type="text"
                    maxlength="4"
                    :placeholder="$t('message.account.accountPlaceholder3')"
                    v-model="ruleForm.code"
                    clearable
                    autocomplete="off"
                        type="text"
                        maxlength="4"
                        :placeholder="$t('message.account.accountPlaceholder3')"
                        v-model="ruleForm.code"
                        clearable
                        autocomplete="off"
                >
                    <template #prefix>
                        <el-icon class="el-input__icon"><ele-Position /></el-icon>
@@ -56,141 +56,138 @@
</template>
<script lang="ts">
import { toRefs, reactive, defineComponent, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n';
import Cookies from 'js-cookie';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
import { initBackEndControlRoutes } from '/@/router/backEnd';
import { Session } from '/@/utils/storage';
import { formatAxis } from '/@/utils/formatTime';
import { NextLoading } from '/@/utils/loading';
import { useLoginApi } from '/@/api/login';
import {useUserInfo} from "/@/stores/userInfo";
    import { toRefs, reactive, defineComponent, computed } from 'vue';
    import { useRoute, useRouter } from 'vue-router';
    import { ElMessage } from 'element-plus';
    import { useI18n } from 'vue-i18n';
    import Cookies from 'js-cookie';
    import { storeToRefs } from 'pinia';
    import { useThemeConfig } from '/@/stores/themeConfig';
    import { initFrontEndControlRoutes } from '/@/router/frontEnd';
    import { initBackEndControlRoutes } from '/@/router/backEnd';
    import { Session } from '/@/utils/storage';
    import { formatAxis } from '/@/utils/formatTime';
    import { NextLoading } from '/@/utils/loading';
    import { useLoginApi } from '/@/api/login';
    import {useUserInfo} from "/@/stores/userInfo";
export default defineComponent({
    name: 'loginAccount',
    setup() {
        const { t } = useI18n();
        const userInfo = useUserInfo()
        const { userInfos } = storeToRefs(userInfo);
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const route = useRoute();
        const router = useRouter();
        const state = reactive({
            isShowPassword: false,
            ruleForm: {
                username: 'admin',
                password: '123456',
            },
            loading: {
                signIn: false,
            },
        });
        // 时间获取
        const currentTime = computed(() => {
            return formatAxis(new Date());
        });
        // 登录
        const onSignIn = async () => {
            state.loading.signIn = true;
            // 存储 token 到浏览器缓存
            let res = await useLoginApi().signIn(state.ruleForm)
            if(res.data.code === '200'){
                Session.set('ifMenu',false)
                Session.set('projectId','')
                Session.set('token', res.data.data.accessToken);
                Session.set('sign',res.data.data.id)
                await initFrontEndControlRoutes();
                signInSuccess();
            }else{
                state.loading.signIn = false
                ElMessage({
                    type:'warning',
                    message:res.data.msg
                })
            }
            // Session.set('token', Math.random().toString(36).substr(0));
            // // 模拟数据,对接接口时,记得删除多余代码及对应依赖的引入。用于 `/src/stores/userInfo.ts` 中不同用户登录判断(模拟数据)
            // Cookies.set('userName', state.ruleForm.username);
            // if (!themeConfig.value.isRequestRoutes) {
            //     // 前端控制路由,2、请注意执行顺序
            //     await initFrontEndControlRoutes();
            //     signInSuccess();
            // } else {
            //     // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
            //     // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
            //     await initBackEndControlRoutes();
            //     // 执行完 initBackEndControlRoutes,再执行 signInSuccess
            //     signInSuccess();
            // }
        };
        // 登录成功后的跳转
        const signInSuccess = async () => {
            // 初始化登录成功时间问候语
            let currentTimeInfo = currentTime.value;
            // 登录成功,跳到转首页
            // 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
            if (route.query?.redirect) {
                router.push('/');
                // router.push({
                //     path: <string>route.query?.redirect,
                //     query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
                // });
            } else {
                router.push('/login');
            }
            state.loading.signIn = true;
            const signInText = t('message.signInText');
            ElMessage.success(`${currentTimeInfo},${signInText}`);
            // 登录成功提示
            // 关闭 loading
            // 添加 loading,防止第一次进入界面时出现短暂空白
            // NextLoading.start();
        };
        return {
            onSignIn,
            ...toRefs(state),
        };
    },
});
    export default defineComponent({
        name: 'loginAccount',
        setup() {
            const { t } = useI18n();
            const userInfo = useUserInfo()
            const route = useRoute();
            const router = useRouter();
            const state = reactive({
                isShowPassword: false,
                ruleForm: {
                    username: 'admin',
                    password: '123456',
                },
                loading: {
                    signIn: false,
                },
            });
            // 时间获取
            const currentTime = computed(() => {
                return formatAxis(new Date());
            });
            // 登录
            const onSignIn = async () => {
                state.loading.signIn = true;
                // 存储 token 到浏览器缓存
                let res = await useLoginApi().signIn(state.ruleForm)
                if(res.data.code === '200'){
                    userInfo.setUserInfos(res.data.data)
                    Session.set('token', res.data.data.accessToken);
                    Session.set('projectId','');
                    Session.set('uid',res.data.data.id);
                    await initBackEndControlRoutes();
                    signInSuccess();
                }else{
                    state.loading.signIn = false
                    ElMessage({
                        type:'warning',
                        message:res.data.msg
                    })
                }
                // Session.set('token', Math.random().toString(36).substr(0));
                // // 模拟数据,对接接口时,记得删除多余代码及对应依赖的引入。用于 `/src/stores/userInfo.ts` 中不同用户登录判断(模拟数据)
                // Cookies.set('userName', state.ruleForm.username);
                // if (!themeConfig.value.isRequestRoutes) {
                //     // 前端控制路由,2、请注意执行顺序
                //     await initFrontEndControlRoutes();
                //     signInSuccess();
                // } else {
                //     // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
                //     // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
                //     await initBackEndControlRoutes();
                //     // 执行完 initBackEndControlRoutes,再执行 signInSuccess
                //     signInSuccess();
                // }
            };
            // 登录成功后的跳转
            const signInSuccess = async () => {
                // 初始化登录成功时间问候语
                let currentTimeInfo = currentTime.value;
                // 登录成功,跳到转首页
                // 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
                if (route.query?.redirect) {
                    router.push('/');
                    // router.push({
                    //     path: <string>route.query?.redirect,
                    //     query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
                    // });
                } else {
                    router.push('/login');
                }
                state.loading.signIn = true;
                const signInText = t('message.signInText');
                ElMessage.success(`${currentTimeInfo},${signInText}`);
                // 登录成功提示
                // 关闭 loading
                // 添加 loading,防止第一次进入界面时出现短暂空白
                // NextLoading.start();
            };
            return {
                onSignIn,
                ...toRefs(state),
            };
        },
    });
</script>
<style scoped lang="scss">
.login-content-form {
    margin-top: 20px;
    @for $i from 1 through 4 {
        .login-animation#{$i} {
            opacity: 0;
            animation-name: error-num;
            animation-duration: 0.5s;
            animation-fill-mode: forwards;
            animation-delay: calc($i/10) + s;
    .login-content-form {
        margin-top: 20px;
        @for $i from 1 through 4 {
            .login-animation#{$i} {
                opacity: 0;
                animation-name: error-num;
                animation-duration: 0.5s;
                animation-fill-mode: forwards;
                animation-delay: calc($i/10) + s;
            }
        }
        .login-content-password {
            display: inline-block;
            width: 20px;
            cursor: pointer;
            &:hover {
                color: #909399;
            }
        }
        .login-content-code {
            width: 100%;
            padding: 0;
            font-weight: bold;
            letter-spacing: 5px;
        }
        .login-content-submit {
            width: 100%;
            letter-spacing: 2px;
            font-weight: 300;
            margin-top: 15px;
        }
    }
    .login-content-password {
        display: inline-block;
        width: 20px;
        cursor: pointer;
        &:hover {
            color: #909399;
        }
    }
    .login-content-code {
        width: 100%;
        padding: 0;
        font-weight: bold;
        letter-spacing: 5px;
    }
    .login-content-submit {
        width: 100%;
        letter-spacing: 2px;
        font-weight: 300;
        margin-top: 15px;
    }
}
</style>
src/views/login/index.vue
@@ -23,168 +23,168 @@
</template>
<script lang="ts">
import { toRefs, reactive, computed, defineComponent, onMounted } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import logoMini from '/@/assets/logo-mini.svg';
import loginIconTwo from '/@/assets/login-icon-two.svg';
import { NextLoading } from '/@/utils/loading';
import Account from '/@/views/login/component/account.vue';
    import { toRefs, reactive, computed, defineComponent, onMounted } from 'vue';
    import { storeToRefs } from 'pinia';
    import { useThemeConfig } from '/@/stores/themeConfig';
    import logoMini from '/@/assets/logo-mini.svg';
    import loginIconTwo from '/@/assets/login-icon-two.svg';
    import { NextLoading } from '/@/utils/loading';
    import Account from '/@/views/login/component/account.vue';
// 定义接口来定义对象的类型
interface LoginState {
    tabsActiveName: string;
    isScan: boolean;
}
    // 定义接口来定义对象的类型
    interface LoginState {
        tabsActiveName: string;
        isScan: boolean;
    }
export default defineComponent({
    name: 'loginIndex',
    components: { Account, },
    setup() {
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const state = reactive<LoginState>({
            tabsActiveName: 'account',
            isScan: false,
        });
        // 获取布局配置信息
        const getThemeConfig = computed(() => {
            return themeConfig.value;
        });
        // 页面加载时
        onMounted(() => {
            NextLoading.done();
        });
        return {
            logoMini,
            loginIconTwo,
            getThemeConfig,
            ...toRefs(state),
        };
    },
});
    export default defineComponent({
        name: 'loginIndex',
        components: { Account, },
        setup() {
            const storesThemeConfig = useThemeConfig();
            const { themeConfig } = storeToRefs(storesThemeConfig);
            const state = reactive<LoginState>({
                tabsActiveName: 'account',
                isScan: false,
            });
            // 获取布局配置信息
            const getThemeConfig = computed(() => {
                return themeConfig.value;
            });
            // 页面加载时
            onMounted(() => {
                NextLoading.done();
            });
            return {
                logoMini,
                loginIconTwo,
                getThemeConfig,
                ...toRefs(state),
            };
        },
    });
</script>
<style scoped lang="scss">
.login-container {
    width: 100%;
    height: 100%;
    position: relative;
    background: var(--el-color-white);
    .login-icon-group {
    .login-container {
        width: 100%;
        height: 100%;
        position: relative;
        .login-icon-group-title {
            position: absolute;
            top: 50px;
            left: 80px;
            display: flex;
            align-items: center;
            img {
                width: 30px;
                height: 30px;
        background: var(--el-color-white);
        .login-icon-group {
            width: 100%;
            height: 100%;
            position: relative;
            .login-icon-group-title {
                position: absolute;
                top: 50px;
                left: 80px;
                display: flex;
                align-items: center;
                img {
                    width: 30px;
                    height: 30px;
                }
                &-text {
                    padding-left: 15px;
                    color: var(--el-color-primary);
                }
            }
            &-text {
                padding-left: 15px;
                color: var(--el-color-primary);
            }
        }
        &::before {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 60%;
            overflow: hidden;
            height: 80%;
            -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='1200' height='770' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M58.4 47.77C104.6 59.51 135.26 67.37 162.11 78.04C188.97 88.72 226.33 102.69 265.92 123.55C305.51 144.4 366.96 167.09 441.43 121.52C515.9 75.95 546.48 61.01 577.69 46.27C608.9 31.53 625.86 23.69 680.26 12.28C734.65 0.87 837.29 10.7 867.29 21.8C897.29 32.9 935.51 51.9 962.21 95.45C988.9 139.01 972.91 177.36 951.37 221.39C929.83 265.43 883.49 306 890.44 337.33C897.4 368.66 974.73 412.18 974.73 411.47C974.73 412.18 1066.36 457.62 1106.36 491.06C1146.36 524.5 1178.8 563.36 1184.03 579.63C1189.26 595.9 1200.4 622.49 1181.55 676.88C1162.71 731.26 1127.16 764.32 1115.31 778.64C1103.45 792.96 5.34 783.61 4.32 784.63C3.3 785.65 -172.34 2.38 1.13 35.04L58.4 47.77L58.4 47.77Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
            background: var(--el-color-primary-light-5);
            transition: all 0.3s ease;
        }
        &::after {
            content: '';
            width: 150px;
            height: 300px;
            position: absolute;
            right: 0;
            top: 0;
            -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='150' height='300' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M-0.56 -0.28C41.94 36.17 67.73 18.94 93.33 33.96C118.93 48.98 107.58 73.56 101.94 89.76C96.29 105.96 50.09 217.83 47.87 231.18C45.64 244.52 46.02 255.2 64.4 270.05C82.79 284.91 121.99 292.31 111.98 289.81C101.97 287.32 153.96 301.48 151.83 299.9C149.69 298.32 149.98 -1.36 149.71 -1.18C149.98 -1.36 -43.06 -36.74 -0.56 -0.28L-0.56 -0.28Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
            background: var(--el-color-primary-light-5);
            transition: all 0.3s ease;
        }
        &-icon {
            width: 60%;
            height: 70%;
            position: absolute;
            left: 0;
            bottom: 0;
        }
    }
    .login-content {
        width: 500px;
        padding: 20px;
        position: absolute;
        right: 200px;
        top: 50%;
        transform: translateY(-50%) translate3d(0, 0, 0);
        background-color: var(--el-color-white);
        border: 5px solid var(--el-color-primary-light-8);
        border-radius: 5px;
        overflow: hidden;
        z-index: 1;
        height: 460px;
        .login-content-main {
            margin: 0 auto;
            width: 80%;
            .login-content-title {
                color: var(--el-text-color-primary);
                font-weight: 500;
                font-size: 22px;
                text-align: center;
                letter-spacing: 4px;
                margin: 15px 0 30px;
                white-space: nowrap;
                z-index: 5;
                position: relative;
            &::before {
                content: '';
                position: absolute;
                bottom: 0;
                left: 0;
                width: 60%;
                overflow: hidden;
                height: 80%;
                -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='1200' height='770' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M58.4 47.77C104.6 59.51 135.26 67.37 162.11 78.04C188.97 88.72 226.33 102.69 265.92 123.55C305.51 144.4 366.96 167.09 441.43 121.52C515.9 75.95 546.48 61.01 577.69 46.27C608.9 31.53 625.86 23.69 680.26 12.28C734.65 0.87 837.29 10.7 867.29 21.8C897.29 32.9 935.51 51.9 962.21 95.45C988.9 139.01 972.91 177.36 951.37 221.39C929.83 265.43 883.49 306 890.44 337.33C897.4 368.66 974.73 412.18 974.73 411.47C974.73 412.18 1066.36 457.62 1106.36 491.06C1146.36 524.5 1178.8 563.36 1184.03 579.63C1189.26 595.9 1200.4 622.49 1181.55 676.88C1162.71 731.26 1127.16 764.32 1115.31 778.64C1103.45 792.96 5.34 783.61 4.32 784.63C3.3 785.65 -172.34 2.38 1.13 35.04L58.4 47.77L58.4 47.77Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
                background: var(--el-color-primary-light-5);
                transition: all 0.3s ease;
            }
            &::after {
                content: '';
                width: 150px;
                height: 300px;
                position: absolute;
                right: 0;
                top: 0;
                -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='150' height='300' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M-0.56 -0.28C41.94 36.17 67.73 18.94 93.33 33.96C118.93 48.98 107.58 73.56 101.94 89.76C96.29 105.96 50.09 217.83 47.87 231.18C45.64 244.52 46.02 255.2 64.4 270.05C82.79 284.91 121.99 292.31 111.98 289.81C101.97 287.32 153.96 301.48 151.83 299.9C149.69 298.32 149.98 -1.36 149.71 -1.18C149.98 -1.36 -43.06 -36.74 -0.56 -0.28L-0.56 -0.28Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
                background: var(--el-color-primary-light-5);
                transition: all 0.3s ease;
            }
            &-icon {
                width: 60%;
                height: 70%;
                position: absolute;
                left: 0;
                bottom: 0;
            }
        }
        .login-content-main-sacn {
        .login-content {
            width: 500px;
            padding: 20px;
            position: absolute;
            top: 0;
            right: 0;
            width: 50px;
            height: 50px;
            right: 200px;
            top: 50%;
            transform: translateY(-50%) translate3d(0, 0, 0);
            background-color: var(--el-color-white);
            border: 5px solid var(--el-color-primary-light-8);
            border-radius: 5px;
            overflow: hidden;
            cursor: pointer;
            transition: all ease 0.3s;
            color: var(--el-text-color-primary);
            &-delta {
            z-index: 1;
            height: 460px;
            .login-content-main {
                margin: 0 auto;
                width: 80%;
                .login-content-title {
                    color: var(--el-text-color-primary);
                    font-weight: 500;
                    font-size: 22px;
                    text-align: center;
                    letter-spacing: 4px;
                    margin: 15px 0 30px;
                    white-space: nowrap;
                    z-index: 5;
                    position: relative;
                    transition: all 0.3s ease;
                }
            }
            .login-content-main-sacn {
                position: absolute;
                width: 35px;
                height: 70px;
                z-index: 2;
                top: 2px;
                right: 21px;
                background: var(--el-color-white);
                transform: rotate(-45deg);
            }
            &:hover {
                opacity: 1;
                transition: all ease 0.3s;
                color: var(--el-color-primary) !important;
            }
            i {
                width: 47px;
                top: 0;
                right: 0;
                width: 50px;
                height: 50px;
                display: inline-block;
                font-size: 48px;
                position: absolute;
                right: 2px;
                top: -1px;
                overflow: hidden;
                cursor: pointer;
                transition: all ease 0.3s;
                color: var(--el-text-color-primary);
                &-delta {
                    position: absolute;
                    width: 35px;
                    height: 70px;
                    z-index: 2;
                    top: 2px;
                    right: 21px;
                    background: var(--el-color-white);
                    transform: rotate(-45deg);
                }
                &:hover {
                    opacity: 1;
                    transition: all ease 0.3s;
                    color: var(--el-color-primary) !important;
                }
                i {
                    width: 47px;
                    height: 50px;
                    display: inline-block;
                    font-size: 48px;
                    position: absolute;
                    right: 2px;
                    top: -1px;
                }
            }
        }
    }
}
</style>
src/views/system/menu/component/menuDialog.vue
@@ -6,12 +6,12 @@
                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                        <el-form-item label="上级菜单">
                            <el-cascader
                                :options="menuData"
                                :props="{ checkStrictly: true, value: 'id', label: 'title' }"
                                placeholder="请选择上级菜单"
                                clearable
                                class="w100"
                                v-model="ruleForm.menuSuperior"
                                    :options="menuData"
                                    :props="{ checkStrictly: true, value: 'id', label: 'title' }"
                                    placeholder="请选择上级菜单"
                                    clearable
                                    class="w100"
                                    v-model="ruleForm.menuSuperior"
                            >
                            </el-cascader>
                        </el-form-item>
@@ -58,10 +58,10 @@
                        <el-form-item label="项目名">
                            <el-select v-model="ruleForm.projectId" controls-position="right" placeholder="请输入排序" class="w100">
                                <el-option
                                v-for="item in projectList"
                                :key="item.key"
                                :value="item.id"
                                :label="item.name"
                                        v-for="item in projectList"
                                        :key="item.key"
                                        :value="item.id"
                                        :label="item.name"
                                >
                                </el-option>
                            </el-select>
@@ -93,179 +93,174 @@
</template>
<script lang="ts">
import { reactive, toRefs, onMounted, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useRoutesList } from '/@/stores/routesList';
import { i18n } from '/@/i18n/index';
import IconSelector from '/@/components/iconSelector/index.vue';
import { useMenuApi } from '/@/api/menu/index'
import { ElMessageBox, ElMessage } from 'element-plus';
import {Session} from "/@/utils/storage";
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
    import { reactive, toRefs, onMounted, defineComponent } from 'vue';
    import { storeToRefs } from 'pinia';
    import { useRoutesList } from '/@/stores/routesList';
    import { i18n } from '/@/i18n/index';
    import IconSelector from '/@/components/iconSelector/index.vue';
    import { useMenuApi } from '/@/api/menu/index'
    import { ElMessageBox, ElMessage } from 'element-plus';
    import {Session} from "/@/utils/storage";
    // import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
export default defineComponent({
    name: 'systemAddMenu',
    components: { IconSelector },
    setup(props,context) {
        const stores = useRoutesList();
        const { routesList } = storeToRefs(stores);
        const state = reactive({
            isShowDialog: false,
            title:'',
            buttonName:'',
            // 参数请参考 `/src/router/route.ts` 中的 `dynamicRoutes` 路由菜单格式
            ruleForm: {
                projectId:'',
                parentId:0,
                menuSuperior: [], // 上级菜单
                menuType: 'menu', // 菜单类型
                name: '', // 路由名称
                component: '', // 组件路径
                priority: 0, // 菜单排序
                path: '', // 路由路径
                redirect: '', // 路由重定向,有子集 children 时
                meta: {
                    title: '', // 菜单名称
                    icon: '', // 菜单图标
                    isHide: false, // 是否隐藏
                    isKeepAlive: true, // 是否缓存
                    isAffix: false, // 是否固定
                    isLink: '', // 外链/内嵌时链接地址(http:xxx.com),开启外链条件,`1、isLink: 链接地址不为空`
                    isIframe: false, // 是否内嵌,开启条件,`1、isIframe:true 2、isLink:链接地址不为空`
                    roles: '', // 权限标识,取角色管理
                },
                btnPower: '', // 菜单类型为按钮时,权限标识
            },
            menuData: [], // 上级菜单数据
            projectList:[
                {id:'1',name:'基础数据权限管理系统',key:0},
                {id:'2',name:'系统1',key:1},
                {id:'3',name:'系统2',key:2},
                {id:'4',name:'系统3',key:3},
                {id:'5',name:'系统4',key:4},
                {id:'6',name:'应急管理系统',key:5},
                {id:'7',name:'目标责任管理系统',key:6},
                {id:'8',name:'事故管理系统',key:7},
                {id:'9',name:'设备综合管控系统',key:8},
            ],
        });
        // 获取 vuex 中的路由
        const getMenuList = (routes: any) => {
            const arr: any = [];
            routes.map((val: any) => {
                val['title'] = val.meta.title;
                val['id'] = val.id
                arr.push(val);
                if (val.children) getMenuList(val.children);
            });
            return arr;
        };
        // 打开弹窗
        const openDialog = (type:string,value:any) => {
            state.isShowDialog = true;
            if(type === '新增'){
                state.buttonName = '新增'
                state.title = '新增菜单'
                state.ruleForm = {
    export default defineComponent({
        name: 'systemAddMenu',
        components: { IconSelector },
        setup(props,context) {
            const stores = useRoutesList();
            const { routesList } = storeToRefs(stores);
            const state = reactive({
                isShowDialog: false,
                title:'',
                buttonName:'',
                // 参数请参考 `/src/router/route.ts` 中的 `dynamicRoutes` 路由菜单格式
                ruleForm: {
                    projectId:'',
                    parentId:0,
                    menuSuperior: [],
                    menuType: 'menu',
                    name: '',
                    component: '',
                    priority: 0,
                    path: '',
                    redirect: '',
                    menuSuperior: [], // 上级菜单
                    menuType: 'menu', // 菜单类型
                    name: '', // 路由名称
                    component: '', // 组件路径
                    priority: 0, // 菜单排序
                    path: '', // 路由路径
                    redirect: '', // 路由重定向,有子集 children 时
                    meta: {
                        title: '',
                        icon: '',
                        isHide: false,
                        isKeepAlive: true,
                        isAffix: false,
                        isLink: '',
                        isIframe: false,
                        roles: '',
                        title: '', // 菜单名称
                        icon: '', // 菜单图标
                        isHide: false, // 是否隐藏
                        isKeepAlive: true, // 是否缓存
                        isAffix: false, // 是否固定
                        isLink: '', // 外链/内嵌时链接地址(http:xxx.com),开启外链条件,`1、isLink: 链接地址不为空`
                        isIframe: false, // 是否内嵌,开启条件,`1、isIframe:true 2、isLink:链接地址不为空`
                        roles: '', // 权限标识,取角色管理
                    },
                    btnPower: '',
                }
            }else{
                state.buttonName = '修改'
                state.title = '修改菜单'
                state.ruleForm = JSON.parse(JSON.stringify(value))
            }
        };
        // 关闭弹窗
        const closeDialog = () => {
            state.isShowDialog = false;
        };
        // 是否内嵌下拉改变
        // const onSelectIframeChange = () => {
        //     if (state.ruleForm.meta.isIframe) state.ruleForm.isLink = true;
        //     else state.ruleForm.isLink = false;
        // };
        // 取消
        const onCancel = () => {
            closeDialog();
        };
        // 新增
        const onSubmit = async () => {
            if(state.ruleForm.menuSuperior && state.ruleForm.menuSuperior !== []){
                let menuId = JSON.parse(JSON.stringify(state.ruleForm.menuSuperior))
                state.ruleForm.parentId = menuId[menuId.length - 1]
            }
            if(state.title === '新增菜单'){
                let res = await useMenuApi().addMenu(state.ruleForm)
                if(res.data.code === '200'){
                    ElMessage({
                        type:'success',
                        message:'菜单新增成功',
                        duration:2000
                    })
                    closeDialog();
                    context.emit('getMenuList')
                    btnPower: '', // 菜单类型为按钮时,权限标识
                },
                menuData: [], // 上级菜单数据
                projectList:[
                ],
            });
            // 获取 vuex 中的路由
            const getMenuList = (routes: any) => {
                const arr: any = [];
                routes.map((val: any) => {
                    val['title'] = val.meta.title;
                    val['id'] = val.id
                    arr.push(val);
                    if (val.children) getMenuList(val.children);
                });
                return arr;
            };
            // 打开弹窗
            const openDialog = (type:string,value:any,projectList: any,projectId:string) => {
                state.projectList = JSON.parse(JSON.stringify(projectList))
                state.isShowDialog = true;
                if(type === '新增'){
                    state.buttonName = '新增'
                    state.title = '新增菜单'
                    state.ruleForm = {
                        projectId:projectId,
                        parentId:0,
                        menuSuperior: [],
                        menuType: 'menu',
                        name: '',
                        component: '',
                        priority: 0,
                        path: '',
                        redirect: '',
                        meta: {
                            title: '',
                            icon: '',
                            isHide: false,
                            isKeepAlive: true,
                            isAffix: false,
                            isLink: '',
                            isIframe: false,
                            roles: '',
                        },
                        btnPower: '',
                    }
                }else{
                    ElMessage({
                        type:'warning',
                        message:res.data.msg
                    })
                    state.buttonName = '修改'
                    state.title = '修改菜单'
                    state.ruleForm = JSON.parse(JSON.stringify(value))
                }
            }else{
                let res = await useMenuApi().modMenu(state.ruleForm)
                if(res.data.code === '200'){
                    ElMessage({
                        type:'success',
                        message:'菜单修改成功',
                        duration:2000
                    })
                    closeDialog();
                    context.emit('getMenuList')
                handelMenu()
            };
            // 关闭弹窗
            const closeDialog = () => {
                state.isShowDialog = false;
            };
            // 是否内嵌下拉改变
            // const onSelectIframeChange = () => {
            //     if (state.ruleForm.meta.isIframe) state.ruleForm.isLink = true;
            //     else state.ruleForm.isLink = false;
            // };
            // 取消
            const onCancel = () => {
                closeDialog();
            };
            // 新增
            const onSubmit = async () => {
                if(state.ruleForm.menuSuperior && state.ruleForm.menuSuperior !== []){
                    let menuId = JSON.parse(JSON.stringify(state.ruleForm.menuSuperior))
                    state.ruleForm.parentId = menuId[menuId.length - 1]
                }
                if(state.title === '新增菜单'){
                    let res = await useMenuApi().addMenu(state.ruleForm)
                    if(res.data.code === '200'){
                        ElMessage({
                            type:'success',
                            message:'菜单新增成功',
                            duration:2000
                        })
                        closeDialog();
                        context.emit('getMenuList')
                    }else{
                        ElMessage({
                            type:'warning',
                            message:res.data.msg
                        })
                    }
                }else{
                    ElMessage({
                        type:'warning',
                        message:res.data.msg
                    })
                    let res = await useMenuApi().modMenu(state.ruleForm)
                    if(res.data.code === '200'){
                        ElMessage({
                            type:'success',
                            message:'菜单修改成功',
                            duration:2000
                        })
                        closeDialog();
                        context.emit('getMenuList')
                    }else{
                        ElMessage({
                            type:'warning',
                            message:res.data.msg
                        })
                    }
                }
                // closeDialog(); // 关闭弹窗
                // setBackEndControlRefreshRoutes() // 刷新菜单,未进行后端接口测试
            };
            const handelMenu = async () => {
                let res = await useMenuApi().getMenuAdmin(state.ruleForm.projectId)
                state.menuData = JSON.parse(JSON.stringify(getMenuList(res.data.data)))
            }
            // closeDialog(); // 关闭弹窗
            // setBackEndControlRefreshRoutes() // 刷新菜单,未进行后端接口测试
        };
        const show = () => {
            console.log(JSON.parse(JSON.stringify(state.ruleForm.menuSuperior)));
        }
        // 页面加载时
        onMounted(async () => {
            let res = await useMenuApi().getMenuAdmin(Session.get('projectId'))
            state.menuData = JSON.parse(JSON.stringify(getMenuList(res.data.data)))
        });
        return {
            openDialog,
            closeDialog,
            onCancel,
            onSubmit,
            ...toRefs(state),
        };
    },
});
            // 页面加载时
            onMounted(async () => {
                // let res = await useMenuApi().getMenuAdmin(Session.get('projectId'))
                // state.menuData = JSON.parse(JSON.stringify(getMenuList(res.data.data)))
            });
            return {
                openDialog,
                closeDialog,
                onCancel,
                onSubmit,
                handelMenu,
                ...toRefs(state),
            };
        },
    });
</script>
src/views/system/menu/index.vue
@@ -2,7 +2,7 @@
    <div class="system-menu-container">
        <el-card shadow="hover">
            <div class="system-menu-search mb15">
                <el-select size="default" v-model="projectId" placeholder="请输入项目名称" style="max-width: 180px">
                <el-select size="default" v-model="projectId" placeholder="请选择项目名称" style="max-width: 180px" @change="getMenuList()">
                    <el-option
                            v-for="item in projectList"
                            :key="item.key"
@@ -11,7 +11,7 @@
                    >
                    </el-option>
                </el-select>
                <el-button size="default" type="primary" class="ml10">
                <el-button size="default" type="primary" class="ml10" @click="getMenuList">
                    <el-icon>
                        <ele-Search />
                    </el-icon>
@@ -66,82 +66,81 @@
</template>
<script lang="ts">
import { ref, toRefs, reactive, computed, onMounted, defineComponent } from 'vue';
import { RouteRecordRaw } from 'vue-router';
import { ElMessageBox, ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import { useRoutesList } from '/@/stores/routesList';
import menuDialog from '/@/views/system/menu/component/menuDialog.vue';
import {useMenuApi} from "/@/api/menu";
import {Session} from "/@/utils/storage";
import pinia from "/@/stores";
import {dynamicRoutes} from "/@/router/route";
    import { ref, toRefs, reactive, computed, onMounted, defineComponent } from 'vue';
    import { RouteRecordRaw } from 'vue-router';
    import { ElMessageBox, ElMessage } from 'element-plus';
    import { storeToRefs } from 'pinia';
    import { useRoutesList } from '/@/stores/routesList';
    import menuDialog from '/@/views/system/menu/component/menuDialog.vue';
    import {useMenuApi} from "/@/api/menu";
    import {Session} from "/@/utils/storage";
    import pinia from "/@/stores";
    import {dynamicRoutes} from "/@/router/route";
    import {useUserInfo} from "/@/stores/userInfo";
export default defineComponent({
    name: 'systemMenu',
    components: { menuDialog },
    setup() {
        const stores = useRoutesList();
        const { routesList } = storeToRefs(stores);
        const menuDialog = ref();
        const state = reactive({
            projectId:'',
            menuData:[],
            projectList:[
                {id:'1',name:'基础数据权限管理系统',key:0},
                {id:'2',name:'系统1',key:1},
                {id:'3',name:'系统2',key:2},
                {id:'4',name:'系统3',key:3},
                {id:'5',name:'系统4',key:4},
                {id:'6',name:'应急管理系统',key:5},
                {id:'7',name:'目标责任管理系统',key:6},
                {id:'8',name:'事故管理系统',key:7},
                {id:'9',name:'设备综合管控系统',key:8},
            ],
        });
        // 获取 vuex 中的路由
        const menuTableData = computed(() => {
            return routesList.value;
        });
        // 打开新增菜单弹窗
        const onOpenMenuDialog = (type: string,value: any) => {
            menuDialog.value.openDialog(type,value);
        };
        // 打开编辑菜单弹窗
        // 删除当前行
        const onTabelRowDel = (row: RouteRecordRaw) => {
            ElMessageBox.confirm(`此操作将永久删除路由:${row.path}, 是否继续?`, '提示', {
                confirmButtonText: '删除',
                cancelButtonText: '取消',
                type: 'warning',
            }).then(() => {
                ElMessage.success('删除成功');
            }).catch(() => {});
        };
        const getMenuList = async () => {
            let res = await useMenuApi().getMenuAdmin(Session.get('projectId'))
            if(res.data.code === '200'){
                // state.menuData = res.data.data
                const storesRoutesList = useRoutesList(pinia);
                storesRoutesList.setRoutesList(res.data.data);
            }else{
                ElMessage({
                    type:'warning',
                    message:res.data.msg
                })
            }
        };
        onMounted( () => {
            getMenuList()
        });
        return {
            getMenuList,
            menuDialog,
            onOpenMenuDialog,
            menuTableData,
            onTabelRowDel,
            ...toRefs(state),
        };
    },
});
    export default defineComponent({
        name: 'systemMenu',
        components: { menuDialog },
        setup() {
            const menuDialog = ref();
            const state = reactive({
                projectId:'1',
                menuData:[],
                menuTableData:[],
                projectList:[
                    {id:'1',name:'基础数据权限管理系统',key:0},
                    {id:'2',name:'系统1',key:1},
                    {id:'3',name:'系统2',key:2},
                    {id:'4',name:'系统3',key:3},
                    {id:'5',name:'系统4',key:4},
                    {id:'6',name:'应急管理系统',key:5},
                    {id:'7',name:'目标责任管理系统',key:6},
                    {id:'8',name:'事故管理系统',key:7},
                    {id:'9',name:'设备综合管控系统',key:8},
                ],
            });
            // // 获取 vuex 中的路由
            // const menuTableData = computed(() => {
            //     return routesList.value;
            // });
            // 打开新增菜单弹窗
            const onOpenMenuDialog = (type: string,value: any) => {
                menuDialog.value.openDialog(type,value,state.projectList,state.projectId);
            };
            // 打开编辑菜单弹窗
            // 删除当前行
            const onTabelRowDel = (row: RouteRecordRaw) => {
                ElMessageBox.confirm(`此操作将永久删除路由:${row.path}, 是否继续?`, '提示', {
                    confirmButtonText: '删除',
                    cancelButtonText: '取消',
                    type: 'warning',
                }).then(() => {
                    ElMessage.success('删除成功');
                }).catch(() => {});
            };
            const getMenuList = async () => {
                let res = await useMenuApi().getMenuAdmin(state.projectId)
                if(res.data.code === '200'){
                    state.menuTableData = res.data.data
                    // const storesRoutesList = useRoutesList(pinia);
                    // storesRoutesList.setRoutesList(res.data.data);
                }else{
                    ElMessage({
                        type:'warning',
                        message:res.data.msg
                    })
                }
            };
            onMounted( () => {
                getMenuList()
            });
            return {
                getMenuList,
                menuDialog,
                onOpenMenuDialog,
                onTabelRowDel,
                ...toRefs(state),
            };
        },
    });
</script>