马宇豪
2024-11-15 d8b570430066fae42d6884671cef541fc820de1c
动态路由
已修改22个文件
已删除1个文件
987 ■■■■ 文件已修改
.env.development 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/TopNav/index.vue 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Navbar.vue 129 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/Logo.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/SidebarItem.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/index.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/menu.js 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/permission.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/permission.js 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/components/loginForm.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/baseSet/evaluateType/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/baseSet/expertsType/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/baseSet/openApply/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/evaluateRecord/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/experts/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/postEvaluation/components/expertList.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/postEvaluation/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.development
@@ -8,8 +8,8 @@
#黄镇
#VITE_APP_BASE_API = 'http://192.168.0.47:8085'
#孔哥
#VITE_APP_BASE_API = 'http://192.168.2.15:8088/api'
#贺哥
VITE_APP_BASE_API = 'http://192.168.2.11:8585'
#线上
VITE_APP_BASE_API = 'http://106.15.95.149:8088/api'
#VITE_APP_BASE_API = 'http://106.15.95.149:8088/api'
src/api/login.js
@@ -1,16 +1,15 @@
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid,identity) {
export function login(username, password, code, uuid) {
  const data = {
    username,
    password,
    code,
    uuid,
    identity
  }
  return request({
    url: '/system/account/login',
    url: '/login',
    headers: {
      isToken: false,
      repeatSubmit: false
@@ -51,7 +50,7 @@
// 退出方法
export function logout() {
  return request({
    url: '/system/account/logout',
    url: '/logout',
    method: 'post'
  })
}
@@ -59,7 +58,7 @@
// 获取验证码
export function getCodeImg() {
  return request({
    url: '/system/captcha/captchaImage',
    url: '/captchaImage',
    headers: {
      isToken: false
    },
src/components/TopNav/index.vue
@@ -1,18 +1,17 @@
<template>
  <el-menu
    :default-active="activeMenu"
    mode="horizontal"
    @select="handleSelect"
    :ellipsis="false"
      :default-active="activeMenu"
      mode="horizontal"
      @select="handleSelect"
      :ellipsis="false"
  >
    <template v-for="(item, index) in topMenus">
      <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
        ><svg-icon
          v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
          :icon-class="item.meta.icon"
        />
        {{ item.meta.title }}</el-menu-item
      >
      <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
        <svg-icon
            v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
            :icon-class="item.meta.icon"/>
        {{ item.meta.title }}
      </el-menu-item>
    </template>
    <!-- 顶部菜单超出数量折叠 -->
@@ -20,12 +19,14 @@
      <template #title>更多菜单</template>
      <template v-for="(item, index) in topMenus">
        <el-menu-item
          :index="item.path"
          :key="index"
          v-if="index >= visibleNumber"
          ><svg-icon :icon-class="item.meta.icon" />
          {{ item.meta.title }}</el-menu-item
        >
            :index="item.path"
            :key="index"
            v-if="index >= visibleNumber">
          <svg-icon
              v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
              :icon-class="item.meta.icon"/>
          {{ item.meta.title }}
        </el-menu-item>
      </template>
    </el-sub-menu>
  </el-menu>
@@ -63,9 +64,9 @@
    if (menu.hidden !== true) {
      // 兼容顶部栏一级菜单内部跳转
      if (menu.path === "/") {
          topMenus.push(menu.children[0]);
        topMenus.push(menu.children[0]);
      } else {
          topMenus.push(menu);
        topMenus.push(menu);
      }
    }
  })
@@ -101,7 +102,7 @@
    const tmpPath = path.substring(1, path.length);
    activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
    if (!route.meta.link) {
        appStore.toggleSideBarHide(false);
      appStore.toggleSideBarHide(false);
    }
  } else if(!route.children) {
    activePath = path;
@@ -195,7 +196,7 @@
/* 背景色隐藏 */
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
    background-color: #ffffff !important;
  background-color: #ffffff !important;
}
/* 图标右间距 */
src/layout/components/Navbar.vue
@@ -16,7 +16,7 @@
<!--          <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />-->
<!--        </el-tooltip>-->
        <screenfull id="screenfull" class="right-menu-item hover-effect" />
<!--        <screenfull id="screenfull" class="right-menu-item hover-effect" />-->
<!--        <el-tooltip content="布局大小" effect="dark" placement="bottom">-->
<!--          <size-select id="size-select" class="right-menu-item hover-effect" />-->
@@ -25,8 +25,7 @@
      <div class="avatar-container">
        <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
          <div class="avatar-wrapper">
<!--            <img :src="userStore.avatar" class="user-avatar" />-->
            <img src="../../assets/images/avator.png" class="user-avatar" />
            <img :src="avator" class="user-avatar" />
            <el-icon><caret-bottom /></el-icon>
          </div>
          <template #dropdown>
@@ -34,13 +33,10 @@
<!--              <router-link to="/user/profile">-->
<!--                <el-dropdown-item>个人中心</el-dropdown-item>-->
<!--              </router-link>-->
              <el-dropdown-item command="info">
                <span>基本信息</span>
              </el-dropdown-item>
              <el-dropdown-item command="password">
                <span>修改密码</span>
              </el-dropdown-item>
              <el-dropdown-item divided command="logout">
<!--              <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">-->
<!--                <span>布局设置</span>-->
<!--              </el-dropdown-item>-->
              <el-dropdown-item command="logout">
                <span>退出登录</span>
              </el-dropdown-item>
            </el-dropdown-menu>
@@ -48,14 +44,11 @@
        </el-dropdown>
      </div>
    </div>
    <review-dialog ref="reviewRef" ></review-dialog>
    <register ref="regRef" @getList="getList" />
    <supervise-dialog ref="superRef"></supervise-dialog>
  </div>
</template>
<script setup>
import {ElMessage, ElMessageBox} from 'element-plus'
import { ElMessageBox } from 'element-plus'
import Breadcrumb from '@/components/Breadcrumb'
import TopNav from '@/components/TopNav'
import Hamburger from '@/components/Hamburger'
@@ -67,118 +60,28 @@
import useAppStore from '@/store/modules/app'
import useUserStore from '@/store/modules/user'
import useSettingsStore from '@/store/modules/settings'
import {getToken, removeToken} from "@/utils/auth";
import {onMounted, ref} from "vue";
import Cookies from "js-cookie";
import reviewDialog from "@/views/safetyReview/institution/components/viewInstitution.vue"
import superviseDialog from "@/views/safetyReview/userManage/superviseUsers/components/superviseDialog.vue"
import {Register} from "@/layout/components";
import {getUserById} from "@/api/sysUsers";
import menu from "@/layout/components/Sidebar/menu";
import avator from '@/assets/images/avator.png'
const appStore = useAppStore()
const userStore = useUserStore()
const settingsStore = useSettingsStore()
const reviewRef = ref();
const regRef = ref(null)
const superRef = ref();
const userInfo = ref();
onMounted(()=>{
  if(getToken()){
    userInfo.value = JSON.parse(Cookies.get('userInfo'))
    console.log("userInfo",userInfo.value )
  }
  getState();
})
const getState = async () => {
  console.log('navbar')
  const param = {
    userId: userInfo.value.id
  }
  const res = await getUserById(param)
  if(res.code == 200){
    userInfo.value.state = res.data.state;
    // if(userInfo.value.state===2){
    //   sidebarRouters.value =  menu.agencyMenu
    //   Cookies.set('routers',JSON.stringify(sidebarRouters.value))
    //   location.href = '/project';
    // }
    // else {
    //   location.href = '/noMenu';
    // }
  }else{
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
function toggleSideBar() {
  appStore.toggleSideBar()
}
function handleCommand(command) {
  switch (command) {
    case "info":
      getInfo();
    case "setLayout":
      setLayout();
      break;
    case "logout":
      logout();
      break;
    case "password":
      editPsd();
      break;
    default:
      break;
  }
}
function getInfo() {
  console.log("getInfo",userInfo.value)
  //机构用户
  if(userInfo.value.identity === 1){
    //审核驳回(可修改)
    if(userInfo.value.state === 3){
      const obj = {
        id: userInfo.value.id,
        username: userInfo.value.username,
        agencyId: userInfo.value.agentId
      }
      regRef.value.openDialog('reject', obj);
    }else{
      //审核通过、未审核状态(不可修改)
      const obj = {
        agencyId: userInfo.value.agentId
      }
      reviewRef.value.openDialog(obj,'view')
    }
  }
  //监管用户
  else if (userInfo.value.identity === 0) {
    const obj = {
      id: userInfo.value.id
    }
    superRef.value.openDialog('view', obj);
  }
}
function editPsd() {
  superRef.value.openDialog('pwd', userInfo.value);
}
const sidebarRouters = ref([])
const getList = () => {
  // getState()
  location.href = '/noMenu';
  // if(userInfo.value.state===2){
  //   sidebarRouters.value =  menu.agencyMenu
  //   Cookies.set('routers',JSON.stringify(sidebarRouters.value))
  //   location.href = '/project';
  // }else {
  //   location.href = '/noMenu';
  // }
}
function logout() {
@@ -187,9 +90,9 @@
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    removeToken()
    location.href = '/homePage';
    userStore.logOut().then(() => {
      location.href = '/index';
    })
  }).catch(() => { });
}
@@ -205,8 +108,8 @@
  overflow: hidden;
  position: relative;
  background: #fff;
  border-radius: 0.4rem 0.4rem 0 0;
  border-bottom: 1px solid #d5dce5;
  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
  .hamburger-container {
    line-height: 46px;
    height: 100%;
src/layout/components/Sidebar/Logo.vue
@@ -1,11 +1,11 @@
<template>
  <div class="sidebar-logo-container" :class="{ 'collapse': collapse }" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
    <transition name="sidebarLogoFade">
      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" :to="firstPage">
      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" :to="permissionStore.indexPage">
        <img v-if="logo" :src="logo" class="sidebar-logo" />
        <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
      </router-link>
      <router-link v-else key="expand" class="sidebar-logo-link" :to="firstPage">
      <router-link v-else key="expand" class="sidebar-logo-link" :to="permissionStore.indexPage">
        <img v-if="logo" :src="logo" class="sidebar-logo" />
        <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
      </router-link>
@@ -15,22 +15,16 @@
<script setup>
import variables from '@/assets/styles/variables.module.scss'
import logo from '@/assets/logo/logo2.png'
import logo from '@/assets/logo/logo.png'
import useSettingsStore from '@/store/modules/settings'
import {onMounted, ref} from "vue";
import Cookies from "js-cookie";
import usePermissionStore from '@/store/modules/permission'
defineProps({
  collapse: {
    type: Boolean,
    required: true
  }
})
const firstPage = ref("");
onMounted(() => {
    const routers = JSON.parse(Cookies.get('routers')) ;
    firstPage.value = routers[0].path;
});
const permissionStore = usePermissionStore()
const title = import.meta.env.VITE_APP_TITLE;
const settingsStore = useSettingsStore();
const sideTheme = computed(() => settingsStore.sideTheme);
@@ -63,7 +57,7 @@
      width: 32px;
      height: 32px;
      vertical-align: middle;
      margin-right: 8px;
      margin-right: 12px;
    }
    & .sidebar-title {
@@ -72,7 +66,7 @@
      color: #fff;
      font-weight: 600;
      line-height: 50px;
      font-size: 16px;
      font-size: 14px;
      font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
      vertical-align: middle;
    }
@@ -84,4 +78,4 @@
    }
  }
}
</style>
</style>
src/layout/components/Sidebar/SidebarItem.vue
@@ -16,12 +16,12 @@
      </template>
      <sidebar-item
        v-for="child in item.children"
        :key="child.path"
        :is-nest="true"
        :item="child"
        :base-path="resolvePath(child.path)"
        class="nest-menu"
          v-for="child in item.children"
          :key="child.path"
          :is-nest="true"
          :item="child"
          :base-path="resolvePath(child.path)"
          class="nest-menu"
      />
    </el-sub-menu>
  </div>
src/layout/components/Sidebar/index.vue
@@ -3,20 +3,20 @@
    <logo v-if="showLogo" :collapse="isCollapse" />
    <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper">
      <el-menu
        :default-active="activeMenu"
        :collapse="isCollapse"
        :background-color="sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
        :text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
        :unique-opened="true"
        :active-text-color="theme"
        :collapse-transition="false"
        mode="vertical"
          :default-active="activeMenu"
          :collapse="isCollapse"
          :background-color="sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
          :text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
          :unique-opened="true"
          :active-text-color="theme"
          :collapse-transition="false"
          mode="vertical"
      >
        <sidebar-item
          v-for="(route, index) in sidebarRouters"
          :key="route.path + index"
          :item="route"
          :base-path="route.path"
            v-for="(route, index) in sidebarRouters"
            :key="route.path + index"
            :item="route"
            :base-path="route.path"
        />
      </el-menu>
    </el-scrollbar>
@@ -30,30 +30,16 @@
import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'
import {onMounted, ref} from "vue";
import Cookies from "js-cookie";
import menu from "./menu"
import {computed} from "vue";
import {useRoute} from "vue-router";
const route = useRoute();
const appStore = useAppStore()
const settingsStore = useSettingsStore()
const permissionStore = usePermissionStore()
// const sidebarRouters =  computed(() => permissionStore.sidebarRouters);
const sidebarRouters = ref([])
onMounted(() => {
    sidebarRouters.value = JSON.parse(Cookies.get('routers'))
});
// const getMenu = () => {
//     const userInfo = JSON.parse(Cookies.get('userInfo'))
//     if(userInfo.identity === 0) {
//
//         sidebarRouters.value =  menu.adminMenu
//         Cookies.set('routers',JSON.stringify(sidebarRouters.value))
//     }
// }
const sidebarRouters =  computed(() => permissionStore.sidebarRouters);
console.log(sidebarRouters.value,789)
const showLogo = computed(() => settingsStore.sidebarLogo);
const sideTheme = computed(() => settingsStore.sideTheme);
const theme = computed(() => settingsStore.theme);
@@ -65,7 +51,14 @@
  if (meta.activeMenu) {
    return meta.activeMenu;
  }
  return path;
})
  const showRoute  = sidebarRouters.value.filter(item => !item.hidden);
  if(showRoute[0].path === '/'){
    return '/' + showRoute[0].children[0].path
  }else{
    return showRoute[0].path + '/' + showRoute[0].children[0].path
  }
  // return path
})
</script>
src/layout/components/Sidebar/menu.js
文件已删除
src/layout/index.vue
@@ -27,8 +27,7 @@
const sideTheme = computed(() => settingsStore.sideTheme);
const sidebar = computed(() => useAppStore().sidebar);
const device = computed(() => useAppStore().device);
// const needTagsView = computed(() => settingsStore.tagsView);
const needTagsView = false;
const needTagsView = computed(() => settingsStore.tagsView);
const fixedHeader = computed(() => settingsStore.fixedHeader);
const classObj = computed(() => ({
@@ -64,8 +63,8 @@
</script>
<style lang="scss" scoped>
  @import "@/assets/styles/mixin.scss";
  @import "@/assets/styles/variables.module.scss";
@import "@/assets/styles/mixin.scss";
@import "@/assets/styles/variables.module.scss";
.app-wrapper {
  @include clearfix;
@@ -109,4 +108,4 @@
.mobile .fixed-header {
  width: 100%;
}
</style>
</style>
src/permission.js
@@ -18,42 +18,58 @@
  if (getToken()) {
    to.meta.title && useSettingsStore().setTitle(to.meta.title)
    /* has token*/
    // if (to.path === '/homePage') {
    //   next({ path: '/' })
    //   NProgress.done()
    // } else {
    //   if (useUserStore().roles.length === 0) {
    //     isRelogin.show = true
    //     // 判断当前用户是否已拉取完user_info信息
    //     useUserStore().getInfo().then(() => {
    //       isRelogin.show = false
    //       usePermissionStore().generateRoutes().then(accessRoutes => {
    //         // 根据roles权限生成可访问的路由表
    //         accessRoutes.forEach(route => {
    //           if (!isHttp(route.path)) {
    //             router.addRoute(route) // 动态添加可访问路由表
    //           }
    //         })
    //         next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
    //       })
    //     }).catch(err => {
    //       useUserStore().logOut().then(() => {
    //         ElMessage.error(err)
    //         next({ path: '/' })
    //       })
    //     })
    //   } else {
    if (to.path === '/homePage') {
      next({ path: '/' })
      NProgress.done()
    } else if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      if (useUserStore().roles.length === 0) {
        isRelogin.show = true
        // 判断当前用户是否已拉取完user_info信息
        useUserStore().getInfo().then(() => {
          isRelogin.show = false
          usePermissionStore().generateRoutes().then(accessRoutes => {
            // 根据roles权限生成可访问的路由表
            accessRoutes.forEach(route => {
              if (!isHttp(route.path)) {
                router.addRoute(route) // 动态添加可访问路由表
              }
            })
            console.log(to.fullPath,"to.fullPath")
            if (to.fullPath == '/index') {
              // 当登录之后,直接通过ip地址和端口号访问时,跳转到第一个路由页面indexPage
              let pathIndex = ''
              //通过权限返回菜单去避免 如有首页权限 出现//index 情况
              if (accessRoutes[0].path == '/') {
                pathIndex = accessRoutes[0].path + accessRoutes[0].children[0].path
              } else{
                pathIndex = accessRoutes[0].path + '/' + accessRoutes[0].children[0].path
              }
              next({ path: pathIndex, replace: true }) // hack方法 确保addRoutes已完成
            } else {
              next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
            }
            // next({ ...to, replace: true })
            // hack方法 确保addRoutes已完成
          })
        }).catch(err => {
          useUserStore().logOut().then(() => {
            ElMessage.error(err)
            next({ path: '/' })
          })
        })
      } else {
        next()
    //   }
    // }
      }
    }
  } else {
    // 没有token
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登录白名单,直接进入
      next()
    } else {
      // next(`/homePage?redirect=${to.fullPath}`) // 否则全部重定向到登录页
      next('/homePage')
      next(`/homePage?redirect=${to.fullPath}`) // 否则全部重定向到登录页
      NProgress.done()
    }
  }
src/router/index.js
@@ -1,4 +1,4 @@
import { createWebHistory, createRouter } from 'vue-router'
import { createWebHistory, createWebHashHistory, createRouter } from 'vue-router'
/* Layout */
import Layout from '@/layout'
@@ -62,244 +62,33 @@
    component: () => import('@/views/safetyReview/expertManage/checkProgress/index.vue'),
    hidden: true
  },
  {
    path: '/expertUser',
    component: () => import('@/views/safetyReview/userManage/expertUsers/index.vue'),
    hidden: true
  },
  {
    path: '/evaluate',
    component: () => import('@/views/safetyReview/baseSet/evaluateType/index.vue'),
    hidden: true
  },
  {
    path: '/business',
    component: () => import('@/views/safetyReview/baseSet/business/index.vue'),
    hidden: true
  },
  {
    path: '/area',
    component: () => import('@/views/safetyReview/baseSet/area/index.vue'),
    hidden: true
  },
  // {
  //   path: '',
  //   path: '/noMenu',
  //   component: Layout,
  //   redirect: '/index',
  //   redirect: '/noMenu',
  //   children: [
  //     {
  //       path: '/index',
  //       component: () => import('@/views/index'),
  //       name: 'Index',
  //       meta: { title: '首页',icon: 'form', affix: true }
  //       path: '/noMenu',
  //       component: () => import('@/views/error/noMenu.vue'),
  //       name: 'noMenu',
  //       meta: { title: '提示',icon: 'form',  affix: true }
  //     }
  //   ]
  // },
  {
    path: '/noMenu',
    component: Layout,
    redirect: '/noMenu',
    children: [
      {
        path: '/noMenu',
        component: () => import('@/views/error/noMenu.vue'),
        name: 'noMenu',
        meta: { title: '提示',icon: 'form',  affix: true }
      }
    ]
  },
  {
    path: '',
    component: Layout,
    redirect: '/institution',
    redirect: '/index',
    hidden: true,
    children: [
      {
        path: '/institution',
        component: () => import('@/views/safetyReview/institution/institution.vue'),
        name: 'Institution',
        meta: { title: '机构公示', icon: 'form', affix: true }
        path: '/index',
        component: () => import('@/views/index'),
        name: 'Index',
        meta: { title: '首页', icon: 'dashboard', affix: true }
      }
    ]
  },
  {
    path: '/notice',
    component: Layout,
    redirect: '/notice',
    children: [
      {
        path: '/notice',
        component: () => import('@/views/safetyReview/notice/notice.vue'),
        name: 'Notice',
        meta: { title: '公告发布',icon: 'form',  affix: true }
      }
    ]
  },
  {
    path: '/law',
    component: Layout,
    redirect: '/law',
    children: [
      {
        path: '/law',
        component: () => import('@/views/safetyReview/law/law.vue'),
        name: 'Law',
        meta: { title: '法律法规',icon: 'form', affix: true }
      }
    ]
  },
  {
    path: '/project',
    component: Layout,
    redirect: '/project',
    children: [
      {
        path: '/project',
        component: () => import('@/views/safetyReview/projectManage/index.vue'),
        name: 'Project',
        meta: { title: '项目管理',icon: 'form', affix: true }
      }
    ]
  },
  {
    path: '/projectSupplement',
    component: Layout,
    redirect: '/projectSupplement',
    children: [
      {
        path: '/projectSupplement',
        component: () => import('@/views/safetyReview/projectSupplement/index.vue'),
        name: 'projectSupplement',
        meta: { title: '项目补录',icon: 'form', affix: true }
      }
    ]
  },
  {
    path: '/process',
    component: Layout,
    redirect: '/process',
    children: [
      {
        path: '/process',
        component: () => import('@/views/safetyReview/projectManage/process.vue'),
        name: 'Process',
        meta: { title: '项目信息管理'}
      }
    ]
  },
  {
    path: '/userManage',
    component: Layout,
    redirect: '/userManage/supervise',
    meta: { title: '用户管理'},
    children: [
      {
        path: 'supervise',
        component: () => import('@/views/safetyReview/userManage/superviseUsers/index.vue'),
        name: 'supervise',
        meta: { title: '监管用户管理',icon: 'form'}
      },
      {
        path: 'institutionUser',
        component: () => import('@/views/safetyReview/userManage/institutionUsers/index.vue'),
        name: 'institutionUser',
        meta: { title: '机构用户管理',icon: 'form'}
      },
      {
        path: 'expertUsers',
        component: () => import('@/views/safetyReview/userManage/expertUsers/index.vue'),
        name: 'expertUsers',
        meta: { title: '专家用户管理',icon: 'form'}
      },
    ]
  },
  {
    path: '/expertManage',
    component: Layout,
    redirect: '/expertManage/experts',
    meta: { title: '厅专家库管理'},
    children: [
      {
        path: 'experts',
        component: () => import('@/views/safetyReview/expertManage/experts/index.vue'),
        name: 'expert',
        meta: { title: '厅专家库',icon: 'form'}
      },
      {
        path: 'applyRecords',
        component: () => import('@/views/safetyReview/expertManage/applyRecords/index.vue'),
        name: 'applyRecords',
        meta: { title: '专家申请记录',icon: 'form'}
      },
      {
        path: 'expertUser',
        component: () => import('@/views/safetyReview/userManage/expertUsers/index.vue'),
        name: 'expertUser',
        meta: { title: '专家用户管理',icon: 'form'}
      },
    ]
  },
  {
    path: '/postEvaluation',
    component: Layout,
    redirect: '/postEvaluation',
    children: [
      {
        path: '/postEvaluation',
        component: () => import('@/views/safetyReview/expertManage/postEvaluation/index.vue'),
        name: 'postEvaluation',
        meta: { title: '事后考评'}
      }
    ]
  },
  {
    path: '/evaluateRecord',
    component: Layout,
    redirect: '/evaluateRecord',
    children: [
      {
        path: '/evaluateRecord',
        component: () => import('@/views/safetyReview/expertManage/evaluateRecord/index.vue'),
        name: 'evaluateRecord',
        meta: { title: '专家考评记录'}
      }
    ]
  },
  {
    path: '/system',
    component: Layout,
    redirect: '/system/post',
    meta: { title: '系统设置'},
    children: [
      {
        path: 'dept',
        component: () => import('@/views/system/dept/index.vue'),
        name: 'dept',
        meta: { title: '部门处室管理',icon: 'form'}
      },
      {
        path: 'expertsType',
        component: () => import('@/views/safetyReview/baseSet/expertsType/index.vue'),
        name: 'expertsType',
        meta: { title: '专业领域管理',icon: 'form'}
      },
      {
        path: 'evaluate',
        component: () => import('@/views/safetyReview/baseSet/evaluateType/index.vue'),
        name: 'evaluate',
        meta: { title: '考评项目管理',icon: 'form'}
      },
      {
        path: 'openApply',
        component: () => import('@/views/safetyReview/baseSet/openApply/index.vue'),
        name: 'openApply',
        meta: { title: '专家申请设置',icon: 'form'}
      }
    ]
  },
  {
    path: '/user',
    component: Layout,
src/store/modules/permission.js
@@ -16,7 +16,8 @@
      addRoutes: [],
      defaultRoutes: [],
      topbarRouters: [],
      sidebarRouters: []
      sidebarRouters: [],
      indexPage: ''
    }),
    actions: {
      setRoutes(routes) {
@@ -32,6 +33,9 @@
      setSidebarRouters(routes) {
        this.sidebarRouters = routes
      },
      setIndexPages(routes) {
        this.indexPage = routes
      },
      generateRoutes(roles) {
        return new Promise(resolve => {
          // 向后端请求路由数据
@@ -39,15 +43,24 @@
            const sdata = JSON.parse(JSON.stringify(res.data))
            const rdata = JSON.parse(JSON.stringify(res.data))
            const defaultData = JSON.parse(JSON.stringify(res.data))
            let firstPage = ''
            //通过权限返回菜单去避免 如有首页权限 出现//index 情况
            if (res.data[0].path == '/') {
              firstPage = res.data[0].path + res.data[0].children[0].path
            } else{
              firstPage = res.data[0].path + '/' + res.data[0].children[0].path
            }
            const sidebarRoutes = filterAsyncRouter(sdata)
            const rewriteRoutes = filterAsyncRouter(rdata, false, true)
            const defaultRoutes = filterAsyncRouter(defaultData)
            const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
            asyncRoutes.forEach(route => { router.addRoute(route) })
            this.setRoutes(rewriteRoutes)
            // this.setRoutes(rewriteRoutes)
            this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
            // this.setSidebarRouters(sidebarRoutes)
            this.setDefaultRoutes(sidebarRoutes)
            this.setTopbarRoutes(defaultRoutes)
            this.setIndexPages(firstPage)
            resolve(rewriteRoutes)
          })
        })
src/store/modules/user.js
@@ -24,15 +24,8 @@
        const identity = userInfo.identity
        return new Promise( (resolve, reject) => {
          login(username, password, code, uuid, identity).then( async res => {
            setToken(res.data.token)
            Cookies.set('userInfo',JSON.stringify(res.data))
            await getUserById({userId:res.data.id}).then(ress => {
              Cookies.set('userState',JSON.stringify(ress.data.state))
              if(res.data.identity === 1){
                Cookies.set('attribute',JSON.stringify(ress.data.agency.attribute))
              }
            })
            this.token = res.data.token
            setToken(res.token)
            this.token = res.token
            resolve()
          }).catch(error => {
            reject(error)
@@ -45,7 +38,6 @@
          getInfo().then(res => {
            const user = res.user
            const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
            if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
              this.roles = res.roles
              this.permissions = res.permissions
src/utils/request.js
@@ -76,31 +76,22 @@
    // 未设置状态码则默认成功状态
    const code = res.data.code || 200;
    // 获取错误信息
    const msg = errorCode[code] || res.data.message || errorCode['default']
    const msg = res.data.msg || errorCode[code] || errorCode['default']
    // 二进制数据则直接返回
    if (res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer') {
      return res.data
    }
    if (code === 401) {
      if(location.href.indexOf('homePage') == -1 ){
        if (!isRelogin.show) {
          isRelogin.show = true;
          ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
            isRelogin.show = false;
            removeToken()
      if (!isRelogin.show) {
        isRelogin.show = true;
        ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
          isRelogin.show = false;
          useUserStore().logOut().then(() => {
            location.href = '/homePage';
            // useUserStore().logOut().then(() => {
            //   // router.push('/homePage')
            //
            //   location.href = '/homePage';
            // })
          }).catch(() => {
            isRelogin.show = false
          });
        }
      }else{
        // ElMessage({ message: res.data.message, type: 'error' })
        console.log(res.data.message)
          })
        }).catch(() => {
          isRelogin.show = false;
        });
      }
      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
    } else if (code === 500) {
src/views/components/loginForm.vue
@@ -46,10 +46,6 @@
              <img :src="codeUrl" @click="getCode" class="login-code-img"/>
            </div>
          </el-form-item>
    <!--      <el-radio-group v-model="loginForm.role" class="mb5">-->
    <!--        <el-radio :label="0" size="large">监管部门</el-radio>-->
    <!--        <el-radio :label="1" size="large">机构管理员</el-radio>-->
    <!--      </el-radio-group>-->
          <div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 25px">
            <div class="btn-cont">
              <button class="login-btn" @click.prevent="handleLogin">
@@ -74,16 +70,17 @@
</template>
<script setup>
import {onMounted, ref, watch, defineAsyncComponent, nextTick} from "vue"
import {onMounted, ref, watch, defineAsyncComponent, nextTick, computed} from "vue"
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
import useUserStore from '@/store/modules/user'
import { Register } from "@/layout/components";
import { Base64 } from 'js-base64'
import menu from "@/layout/components/Sidebar/menu";
import ExpertForm from "../safetyReview/expertManage/applyRecords/components/expertForm";
import usePermissionStore from '@/store/modules/permission'
const permissionStore = usePermissionStore()
const sidebarRouters =  computed(() => permissionStore.sidebarRouters);
const userStore = useUserStore()
const route = useRoute();
const router = useRouter();
@@ -93,8 +90,7 @@
  username: "",
  password: "",
  code: "",
  uuid: "",
  role: 0
  uuid: ""
});
const loginRules = {
@@ -113,7 +109,7 @@
const redirect = ref(undefined);
onMounted(()=>{
  Cookies.remove("userState");
})
const openRegist = ()=>{
@@ -123,10 +119,6 @@
watch(route, (newRoute) => {
    redirect.value = newRoute.query && newRoute.query.redirect;
}, { immediate: true });
const sidebarRouters = ref([])
const expertFormRef = ref()
@@ -154,7 +146,8 @@
      // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
      // if (loginForm.value.rememberMe) {
        Cookies.set("username", loginForm.value.username, { expires: 30 });
        Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
        Cookies.set("password", loginForm.value.password, { expires: 30 });
        // Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
      //   Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
      // } else {
        // 否则移除
@@ -166,48 +159,19 @@
      // loginForm.value.password = Base64.encode(loginForm.value.password)
        const param = {
            username: loginForm.value.username,
            password: Base64.encode(loginForm.value.password),
            password: loginForm.value.password,
            code: loginForm.value.code,
            uuid: loginForm.value.uuid,
            identity: loginForm.value.role
        }
      userStore.login(param).then(() => {
        // const query = route.query;
        // const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
        //   if (cur !== "redirect") {
        //     acc[cur] = query[cur];
        //   }
        //   return acc;
        // }, {});
        const userInfo = JSON.parse(Cookies.get('userInfo'))
          if(userInfo.identity === 0 ) {
              //监管用户
              sidebarRouters.value =  menu.adminMenu
              Cookies.set('routers',JSON.stringify(sidebarRouters.value))
          }else if(userInfo.identity === 1) {
            const userState = JSON.parse(Cookies.get('userState'))
            console.log("userState",userState)
              //机构用户
              //未审核状态不显示菜单
              if(userState !==2 ){
                sidebarRouters.value = menu.noMenu
                Cookies.set('routers',JSON.stringify(sidebarRouters.value))
              }else {
                sidebarRouters.value =  menu.agencyMenu
                Cookies.set('routers',JSON.stringify(sidebarRouters.value))
              }
        const query = route.query;
        const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
          if (cur !== "redirect") {
            acc[cur] = query[cur];
          }
          let path = ""
          if(sidebarRouters.value[0].children && sidebarRouters.value[0].children.length > 0){
              path = sidebarRouters.value[0].path + '/'+ sidebarRouters.value[0].children[0].path
          }else {
              path = sidebarRouters.value[0].path
          }
        router.push({
            path: path
        })
        // router.push({ path: redirect.value || "/", query: otherQueryParams });
          return acc;
        }, {});
        router.push({ path: redirect.value || "/", query: otherQueryParams });
      }).catch(() => {
        loading.value = false;
        // 重新获取验证码
@@ -221,22 +185,22 @@
function getCode() {
  getCodeImg().then(res => {
    captchaEnabled.value = res.data.captchaEnabled === undefined ? true : res.captchaEnabled
    captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
    if (captchaEnabled.value) {
      codeUrl.value = "data:image/gif;base64," + res.data.image
      loginForm.value.uuid = res.data.uuid
      codeUrl.value = "data:image/gif;base64," + res.img
      loginForm.value.uuid = res.uuid
    }
  });
}
// function getCookie() {
//   const username = Cookies.get("username")
//   const password = Cookies.get("password")
//   loginForm.value = {
//     username: username === undefined ? loginForm.value.username : username,
//     password: password === undefined ? loginForm.value.password : decrypt(password),
//   };
// }
function getCookie() {
  const username = Cookies.get("username")
  const password = Cookies.get("password")
  loginForm.value = {
    username: username === undefined ? loginForm.value.username : username,
    password: password === undefined ? loginForm.value.password : decrypt(password),
  };
}
getCode();
// getCookie();
src/views/index.vue
@@ -6,28 +6,28 @@
          领取阿里云通用云产品1888优惠券
          <br />
          <el-link
            href="https://www.aliyun.com/minisite/goods?userCode=brki8iof"
            type="primary"
            target="_blank"
            >https://www.aliyun.com/minisite/goods?userCode=brki8iof</el-link
              href="https://www.aliyun.com/minisite/goods?userCode=brki8iof"
              type="primary"
              target="_blank"
          >https://www.aliyun.com/minisite/goods?userCode=brki8iof</el-link
          >
          <br />
          领取腾讯云通用云产品2860优惠券
          <br />
          <el-link
            href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console"
            type="primary"
            target="_blank"
            >https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</el-link
              href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console"
              type="primary"
              target="_blank"
          >https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</el-link
          >
          <br />
          阿里云服务器折扣区
          <el-link href="http://aly.ruoyi.vip" type="primary" target="_blank"
            >>☛☛点我进入☚☚</el-link
          >>☛☛点我进入☚☚</el-link
          >
          &nbsp;&nbsp;&nbsp; 腾讯云服务器秒杀区
          <el-link href="http://txy.ruoyi.vip" type="primary" target="_blank"
            >>☛☛点我进入☚☚</el-link
          >>☛☛点我进入☚☚</el-link
          ><br />
          <h4 class="text-danger">
            云产品通用红包,可叠加官网常规优惠使用。(仅限新用户)
@@ -41,7 +41,7 @@
      <el-col :sm="24" :lg="12" style="padding-left: 20px">
        <h2>若依后台管理框架</h2>
        <p>
          一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了专家管理系统,她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
          一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了若依管理系统,她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
        </p>
        <p>
          <b>当前版本:</b> <span>v{{ version }}</span>
@@ -51,17 +51,17 @@
        </p>
        <p>
          <el-button
            type="primary"
            icon="Cloudy"
            plain
            @click="goTarget('https://gitee.com/y_project/RuoYi-Vue')"
            >访问码云</el-button
              type="primary"
              icon="Cloudy"
              plain
              @click="goTarget('https://gitee.com/y_project/RuoYi-Vue')"
          >访问码云</el-button
          >
          <el-button
            icon="HomeFilled"
            plain
            @click="goTarget('http://ruoyi.vip')"
            >访问主页</el-button
              icon="HomeFilled"
              plain
              @click="goTarget('http://ruoyi.vip')"
          >访问主页</el-button
          >
        </p>
      </el-col>
@@ -114,28 +114,28 @@
              <i class="el-icon-s-promotion"></i> 官网:<el-link
                href="http://www.ruoyi.vip"
                target="_blank"
                >http://www.ruoyi.vip</el-link
              >
            >http://www.ruoyi.vip</el-link
            >
            </p>
            <p>
              <i class="el-icon-user-solid"></i> QQ群:<s> 满937441 </s> <s> 满887144332 </s>
              <s> 满180251782 </s> <s> 满104180207 </s> <s> 满186866453 </s> <s> 满201396349 </s>
              <s> 满101456076 </s> <s> 满101539465 </s> <s> 满264312783 </s> <s> 满167385320 </s>
              <s> 满104748341 </s> <s> 满160110482 </s> <s> 满170801498 </s> <s> 满108482800 </s>
              <s> 满101456076 </s> <s> 满101539465 </s> <s> 满264312783 </s> <s> 满167385320 </s>
              <s> 满104748341 </s> <s> 满160110482 </s> <s> 满170801498 </s> <s> 满108482800 </s>
              <s> 满101046199 </s> <s> 满136919097 </s> <s> 满143961921 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=1HmEGh7zKA_CKI2E-pGInPTlC5jS9mc_&authKey=XaiUf1wfbSTEecm4lDMtIMsc6g%2BoETxjBm1BbZPr6IfuMGRj7oG4GEeu7jtzNaw%2F&noverify=0&group_code=174951577" target="_blank">174951577</a>
            </p>
            <p>
              <i class="el-icon-chat-dot-round"></i> 微信:<a
                href="javascript:;"
                >/ *若依</a
              >
            >/ *若依</a
            >
            </p>
            <p>
              <i class="el-icon-money"></i> 支付宝:<a
                href="javascript:;"
                class="支付宝信息"
                >/ *若依</a
              >
            >/ *若依</a
            >
            </p>
          </div>
        </el-card>
@@ -930,12 +930,12 @@
          </template>
          <div class="body">
            <img
              src="@/assets/images/pay.png"
              alt="donate"
              style="width:100%"
                src="@/assets/images/pay.png"
                alt="donate"
                style="width:100%"
            />
            <span style="display: inline-block; height: 30px; line-height: 30px"
              >你可以请作者喝杯咖啡表示鼓励</span
            >你可以请作者喝杯咖啡表示鼓励</span
            >
          </div>
        </el-card>
src/views/safetyReview/baseSet/evaluateType/index.vue
@@ -66,7 +66,7 @@
const { queryParams, total, dataList } = toRefs(data);
onMounted(() => {
    getList();
    // getList();
});
const getList = async () => {
    loading.value = true;
src/views/safetyReview/baseSet/expertsType/index.vue
@@ -81,7 +81,7 @@
import {ElMessage, ElMessageBox} from "element-plus"
import { Plus } from '@element-plus/icons-vue'
const state = reactive({
  loading: true,
  loading: false,
  total: 0,
  expertList: [],
  title: "",
@@ -100,7 +100,7 @@
const formRef = ref()
  onMounted(()=>{
    getList()
    // getList()
  })
    /** 查询岗位列表 */
  const getList = async()=> {
src/views/safetyReview/baseSet/openApply/index.vue
@@ -49,7 +49,7 @@
const { queryParams, total, dataList } = toRefs(data);
onMounted(() => {
    getList();
    // getList();
});
const getList = async () => {
    loading.value = true;
src/views/safetyReview/expertManage/evaluateRecord/index.vue
@@ -104,8 +104,8 @@
const { showSearch,total, expertTypes,expertList,queryParams,classiFy,searchTime} = toRefs(data);
const evaluateFormRef = ref()
onMounted(()=>{
  getList()
  getTypes()
  // getList()
  // getTypes()
})
onUnmounted(()=>{
src/views/safetyReview/expertManage/experts/index.vue
@@ -107,8 +107,8 @@
const { showSearch,total, expertTypes,expertList,queryParams,classiFy,searchTime} = toRefs(data);
const expertFormRef = ref()
onMounted(()=>{
  getList()
  getTypes()
  // getList()
  // getTypes()
})
onUnmounted(()=>{
@@ -170,7 +170,7 @@
  loading.value = true;
  const res = await getExpertsList(data.queryParams)
  if(res.code == 200){
    data.expertList = res.data.list.map(item => {
    data.expertList = res.data.map(item => {
      return{
        ...item,
        birthdayName: item.birthday ? item.birthday.slice(0,10) : ''
src/views/safetyReview/expertManage/postEvaluation/components/expertList.vue
@@ -3,7 +3,7 @@
        <el-dialog
            v-model="dialogVisible"
            title="专家评估"
            width="500px"
            width="75%"
        >
          <el-table :data="tableData" border style="width: 100%">
            <el-table-column type="index" width="55" align="center" />
@@ -28,7 +28,7 @@
            <el-table-column label="考评总分" align="center" prop="degree" />
            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
              <template #default="scope">
                <el-button type="primary" link @click="openEvaluate('edit',scope.row)">评分</el-button>
                <el-button type="primary" link @click="openEvaluate()">评分</el-button>
              </template>
            </el-table-column>
          </el-table>
src/views/safetyReview/expertManage/postEvaluation/index.vue
@@ -61,18 +61,18 @@
          v-model:limit="queryParams.pageSize"
          @pagination="getList"
      />
      <expert-list ref="expertListRef" @getList="getList"></expert-list>
      <expert-dialog ref="expertListRef" @getList="getList"></expert-dialog>
    </div>
</template>
<script setup>
import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import ExpertList from "./components/expertList";
import ExpertDialog from "./components/expertList";
import {delExpert, getExpertsList, getExpertTypes} from "../../../../api/form";
import { Plus } from '@element-plus/icons-vue'
const loading = ref(false);
const loading = ref(false)
const data = reactive({
  showSearch: true,
  total: 0,
@@ -98,8 +98,8 @@
const expertListRef = ref()
onMounted(()=>{
  getList()
  getTypes()
  // getList()
  // getTypes()
})
onUnmounted(()=>{
@@ -170,7 +170,6 @@
}
const openDialog = async (type, value) => {
  console.log(expertListRef.value,888)
  expertListRef.value.openDialog(type, value)
}