From 5d0e4bcaf5d44a9ce2ff196e38c77676aa8ea880 Mon Sep 17 00:00:00 2001
From: zhouwx <1175765986@qq.com>
Date: Fri, 12 Jun 2026 16:37:15 +0800
Subject: [PATCH] 中科大支线—添加菜单、角色

---
 src/views/index.vue                                                                                        |  101 +
 src/views/hazardousChemicals/avoidWarningMenu/avoidWarning/components/avoidDialog.vue                      |    0 
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawTable.vue           |    0 
 src/views/hazardousChemicals/systemManage/config/components/mapLocation.vue                                |   24 
 src/views/hazardousChemicals/finishedBasicInfoMenu/finishedBasicInfo/index.vue                             |    0 
 src/layout/components/Sidebar/Logo.vue                                                                     |   22 
 src/views/system/role/authUser.vue                                                                         |   60 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/printCode.vue                  |    0 
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawWarehouseRecord.vue |    0 
 src/permission.js                                                                                          |   92 +
 src/views/hazardousChemicals/useCountMenu/useCount/index.vue                                               |    0 
 src/api/login.js                                                                                           |    2 
 src/views/hazardousChemicals/accessRecordsMenu/accessRecords/index.vue                                     |    0 
 src/store/modules/user.js                                                                                  |   15 
 src/views/hazardousChemicals/subscribeApplyManage/subscribe/index.vue                                      |  263 ++++
 src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/rawTable.vue                       |    2 
 src/views/hazardousChemicals/basicInfonMenu/basicInfon/index.vue                                           |    0 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/addRawDialog.vue               |    0 
 src/router/index.js                                                                                        |  643 +++++++----
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawDetail.vue          |    0 
 src/views/hazardousChemicals/basicInfonMenu/basicInfon/components/basicDialog.vue                          |    0 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/productTable.vue               |    0 
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/proWarehouseRecord.vue |    0 
 src/views/hazardousChemicals/subscribeApplyManage/record/index.vue                                         |  266 +++++
 src/views/hazardousChemicals/avoidWarningMenu/avoidWarning/index.vue                                       |    0 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/printCodeMore.vue              |    0 
 src/views/hazardousChemicals/subscribeApplyManage/approval/index.vue                                       |  262 ++++
 src/views/hazardousChemicals/overdueWarningMenu/overdueWarning/index.vue                                   |    0 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/addProDialog.vue               |    0 
 src/views/system/role/index.vue                                                                            |   14 
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/proDetail.vue          |    0 
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/viewQR.vue             |    0 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/rawDetail.vue                  |    0 
 src/views/hazardousChemicals/finishedBasicInfoMenu/finishedBasicInfo/components/finishedBasicDialog.vue    |    0 
 src/views/hazardousChemicals/homePageMenu/homePage/index.vue                                               |    0 
 src/views/system/menu/index.vue                                                                            |    2 
 src/views/hazardousChemicals/subscribeApplyManage/record/components/editDialog.vue                         |  201 +++
 src/views/hazardousChemicals/traceableQueryMenu/traceableQuery/index.vue                                   |    2 
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/index.vue                         |    0 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/rawTable.vue                   |    0 
 src/views/system/role/selectUser.vue                                                                       |   42 
 src/layout/components/Sidebar/index.vue                                                                    |   45 
 src/layout/components/Sidebar/SidebarItem.vue                                                              |  181 ++
 src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/productTable.vue       |    0 
 src/utils/dict.js                                                                                          |    2 
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/index.vue                                 |    0 
 src/views/homePage.vue                                                                                     |  179 ++-
 src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/proDetail.vue                  |    0 
 src/views/hazardousChemicals/subscribeApplyManage/approval/components/editDialog.vue                       |  238 ++++
 src/store/modules/permission.js                                                                            |   30 
 src/views/hazardousChemicals/subscribeApplyManage/subscribe/components/editDialog.vue                      |  335 ++++++
 src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/productTable.vue                   |    2 
 src/api/menu.js                                                                                            |    4 
 src/store/modules/dict.js                                                                                  |   98 
 package.json                                                                                               |    7 
 55 files changed, 2,600 insertions(+), 534 deletions(-)

diff --git a/package.json b/package.json
index e4b41c8..1f5becc 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,12 @@
     "vue-router": "4.1.4",
     "vue3-count-to": "^1.1.2",
     "vue3-json-excel": "^1.0.10-alpha",
-    "wangeditor5-for-vue3": "^0.1.0"
+    "wangeditor5-for-vue3": "^0.1.0",
+    "docx": "^9.5.1",
+    "docx-preview": "^0.3.5",
+    "docx-templates": "^4.14.1",
+    "docxtemplater": "^3.65.1",
+    "docxtemplater-image-module-free": "^1.1.1"
   },
   "devDependencies": {
     "@vitejs/plugin-vue": "3.1.0",
diff --git a/src/api/login.js b/src/api/login.js
index eb9601a..69847e6 100644
--- a/src/api/login.js
+++ b/src/api/login.js
@@ -43,7 +43,7 @@
 // 获取用户详细信息
 export function getInfo() {
   return request({
-    url: '/getInfo',
+    url: '/system/account/getInfo',
     method: 'get'
   })
 }
diff --git a/src/api/menu.js b/src/api/menu.js
index faef101..ee2cb16 100644
--- a/src/api/menu.js
+++ b/src/api/menu.js
@@ -3,7 +3,7 @@
 // 获取路由
 export const getRouters = () => {
   return request({
-    url: '/getRouters',
+    url: '/system/account/getRouters',
     method: 'get'
   })
-}
\ No newline at end of file
+}
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index ebaaa8a..5897980 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/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="logoImg" :src="logoImg" 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="logoImg" :src="logoImg" class="sidebar-logo" />
         <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
       </router-link>
@@ -17,6 +17,7 @@
 import variables from '@/assets/styles/variables.module.scss'
 import logo from '@/assets/logo/logo2.png'
 import useSettingsStore from '@/store/modules/settings'
+import usePermissionStore from '@/store/modules/permission'
 import {onMounted, ref} from "vue";
 import Cookies from "js-cookie";
 defineProps({
@@ -28,14 +29,14 @@
 const logoImg = ref('')
 const firstPage = ref("");
 onMounted(() => {
-    const routers = JSON.parse(Cookies.get('routers')) ;
-    if(routers[0].children){
-      firstPage.value = routers[0].path + '/' + routers[0].children[0].path;
-    }else {
-      firstPage.value = routers[0].path;
-    }
-
-  console.log(routers,'firstPage.value')
+    // const routers = JSON.parse(Cookies.get('routers')) ;
+    // if(routers[0].children){
+    //   firstPage.value = routers[0].path + '/' + routers[0].children[0].path;
+    // }else {
+    //   firstPage.value = routers[0].path;
+    // }
+  //
+  // console.log(routers,'firstPage.value')
     console.log(firstPage.value,'firstPage.value')
     if(Cookies.get('configInfo')){
       const config = JSON.parse(Cookies.get('configInfo'))
@@ -50,6 +51,7 @@
 
 
 });
+const permissionStore = usePermissionStore()
 const title = import.meta.env.VITE_APP_TITLE;
 const settingsStore = useSettingsStore();
 const sideTheme = computed(() => settingsStore.sideTheme);
diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
index c423fb1..cf69f54 100644
--- a/src/layout/components/Sidebar/SidebarItem.vue
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -1,33 +1,147 @@
 <template>
+<!--  <div v-if="!item.hidden">-->
+<!--    <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">-->
+<!--      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">-->
+<!--        <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">-->
+<!--          <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>-->
+<!--          <template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template>-->
+<!--        </el-menu-item>-->
+<!--      </app-link>-->
+<!--    </template>-->
+
+<!--    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>-->
+<!--      <template v-if="item.meta" #title>-->
+<!--        <svg-icon :icon-class="item.meta && item.meta.icon" />-->
+<!--        <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>-->
+<!--      </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"-->
+<!--      />-->
+<!--    </el-sub-menu>-->
+<!--  </div>-->
   <div v-if="!item.hidden">
-    <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
-      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
-        <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
-          <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
-          <template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template>
+    <!-- 优化条件:优先判定【仅有1个可见子菜单】,直接走一级菜单渲染 -->
+    <template v-if="calcSingleChild(item) && item.path != '/system'">
+      <app-link v-if="onlyOneChild?.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
+        <el-menu-item
+            :index="resolvePath(onlyOneChild.path)"
+            :class="{ 'submenu-title-noDropdown': !isNest }"
+        >
+          <svg-icon :icon-class="item.meta?.icon || onlyOneChild.meta?.icon"/>
+          <template #title>
+            <span class="menu-title" :title="hasTitle(item.meta?.title || onlyOneChild.meta?.title)">
+              {{ item.meta?.title || onlyOneChild.meta?.title }}
+            </span>
+          </template>
         </el-menu-item>
       </app-link>
     </template>
 
-    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
+    <!-- 多个子菜单 / 强制目录:正常展开二级菜单 -->
+    <el-sub-menu
+        v-else
+        ref="subMenu"
+        :index="resolvePath(item.path)"
+        popper-append-to-body
+    >
       <template v-if="item.meta" #title>
         <svg-icon :icon-class="item.meta && item.meta.icon" />
         <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
       </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>
 </template>
 
+<!--<script setup>-->
+<!--import { isExternal } from '@/utils/validate'-->
+<!--import AppLink from './Link'-->
+<!--import { getNormalPath } from '@/utils/ruoyi'-->
+
+<!--const props = defineProps({-->
+<!--  // route object-->
+<!--  item: {-->
+<!--    type: Object,-->
+<!--    required: true-->
+<!--  },-->
+<!--  isNest: {-->
+<!--    type: Boolean,-->
+<!--    default: false-->
+<!--  },-->
+<!--  basePath: {-->
+<!--    type: String,-->
+<!--    default: ''-->
+<!--  }-->
+<!--})-->
+
+<!--const onlyOneChild = ref({});-->
+
+<!--function hasOneShowingChild(children = [], parent) {-->
+<!--  if (!children) {-->
+<!--    children = [];-->
+<!--  }-->
+<!--  const showingChildren = children.filter(item => {-->
+<!--    if (item.hidden) {-->
+<!--      return false-->
+<!--    } else {-->
+<!--      // Temp set(will be used if only has one showing child)-->
+<!--      onlyOneChild.value = item-->
+<!--      return true-->
+<!--    }-->
+<!--  })-->
+
+<!--  // When there is only one child router, the child router is displayed by default-->
+<!--  if (showingChildren.length === 1) {-->
+<!--    return true-->
+<!--  }-->
+
+<!--  // Show parent if there are no child router to display-->
+<!--  if (showingChildren.length === 0) {-->
+<!--    onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }-->
+<!--    return true-->
+<!--  }-->
+
+<!--  return false-->
+<!--};-->
+
+<!--function resolvePath(routePath, routeQuery) {-->
+<!--  if (isExternal(routePath)) {-->
+<!--    return routePath-->
+<!--  }-->
+<!--  if (isExternal(props.basePath)) {-->
+<!--    return props.basePath-->
+<!--  }-->
+<!--  if (routeQuery) {-->
+<!--    let query = JSON.parse(routeQuery);-->
+<!--    return { path: getNormalPath(props.basePath + '/' + routePath), query: query }-->
+<!--  }-->
+<!--  return getNormalPath(props.basePath + '/' + routePath)-->
+<!--}-->
+
+<!--function hasTitle(title){-->
+<!--  if (title.length > 5) {-->
+<!--    return title;-->
+<!--  } else {-->
+<!--    return "";-->
+<!--  }-->
+<!--}-->
+<!--</script>-->
 <script setup>
+import { ref } from 'vue'
 import { isExternal } from '@/utils/validate'
 import AppLink from './Link'
 import { getNormalPath } from '@/utils/ruoyi'
@@ -48,35 +162,44 @@
   }
 })
 
-const onlyOneChild = ref({});
+// 修复:初始化为 null,而非空对象
+const onlyOneChild = ref(null);
 
+/**
+ * 修复版:判断是否只有一个可见子菜单(核心改动)
+ */
 function hasOneShowingChild(children = [], parent) {
-  if (!children) {
-    children = [];
-  }
-  const showingChildren = children.filter(item => {
-    if (item.hidden) {
-      return false
-    } else {
-      // Temp set(will be used if only has one showing child)
-      onlyOneChild.value = item
-      return true
-    }
-  })
+  if (!children) children = []
 
-  // When there is only one child router, the child router is displayed by default
+  // 1. 先统一过滤出【未隐藏】的子菜单
+  const showingChildren = children.filter(item => !item.hidden)
+
+  // 2. 仅有 1 个可见子菜单:赋值 + 标记无下级,适配原有判断
   if (showingChildren.length === 1) {
+    const child = showingChildren[0]
+    // 标记:当前子菜单没有可展示的下级(关键,适配原模板逻辑)
+    onlyOneChild.value = { ...child, noShowingChildren: true }
     return true
   }
 
-  // Show parent if there are no child router to display
+  // 3. 没有可见子菜单
   if (showingChildren.length === 0) {
     onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
     return true
   }
 
+  // 4. 多个子菜单
+  onlyOneChild.value = null
   return false
-};
+}
+
+/**
+ * 新增统一判断方法:简化模板条件,命中「单菜单合并逻辑」
+ */
+function calcSingleChild(item) {
+// 存在子菜单 且 仅有一个可见子菜单
+  return hasOneShowingChild(item.children, item)
+}
 
 function resolvePath(routePath, routeQuery) {
   if (isExternal(routePath)) {
@@ -93,7 +216,7 @@
 }
 
 function hasTitle(title){
-  if (title.length > 5) {
+  if (title && title.length > 5) {
     return title;
   } else {
     return "";
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index a625286..7735cd8 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/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,13 @@
 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"
+
 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);
 const showLogo = computed(() => settingsStore.sidebarLogo);
 const sideTheme = computed(() => settingsStore.sideTheme);
 const theme = computed(() => settingsStore.theme);
diff --git a/src/permission.js b/src/permission.js
index dc79d74..71e2767 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -11,49 +11,81 @@
 
 NProgress.configure({ showSpinner: false });
 
-const whiteList = ['/homePage'];
+const whiteList = ['/homePage','/fillForm','/checkProgress','/certPdf'];
 
 router.beforeEach((to, from, next) => {
   NProgress.start()
+
   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 = ''
+              if(accessRoutes.length == 0){
+                ElMessage.warning('当前用户未配置菜单权限,请联系管理员!')
+                next(`/index`)
+                return
+              }
+              const firstRoute = accessRoutes[0]
+              // 👇 新增判断:是否有子菜单
+              if (firstRoute.children && firstRoute.children.length > 0) {
+                // 有二级菜单,走原来的逻辑
+                if (firstRoute.path == '/') {
+                  pathIndex = firstRoute.path + firstRoute.children[0].path
+                } else {
+                  pathIndex = firstRoute.path + '/' + firstRoute.children[0].path
+                }
+              } else {
+                // 没有二级菜单,直接用一级路由的path
+                pathIndex = firstRoute?.path || '/404'
+              }
+              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()
     }
   }
diff --git a/src/router/index.js b/src/router/index.js
index 9a9c99a..0969a5c 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,4 +1,395 @@
-import { createWebHistory, createRouter } from 'vue-router'
+// import { createWebHistory, createRouter } from 'vue-router'
+// /* Layout */
+// import Layout from '@/layout'
+//
+// /**
+//  * Note: 路由配置项
+//  *
+//  * hidden: true                     // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
+//  * alwaysShow: true                 // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
+//  *                                  // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
+//  *                                  // 若你想不管路由下面的 children 声明的个数都显示你的根路由
+//  *                                  // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
+//  * redirect: noRedirect             // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
+//  * name:'router-name'               // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
+//  * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
+//  * roles: ['admin', 'common']       // 访问路由的角色权限
+//  * permissions: ['a:a:a', 'b:b:b']  // 访问路由的菜单权限
+//  * meta : {
+//     noCache: true                   // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
+//     title: 'title'                  // 设置该路由在侧边栏和面包屑中展示的名字
+//     icon: 'svg-name'                // 设置该路由的图标,对应路径src/assets/icons/svg
+//     breadcrumb: false               // 如果设置为false,则不会在breadcrumb面包屑中显示
+//     activeMenu: '/system/user'      // 当路由设置了该属性,则会高亮相对应的侧边栏。
+//   }
+//  */
+//
+// // 公共路由
+// export const constantRoutes = [
+//   {
+//     path: '/redirect',
+//     component: Layout,
+//     hidden: true,
+//     children: [
+//       {
+//         path: '/redirect/:path(.*)',
+//         component: () => import('@/views/redirect/index.vue')
+//       }
+//     ]
+//   },
+//   {
+//     path: '/homePage',
+//     component: () => import('@/views/homePage'),
+//     hidden: true
+//   },
+//   {
+//     path: "/:pathMatch(.*)*",
+//     component: () => import('@/views/homePage'),
+//     hidden: true
+//   },
+//   {
+//     path: '/401',
+//     component: () => import('@/views/error/401'),
+//     hidden: true
+//   },
+//   // {
+//   //   path: '/newPage',
+//   //   component: Layout,
+//   //   redirect: '/newPage',
+//   //   children: [
+//   //     {
+//   //       path: '/newPage',
+//   //       component: () => import('@/views/onlineEducation/systemManage/banner/components/newPage.vue'),
+//   //       name: 'NewPage',
+//   //     }
+//   //   ]
+//   // },
+//   {
+//     path: '/warehouseManage',
+//     component: Layout,
+//     redirect: '/warehouseManage',
+//     children: [
+//       {
+//         path: '/warehouseManage',
+//         component: () => import('@/views/hazardousChemicals/warehouseManage/index.vue'),
+//         name: 'warehouseManage',
+//         meta: { title: '入库管理',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//
+//   {
+//     path: '/electronicWarehouse',
+//     component: Layout,
+//     redirect: '/electronicWarehouse',
+//     children: [
+//       {
+//         path: '/electronicWarehouse',
+//         component: () => import('@/views/hazardousChemicals/electronicWarehouse/index.vue'),
+//         name: 'electronicWarehouse',
+//         meta: { title: '电子仓库',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/rawDetail',
+//     component: Layout,
+//     redirect: '/rawDetail',
+//     children: [
+//       {
+//         path: '/rawDetail',
+//         component: () => import('@/views/hazardousChemicals/electronicWarehouse/components/rawDetail.vue'),
+//         name: 'rawDetail',
+//         meta: { title: '危化品详单',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/proDetail',
+//     component: Layout,
+//     redirect: '/proDetail',
+//     children: [
+//       {
+//         path: '/proDetail',
+//         component: () => import('@/views/hazardousChemicals/electronicWarehouse/components/proDetail.vue'),
+//         name: 'proDetail',
+//         meta: { title: '成品详单',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/whRawDetail',
+//     component: Layout,
+//     redirect: '/whRawDetail',
+//     children: [
+//       {
+//         path: '/whRawDetail',
+//         component: () => import('@/views/hazardousChemicals/warehouseManage/components/rawDetail.vue'),
+//         name: 'whRawDetail',
+//         meta: { title: '危化品详情',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/whProDetail',
+//     component: Layout,
+//     redirect: '/whProDetail',
+//     children: [
+//       {
+//         path: '/whProDetail',
+//         component: () => import('@/views/hazardousChemicals/warehouseManage/components/proDetail.vue'),
+//         name: 'whProDetail',
+//         meta: { title: '成品详情',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/accessRecords',
+//     component: Layout,
+//     redirect: '/accessRecords',
+//     children: [
+//       {
+//         path: '/accessRecords',
+//         component: () => import('@/views/hazardousChemicals/accessRecords/index.vue'),
+//         name: 'accessRecords',
+//         meta: { title: '取用记录',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/traceableQuery',
+//     component: Layout,
+//     redirect: '/traceableQuery',
+//     children: [
+//       {
+//         path: '/traceableQuery',
+//         component: () => import('@/views/hazardousChemicals/traceableQuery/index.vue'),
+//         name: 'traceableQuery',
+//         meta: { title: '溯源查询',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/overdueWarning',
+//     component: Layout,
+//     redirect: '/overdueWarning',
+//     children: [
+//       {
+//         path: '/overdueWarning',
+//         component: () => import('@/views/hazardousChemicals/overdueWarning/index.vue'),
+//         name: 'overdueWarning',
+//         meta: { title: '超期预警',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/avoidWarning',
+//     component: Layout,
+//     redirect: '/avoidWarning',
+//     children: [
+//       {
+//         path: '/avoidWarning',
+//         component: () => import('@/views/hazardousChemicals/avoidWarning/index.vue'),
+//         name: 'avoidWarning',
+//         meta: { title: '危化品相忌报警',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/useCount',
+//     component: Layout,
+//     redirect: '/useCount',
+//     children: [
+//       {
+//         path: '/useCount',
+//         component: () => import('@/views/hazardousChemicals/useCount/index.vue'),
+//         name: 'useCount',
+//         meta: { title: '用量统计',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/basicInfo',
+//     component: Layout,
+//     redirect: '/basicInfo',
+//     children: [
+//       {
+//         path: '/basicInfo',
+//         component: () => import('@/views/hazardousChemicals/basicInfon/index.vue'),
+//         name: 'basicInfo',
+//         meta: { title: '危化品基础信息',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/finishedBasicInfo',
+//     component: Layout,
+//     redirect: '/finishedBasicInfo',
+//     children: [
+//       {
+//         path: '/finishedBasicInfo',
+//         component: () => import('@/views/hazardousChemicals/finishedBasicInfo/index.vue'),
+//         name: 'finishedBasicInfo',
+//         meta: { title: '成品基础信息',icon: 'form',  affix: true }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/homePageIndex',
+//     component: Layout,
+//     redirect: '/homePageIndex',
+//     meta: { title: '首页'},
+//     children: [
+//       {
+//         path: 'homePageIndex',
+//         component: () => import('@/views/hazardousChemicals/homePage/index.vue'),
+//         name: 'homePageIndex',
+//         meta: { title: '工作台',icon: 'form'}
+//       },
+//     ]
+//   },
+//   {
+//     path: '/systemManage',
+//     component: Layout,
+//     redirect: '/systemManage/warehouse',
+//     meta: { title: '系统管理'},
+//     children: [
+//       {
+//         path: 'warehouse',
+//         component: () => import('@/views/hazardousChemicals/systemManage/warehouse/index.vue'),
+//         name: 'warehouse',
+//         meta: { title: '仓库管理',icon: 'form'}
+//       },
+//       {
+//         path: 'company',
+//         component: () => import('@/views/hazardousChemicals/systemManage/company/index.vue'),
+//         name: 'company',
+//         meta: { title: '企业管理',icon: 'form'}
+//       },
+//       {
+//         path: 'user',
+//         component: () => import('@/views/hazardousChemicals/systemManage/user/index.vue'),
+//         name: 'user',
+//         meta: { title: '企业用户管理',icon: 'form'}
+//       },
+//       {
+//         path: 'department',
+//         component: () => import('@/views/hazardousChemicals/systemManage/department/index.vue'),
+//         name: 'department',
+//         meta: { title: '部门管理',icon: 'form'}
+//       },
+//       {
+//         path: 'config',
+//         component: () => import('@/views/hazardousChemicals/systemManage/config/index.vue'),
+//         name: 'config',
+//         meta: { title: '企业配置',icon: 'form'}
+//       },
+//       {
+//         path: 'characteristic',
+//         component: () => import('@/views/hazardousChemicals/systemManage/characteristic/index.vue'),
+//         name: 'characteristic',
+//         meta: { title: '危化品特性管理',icon: 'form'}
+//       },
+//       {
+//         path: 'classifyInfoTable',
+//         component: () => import('@/views/hazardousChemicals/systemManage/classifyInfoTable/index.vue'),
+//         name: 'classifyInfoTable',
+//         meta: { title: '危化品分类信息表',icon: 'form'}
+//       },
+//
+//     ]
+//   },
+//
+// ]
+//
+// // 动态路由,基于用户权限动态去加载
+// export const dynamicRoutes = [
+//   {
+//     path: '/system/user-auth',
+//     component: Layout,
+//     hidden: true,
+//     permissions: ['system:user:edit'],
+//     children: [
+//       {
+//         path: 'role/:userId(\\d+)',
+//         component: () => import('@/views/system/user/authRole'),
+//         name: 'AuthRole',
+//         meta: { title: '分配角色', activeMenu: '/system/user' }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/system/role-auth',
+//     component: Layout,
+//     hidden: true,
+//     permissions: ['system:role:edit'],
+//     children: [
+//       {
+//         path: 'user/:roleId(\\d+)',
+//         component: () => import('@/views/system/role/authUser'),
+//         name: 'AuthUser',
+//         meta: { title: '分配用户', activeMenu: '/system/role' }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/system/dict-data',
+//     component: Layout,
+//     hidden: true,
+//     permissions: ['system:dict:list'],
+//     children: [
+//       {
+//         path: 'index/:dictId(\\d+)',
+//         component: () => import('@/views/system/dict/data'),
+//         name: 'Data',
+//         meta: { title: '字典数据', activeMenu: '/system/dict' }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/monitor/job-log',
+//     component: Layout,
+//     hidden: true,
+//     permissions: ['monitor:job:list'],
+//     children: [
+//       {
+//         path: 'index/:jobId(\\d+)',
+//         component: () => import('@/views/monitor/job/log'),
+//         name: 'JobLog',
+//         meta: { title: '调度日志', activeMenu: '/monitor/job' }
+//       }
+//     ]
+//   },
+//   {
+//     path: '/tool/gen-edit',
+//     component: Layout,
+//     hidden: true,
+//     permissions: ['tool:gen:edit'],
+//     children: [
+//       {
+//         path: 'index/:tableId(\\d+)',
+//         component: () => import('@/views/tool/gen/editTable'),
+//         name: 'GenEdit',
+//         meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
+//       }
+//     ]
+//   }
+// ]
+//
+// const router = createRouter({
+//   history: createWebHistory(),
+//   routes: constantRoutes,
+//   scrollBehavior(to, from, savedPosition) {
+//     if (savedPosition) {
+//       return savedPosition
+//     } else {
+//       return { top: 0 }
+//     }
+//   },
+// });
+//
+// export default router;
+import { createWebHistory, createWebHashHistory, createRouter } from 'vue-router'
 /* Layout */
 import Layout from '@/layout'
 
@@ -44,7 +435,7 @@
   },
   {
     path: "/:pathMatch(.*)*",
-    component: () => import('@/views/homePage'),
+    component: () => import('@/views/error/404'),
     hidden: true
   },
   {
@@ -52,254 +443,35 @@
     component: () => import('@/views/error/401'),
     hidden: true
   },
-  // {
-  //   path: '/newPage',
-  //   component: Layout,
-  //   redirect: '/newPage',
-  //   children: [
-  //     {
-  //       path: '/newPage',
-  //       component: () => import('@/views/onlineEducation/systemManage/banner/components/newPage.vue'),
-  //       name: 'NewPage',
-  //     }
-  //   ]
-  // },
-  {
-    path: '/warehouseManage',
-    component: Layout,
-    redirect: '/warehouseManage',
-    children: [
-      {
-        path: '/warehouseManage',
-        component: () => import('@/views/hazardousChemicals/warehouseManage/index.vue'),
-        name: 'warehouseManage',
-        meta: { title: '入库管理',icon: 'form',  affix: true }
-      }
-    ]
-  },
 
   {
-    path: '/electronicWarehouse',
+    path: '',
     component: Layout,
-    redirect: '/electronicWarehouse',
+    redirect: '/index',
+    hidden: true,
     children: [
       {
-        path: '/electronicWarehouse',
-        component: () => import('@/views/hazardousChemicals/electronicWarehouse/index.vue'),
-        name: 'electronicWarehouse',
-        meta: { title: '电子仓库',icon: 'form',  affix: true }
+        path: '/index',
+        component: () => import('@/views/index'),
+        name: 'Index',
+        meta: { title: '首页', icon: 'dashboard', affix: true }
       }
     ]
   },
   {
-    path: '/rawDetail',
+    path: '/user',
     component: Layout,
-    redirect: '/rawDetail',
+    hidden: true,
+    redirect: 'noredirect',
     children: [
       {
-        path: '/rawDetail',
-        component: () => import('@/views/hazardousChemicals/electronicWarehouse/components/rawDetail.vue'),
-        name: 'rawDetail',
-        meta: { title: '危化品详单',icon: 'form',  affix: true }
+        path: 'profile',
+        component: () => import('@/views/system/user/profile/index'),
+        name: 'Profile',
+        meta: { title: '个人中心', icon: 'user' }
       }
     ]
   },
-  {
-    path: '/proDetail',
-    component: Layout,
-    redirect: '/proDetail',
-    children: [
-      {
-        path: '/proDetail',
-        component: () => import('@/views/hazardousChemicals/electronicWarehouse/components/proDetail.vue'),
-        name: 'proDetail',
-        meta: { title: '成品详单',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/whRawDetail',
-    component: Layout,
-    redirect: '/whRawDetail',
-    children: [
-      {
-        path: '/whRawDetail',
-        component: () => import('@/views/hazardousChemicals/warehouseManage/components/rawDetail.vue'),
-        name: 'whRawDetail',
-        meta: { title: '危化品详情',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/whProDetail',
-    component: Layout,
-    redirect: '/whProDetail',
-    children: [
-      {
-        path: '/whProDetail',
-        component: () => import('@/views/hazardousChemicals/warehouseManage/components/proDetail.vue'),
-        name: 'whProDetail',
-        meta: { title: '成品详情',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/accessRecords',
-    component: Layout,
-    redirect: '/accessRecords',
-    children: [
-      {
-        path: '/accessRecords',
-        component: () => import('@/views/hazardousChemicals/accessRecords/index.vue'),
-        name: 'accessRecords',
-        meta: { title: '取用记录',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/traceableQuery',
-    component: Layout,
-    redirect: '/traceableQuery',
-    children: [
-      {
-        path: '/traceableQuery',
-        component: () => import('@/views/hazardousChemicals/traceableQuery/index.vue'),
-        name: 'traceableQuery',
-        meta: { title: '溯源查询',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/overdueWarning',
-    component: Layout,
-    redirect: '/overdueWarning',
-    children: [
-      {
-        path: '/overdueWarning',
-        component: () => import('@/views/hazardousChemicals/overdueWarning/index.vue'),
-        name: 'overdueWarning',
-        meta: { title: '超期预警',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/avoidWarning',
-    component: Layout,
-    redirect: '/avoidWarning',
-    children: [
-      {
-        path: '/avoidWarning',
-        component: () => import('@/views/hazardousChemicals/avoidWarning/index.vue'),
-        name: 'avoidWarning',
-        meta: { title: '危化品相忌报警',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/useCount',
-    component: Layout,
-    redirect: '/useCount',
-    children: [
-      {
-        path: '/useCount',
-        component: () => import('@/views/hazardousChemicals/useCount/index.vue'),
-        name: 'useCount',
-        meta: { title: '用量统计',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/basicInfo',
-    component: Layout,
-    redirect: '/basicInfo',
-    children: [
-      {
-        path: '/basicInfo',
-        component: () => import('@/views/hazardousChemicals/basicInfon/index.vue'),
-        name: 'basicInfo',
-        meta: { title: '危化品基础信息',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/finishedBasicInfo',
-    component: Layout,
-    redirect: '/finishedBasicInfo',
-    children: [
-      {
-        path: '/finishedBasicInfo',
-        component: () => import('@/views/hazardousChemicals/finishedBasicInfo/index.vue'),
-        name: 'finishedBasicInfo',
-        meta: { title: '成品基础信息',icon: 'form',  affix: true }
-      }
-    ]
-  },
-  {
-    path: '/homePageIndex',
-    component: Layout,
-    redirect: '/homePageIndex',
-    meta: { title: '首页'},
-    children: [
-      {
-        path: 'homePageIndex',
-        component: () => import('@/views/hazardousChemicals/homePage/index.vue'),
-        name: 'homePageIndex',
-        meta: { title: '工作台',icon: 'form'}
-      },
-    ]
-  },
-  {
-    path: '/systemManage',
-    component: Layout,
-    redirect: '/systemManage/warehouse',
-    meta: { title: '系统管理'},
-    children: [
-      {
-        path: 'warehouse',
-        component: () => import('@/views/hazardousChemicals/systemManage/warehouse/index.vue'),
-        name: 'warehouse',
-        meta: { title: '仓库管理',icon: 'form'}
-      },
-      {
-        path: 'company',
-        component: () => import('@/views/hazardousChemicals/systemManage/company/index.vue'),
-        name: 'company',
-        meta: { title: '企业管理',icon: 'form'}
-      },
-      {
-        path: 'user',
-        component: () => import('@/views/hazardousChemicals/systemManage/user/index.vue'),
-        name: 'user',
-        meta: { title: '企业用户管理',icon: 'form'}
-      },
-      {
-        path: 'department',
-        component: () => import('@/views/hazardousChemicals/systemManage/department/index.vue'),
-        name: 'department',
-        meta: { title: '部门管理',icon: 'form'}
-      },
-      {
-        path: 'config',
-        component: () => import('@/views/hazardousChemicals/systemManage/config/index.vue'),
-        name: 'config',
-        meta: { title: '企业配置',icon: 'form'}
-      },
-      {
-        path: 'characteristic',
-        component: () => import('@/views/hazardousChemicals/systemManage/characteristic/index.vue'),
-        name: 'characteristic',
-        meta: { title: '危化品特性管理',icon: 'form'}
-      },
-      {
-        path: 'classifyInfoTable',
-        component: () => import('@/views/hazardousChemicals/systemManage/classifyInfoTable/index.vue'),
-        name: 'classifyInfoTable',
-        meta: { title: '危化品分类信息表',icon: 'form'}
-      },
-
-    ]
-  },
-
 ]
 
 // 动态路由,基于用户权限动态去加载
@@ -389,3 +561,4 @@
 });
 
 export default router;
+
diff --git a/src/store/modules/dict.js b/src/store/modules/dict.js
index 27fc308..6b18f9c 100644
--- a/src/store/modules/dict.js
+++ b/src/store/modules/dict.js
@@ -1,57 +1,57 @@
 const useDictStore = defineStore(
-  'dict',
-  {
-    state: () => ({
-      dict: new Array()
-    }),
-    actions: {
-      // 获取字典
-      getDict(_key) {
-        if (_key == null && _key == "") {
-          return null;
-        }
-        try {
-          for (let i = 0; i < this.dict.length; i++) {
-            if (this.dict[i].key == _key) {
-              return this.dict[i].value;
-            }
+    'dict',
+    {
+      state: () => ({
+        dict: new Array()
+      }),
+      actions: {
+        // 获取字典
+        getDict(_key) {
+          if (_key == null && _key == "") {
+            return null;
           }
-        } catch (e) {
-          return null;
-        }
-      },
-      // 设置字典
-      setDict(_key, value) {
-        if (_key !== null && _key !== "") {
-          this.dict.push({
-            key: _key,
-            value: value
-          });
-        }
-      },
-      // 删除字典
-      removeDict(_key) {
-        var bln = false;
-        try {
-          for (let i = 0; i < this.dict.length; i++) {
-            if (this.dict[i].key == _key) {
-              this.dict.splice(i, 1);
-              return true;
+          try {
+            for (let i = 0; i < this.dict.length; i++) {
+              if (this.dict[i].key == _key) {
+                return this.dict[i].value;
+              }
             }
+          } catch (e) {
+            return null;
           }
-        } catch (e) {
-          bln = false;
+        },
+        // 设置字典
+        setDict(_key, value) {
+          if (_key !== null && _key !== "") {
+            this.dict.push({
+              key: _key,
+              value: value
+            });
+          }
+        },
+        // 删除字典
+        removeDict(_key) {
+          var bln = false;
+          try {
+            for (let i = 0; i < this.dict.length; i++) {
+              if (this.dict[i].key == _key) {
+                this.dict.splice(i, 1);
+                return true;
+              }
+            }
+          } catch (e) {
+            bln = false;
+          }
+          return bln;
+        },
+        // 清空字典
+        cleanDict() {
+          this.dict = new Array();
+        },
+        // 初始字典
+        initDict() {
         }
-        return bln;
-      },
-      // 清空字典
-      cleanDict() {
-        this.dict = new Array();
-      },
-      // 初始字典
-      initDict() {
       }
-    }
-  })
+    })
 
 export default useDictStore
diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js
index 958fe63..b53a0f0 100644
--- a/src/store/modules/permission.js
+++ b/src/store/modules/permission.js
@@ -32,6 +32,9 @@
       setSidebarRouters(routes) {
         this.sidebarRouters = routes
       },
+      setIndexPages(routes) {
+        this.indexPage = routes
+      },
       generateRoutes(roles) {
         return new Promise(resolve => {
           // 向后端请求路由数据
@@ -39,15 +42,40 @@
             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
+            // }
+            if (res.data && res.data.length > 0 && res.data[0]) {
+              const firstMenu = res.data[0];
+              // 2. 判断第一个菜单是否有子菜单
+              if (firstMenu.children && firstMenu.children.length > 0) {
+                // 有子菜单,按原来的逻辑拼接
+                if (firstMenu.path === '/') {
+                  firstPage = firstMenu.path + firstMenu.children[0].path;
+                } else {
+                  firstPage = firstMenu.path + '/' + firstMenu.children[0].path;
+                }
+              } else {
+                firstPage = firstMenu.path;
+              }
+            } else {
+              firstPage = '/index';
+            }
             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)
           })
         })
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 7fdf5a5..af5ac68 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -23,9 +23,8 @@
         const password = userInfo.password
         const code = userInfo.code
         const uuid = userInfo.uuid
-        const identity = userInfo.identity
         return new Promise( (resolve, reject) => {
-          login(username, password, code, uuid, identity).then( async res => {
+          login(username, password, code, uuid).then( async res => {
             setToken(res.data.token)
             if(res.data && res.data.id){
               const info = await getUserById(res.data.id);
@@ -42,6 +41,8 @@
                 if(con.code === 200){
                   Cookies.set('configInfo',JSON.stringify(con.data))
                 }
+              }else {
+                Cookies.set('configInfo',null)
               }
             }
             this.token = res.data.token
@@ -55,12 +56,14 @@
       getInfo() {
         return new Promise((resolve, reject) => {
           getInfo().then(res => {
-            const user = res.user
+
+            const user = res.data.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
+            if (res.data.roles && res.data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
+              this.roles = res.data.roles
+              this.permissions = res.data.permissions
             } else {
               this.roles = ['ROLE_DEFAULT']
             }
diff --git a/src/utils/dict.js b/src/utils/dict.js
index 9648f14..d4d8429 100644
--- a/src/utils/dict.js
+++ b/src/utils/dict.js
@@ -21,4 +21,4 @@
     })
     return toRefs(res.value);
   })()
-}
\ No newline at end of file
+}
diff --git a/src/views/hazardousChemicals/accessRecords/components/productTable.vue b/src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/productTable.vue
similarity index 98%
rename from src/views/hazardousChemicals/accessRecords/components/productTable.vue
rename to src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/productTable.vue
index a019a37..d7c8aee 100644
--- a/src/views/hazardousChemicals/accessRecords/components/productTable.vue
+++ b/src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/productTable.vue
@@ -69,7 +69,7 @@
 <script setup>
 import {getCurrentInstance, nextTick, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
 import {ElMessage, ElMessageBox} from "element-plus";
-import flowDeail from '../../../components/flowDetail.vue'
+import flowDeail from '../../../../components/flowDetail.vue'
 import {delWarehouse, getWarehouse} from "@/api/hazardousChemicals/warehouse";
 import {
   delProductRecord,
diff --git a/src/views/hazardousChemicals/accessRecords/components/rawTable.vue b/src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/rawTable.vue
similarity index 98%
rename from src/views/hazardousChemicals/accessRecords/components/rawTable.vue
rename to src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/rawTable.vue
index d1cda31..78a212d 100644
--- a/src/views/hazardousChemicals/accessRecords/components/rawTable.vue
+++ b/src/views/hazardousChemicals/accessRecordsMenu/accessRecords/components/rawTable.vue
@@ -70,7 +70,7 @@
 <script setup>
 import {getCurrentInstance, nextTick, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
 import {ElMessage, ElMessageBox} from "element-plus";
-import flowDeail from '../../../components/flowDetail.vue'
+import flowDeail from '../../../../components/flowDetail.vue'
 const router = useRouter()
 const route = useRoute()
 import {
diff --git a/src/views/hazardousChemicals/accessRecords/index.vue b/src/views/hazardousChemicals/accessRecordsMenu/accessRecords/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/accessRecords/index.vue
rename to src/views/hazardousChemicals/accessRecordsMenu/accessRecords/index.vue
diff --git a/src/views/hazardousChemicals/avoidWarning/components/avoidDialog.vue b/src/views/hazardousChemicals/avoidWarningMenu/avoidWarning/components/avoidDialog.vue
similarity index 100%
rename from src/views/hazardousChemicals/avoidWarning/components/avoidDialog.vue
rename to src/views/hazardousChemicals/avoidWarningMenu/avoidWarning/components/avoidDialog.vue
diff --git a/src/views/hazardousChemicals/avoidWarning/index.vue b/src/views/hazardousChemicals/avoidWarningMenu/avoidWarning/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/avoidWarning/index.vue
rename to src/views/hazardousChemicals/avoidWarningMenu/avoidWarning/index.vue
diff --git a/src/views/hazardousChemicals/basicInfon/components/basicDialog.vue b/src/views/hazardousChemicals/basicInfonMenu/basicInfon/components/basicDialog.vue
similarity index 100%
rename from src/views/hazardousChemicals/basicInfon/components/basicDialog.vue
rename to src/views/hazardousChemicals/basicInfonMenu/basicInfon/components/basicDialog.vue
diff --git a/src/views/hazardousChemicals/basicInfon/index.vue b/src/views/hazardousChemicals/basicInfonMenu/basicInfon/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/basicInfon/index.vue
rename to src/views/hazardousChemicals/basicInfonMenu/basicInfon/index.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/components/proDetail.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/proDetail.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/components/proDetail.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/proDetail.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/components/proWarehouseRecord.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/proWarehouseRecord.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/components/proWarehouseRecord.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/proWarehouseRecord.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/components/productTable.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/productTable.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/components/productTable.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/productTable.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/components/rawDetail.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawDetail.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/components/rawDetail.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawDetail.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/components/rawTable.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawTable.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/components/rawTable.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawTable.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/components/rawWarehouseRecord.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawWarehouseRecord.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/components/rawWarehouseRecord.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/rawWarehouseRecord.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/components/viewQR.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/viewQR.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/components/viewQR.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/components/viewQR.vue
diff --git a/src/views/hazardousChemicals/electronicWarehouse/index.vue b/src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/electronicWarehouse/index.vue
rename to src/views/hazardousChemicals/electronicWarehouseMenu/electronicWarehouse/index.vue
diff --git a/src/views/hazardousChemicals/finishedBasicInfo/components/finishedBasicDialog.vue b/src/views/hazardousChemicals/finishedBasicInfoMenu/finishedBasicInfo/components/finishedBasicDialog.vue
similarity index 100%
rename from src/views/hazardousChemicals/finishedBasicInfo/components/finishedBasicDialog.vue
rename to src/views/hazardousChemicals/finishedBasicInfoMenu/finishedBasicInfo/components/finishedBasicDialog.vue
diff --git a/src/views/hazardousChemicals/finishedBasicInfo/index.vue b/src/views/hazardousChemicals/finishedBasicInfoMenu/finishedBasicInfo/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/finishedBasicInfo/index.vue
rename to src/views/hazardousChemicals/finishedBasicInfoMenu/finishedBasicInfo/index.vue
diff --git a/src/views/hazardousChemicals/homePage/index.vue b/src/views/hazardousChemicals/homePageMenu/homePage/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/homePage/index.vue
rename to src/views/hazardousChemicals/homePageMenu/homePage/index.vue
diff --git a/src/views/hazardousChemicals/overdueWarning/index.vue b/src/views/hazardousChemicals/overdueWarningMenu/overdueWarning/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/overdueWarning/index.vue
rename to src/views/hazardousChemicals/overdueWarningMenu/overdueWarning/index.vue
diff --git a/src/views/hazardousChemicals/subscribeApplyManage/approval/components/editDialog.vue b/src/views/hazardousChemicals/subscribeApplyManage/approval/components/editDialog.vue
new file mode 100644
index 0000000..83a8e54
--- /dev/null
+++ b/src/views/hazardousChemicals/subscribeApplyManage/approval/components/editDialog.vue
@@ -0,0 +1,238 @@
+<template>
+  <div class="notice">
+    <el-dialog
+        v-model="dialogVisible"
+        :title="title"
+        width="800px"
+        :before-close="handleClose"
+        :close-on-press-escape="false"
+        :close-on-click-modal="false"
+    >
+      <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" >
+        <el-form-item required label= "危化品列表" >
+          <div style="display: flex;width: 100%;margin-top: 5px">
+            <el-table :data="state.form.hazardousTargets" :border="true">
+              <el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
+              <el-table-column label="危化品名称" align="center"  >
+                <template #default="{row,$index}">
+                  <el-form-item :prop="'hazardousTargets.' + '[' + $index + ']' + '.name'" >
+                    <span>{{row.name}}</span>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="数量" align="center"  >
+                <template #default="{row,$index}">
+                  <el-form-item :prop="'hazardousTargets.' + '[' + $index + ']' + '.num'">
+                    <span>{{row.num}}</span>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" align="center" class-name="small-padding fixed-width" v-if="title !== '查看'" >
+                <template #default="scope" >
+                  <el-button link type="danger"  @click="handleDelete(scope.row)" >删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+            <el-button
+                v-if="title !== '查看'"
+                style="margin-left: 20px"
+                type="primary"
+                @click="addObject"
+            >新增</el-button>
+          </div>
+        </el-form-item>
+        <el-form-item label="申购文件:">
+          <div>
+            <el-link  type="primary" @click="openFile(state.form.filePath)">{{state.form.fileName}}</el-link>
+          </div>
+        </el-form-item>
+        <el-form-item label="审批意见:" v-if="title === '审批' && state.form.state == 0" >
+          <div style="display: flex;flex-direction: column;width: 70%">
+            <el-radio-group v-model="state.form.regestState">
+              <el-radio :label="0">通过</el-radio>
+              <el-radio :label="1">驳回</el-radio>
+            </el-radio-group>
+            <el-input v-if="state.form.regestState == 1" v-model="state.form.regest" type="textarea" :rows="5"></el-input>
+          </div>
+        </el-form-item>
+        <el-form-item label="审批状态:" v-if="title === '查看' && state.form.state != 0">
+          <span>{{state.form.state == 1 ? '审批通过' : '审批驳回' }}</span>
+        </el-form-item>
+        <el-form-item label="审批意见:" v-if="title === '查看' && state.form.state == 2" style="width: 70%">
+          <el-input v-model="state.form.regest" type="textarea" :rows="5"></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer v-if="title !=='查看'">
+        <span class="dialog-footer">
+            <el-button @click="handleClose" size="default">取 消</el-button>
+            <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus";
+import {addCompany, checkName, distributeCompany, editCompany} from "@/api/hazardousChemicals/company";
+import {verifyPhone, verifyPwd} from "@/utils/validate";
+import {getUser} from "@/api/hazardousChemicals/user";
+import {getToken} from "@/utils/auth";
+import {renderAsync} from "docx-preview";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const emit = defineEmits(["getList"]);
+const state = reactive({
+  form: {
+    id: '',
+    creditCode: '',
+    name: '',
+    major: '',
+    phone: '',
+    code: '',
+    hazardousTargets:[],
+  },
+  formRules:{
+    creditCode: [{ required: true, message: '请输入企业信用代码', trigger: 'blur' }],
+    major:[{ required: true, message: '请输入负责人', trigger: 'blur' }],
+    type: [{ required: true, message: '请选择企业类型', trigger: 'blur' }],
+  },
+
+  peopleList:[],
+  fileList:[],
+  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
+  header: {
+    Authorization: getToken()
+  },
+  fileLimit: 1,
+})
+
+
+const openDialog = async (type, value) => {
+  title.value = type === 'approval' ? '审批' : type ==='edit' ? '申购编辑' : '查看' ;
+  state.form = JSON.parse(JSON.stringify(value));
+  dialogVisible.value = true;
+}
+
+const onSubmit = async () => {
+  const valid = await busRef.value.validate();
+  if(valid){
+    if(title.value === '审批'){
+      const {id, ...data} = JSON.parse(JSON.stringify(state.form))
+      data.code = data.code.toUpperCase()
+      const res = await addCompany(data)
+      if(res.code === 200){
+        ElMessage({
+          type: 'success',
+          message: '新增成功'
+        });
+      }else{
+        ElMessage.warning(res.message)
+      }
+      emit("getList")
+      busRef.value.clearValidate();
+      reset();
+      dialogVisible.value = false;
+    }
+  }
+}
+
+const handleClose = () => {
+  busRef.value.clearValidate();
+  reset();
+  dialogVisible.value = false;
+  emit("getList")
+}
+const reset = () => {
+  state.form = {
+    id: '',
+    creditCode: '',
+    name: '',
+    major: '',
+    phone: '',
+    code: ''
+  }
+}
+const addObject = () => {
+
+  state.form.hazardousTargets.push({name:'',num:null})
+}
+const handleDelete = (val) => {
+  state.form.hazardousTargets = state.form.hazardousTargets.filter(item=> item != val)
+}
+const selectValue =  (val) => {
+  if(!val){
+    state.form.userId = null
+  }
+  state.peopleList.forEach(item => {
+    if(item.name === val){
+      state.form.userId  = item.id
+    }
+  })
+}
+
+
+const openFile = async(path)=>{
+  const ext = path.split('.').pop().toLowerCase();
+  if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+    ElMessageBox.confirm(`暂不支持线上预览.${ext}文件,是否下载查看?`, '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+      window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+    }).catch(() => {
+      console.log('取消预览')
+    });
+    return
+  }else if(ext === 'pdf' || ext === 'jpg'||  ext === 'jpeg' || ext === 'png' ){
+    window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+  }else{
+    try {
+      // 1. 获取文件
+      const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+      const arrayBuffer = await response.arrayBuffer();
+      // 2. 创建新窗口
+      const win = window.open('', '_blank');
+      win.document.write(`
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <title>预览</title>
+          <style>
+            body { margin: 20px; font-family: Arial; }
+            .docx-container { width: 100%; height: 100%; }
+          </style>
+        </head>
+        <body>
+          <div id="container" class="docx-container"></div>
+        </body>
+      </html>
+    `);
+      // 3. 渲染 DOCX
+      await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+    } catch (error) {
+      console.error('预览失败:', error);
+      alert(`预览失败: ${error.message}`);
+    }
+  }
+}
+defineExpose({
+  openDialog
+});
+
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+  :deep(.el-form .el-form-item__label) {
+    font-size: 15px;
+  }
+  .file {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
+}
+</style>
diff --git a/src/views/hazardousChemicals/subscribeApplyManage/approval/index.vue b/src/views/hazardousChemicals/subscribeApplyManage/approval/index.vue
new file mode 100644
index 0000000..f107b29
--- /dev/null
+++ b/src/views/hazardousChemicals/subscribeApplyManage/approval/index.vue
@@ -0,0 +1,262 @@
+<template>
+  <div class="app-container">
+    <div style="display: flex;justify-content: space-between">
+      <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+<!--        <el-form-item>-->
+<!--          <el-button-->
+<!--              type="primary"-->
+<!--              plain-->
+<!--              icon="Plus"-->
+<!--              @click="openDialog('add',{})"-->
+<!--          >新增</el-button>-->
+<!--        </el-form-item>-->
+        <el-form-item label="审批状态:" >
+          <el-select v-model="data.queryParams.state" placeholder="请选择" >
+            <el-option
+                v-for="item in data.stateOptions"
+                :key="item.id"
+                :label="item.value"
+                :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="审批人:" prop="userId" >
+          <el-select
+              clearable
+              v-model="data.userName"
+              filterable
+              remote
+              @change="selectValue"
+              reserve-keyword
+              placeholder="请输入审批人名称"
+              remote-show-suffix
+              :remote-method="getPeopleList"
+              style="width: 100%"
+          >
+            <el-option
+                v-for="item in data.peopleList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.name"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item >
+          <el-button
+              type="primary"
+              @click="getList"
+          >查询</el-button>
+          <el-button
+              type="primary"
+              plain
+              @click="reset"
+          >重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <!-- 表格数据 -->
+    <el-table v-loading="loading" :data="dataList" :border="true">
+      <el-table-column label="序号" type="index" align="center" width="80" />
+      <el-table-column label="申购单号" prop="creditCode" align="center"  />
+      <el-table-column label="危化品名称" prop="code" align="center" />
+      <el-table-column label="申购数量" prop="name" align="center" />
+      <el-table-column label="申购人" prop="major" align="center"  />
+      <el-table-column label="审批人" prop="phone" align="center"/>
+      <el-table-column label="申购文件" prop="phone" align="center">
+        <template #default="scope">
+          <el-link v-if="scope.row.fileName" style="" type="primary" @click="openFile(scope.row.filePath)">{{scope.row.fileName}}</el-link>
+        </template>
+      </el-table-column>
+      <el-table-column label="审批状态" prop="phone" align="center">
+        <template #default="scope">
+          <span> {{scope.row.state == 0 ? '未审批' :scope.row.state == 1 ?'审批通过':scope.row.state == 2 ?'审批驳回':''}}</span><span></span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200" >
+        <template #default="scope">
+          <el-button v-if="scope.row.state == 0" link type="primary" @click="openDialog('approval',scope.row)">审批</el-button>
+          <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <editDialog ref="dialogRef" @getList=getList></editDialog>
+  </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/hazardousChemicals/company";
+import editDialog from "./components/editDialog.vue";
+import {getUser} from "@/api/hazardousChemicals/user";
+import {renderAsync} from "docx-preview";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    state: null,
+    userId:null
+  },
+  total: 0,
+  dataList: [],
+  stateOptions:[
+    {
+      id: 0,
+      value: '未审批'
+    },
+    {
+      id: 1,
+      value: '审批通过'
+    },
+    {
+      id: 2,
+      value: '审批驳回'
+    },
+  ],
+  peopleList:[],
+  userName:''
+});
+
+const { queryParams, total, dataList } = toRefs(data);
+const classHourRef = ref();
+onMounted(()=>{
+  getList()
+  getPeopleList("")
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+  loading.value = true
+  // const res = await getCompany(data.queryParams)
+  // if(res.code == 200){
+  //   data.dataList = res.data.list
+  //   data.total = res.data.total
+  // }else{
+  //   ElMessage.warning(res.message)
+  // }
+  loading.value = false
+}
+
+const openDialog = (type, value) => {
+  dialogRef.value.openDialog(type, value);
+}
+
+/** 重置新增的表单以及其他数据  */
+function reset() {
+  data.queryParams = {
+    pageNum: 1,
+    pageSize: 10,
+    state: null,
+    userId:null
+  }
+  data.userName = ''
+  getList()
+  getPeopleList("")
+}
+const handleDelete = (val) => {
+  ElMessageBox.confirm(
+      '确定删除此条数据?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        const res = await delCompany(val.id)
+        if(res.code == 200){
+          ElMessage.success('数据删除成功')
+          await getList()
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+const getPeopleList = async (val)=>{
+  let queryParams = {}
+  if(val != ""){
+     queryParams = {
+      name: val
+    }
+  }else {
+     queryParams = {
+      pageNum: 1,
+      pageSize: 10
+    }
+  }
+  const res = await getUser(queryParams)
+  if (res.code == 200) {
+    data.peopleList = res.data.list
+  } else {
+    ElMessage.warning(res.message)
+  }
+}
+const selectValue =  (val) => {
+  if(!val){
+    data.queryParams.userId = null
+  }
+  data.peopleList.forEach(item => {
+    if(item.name === val){
+      data.queryParams.userId = item.id
+    }
+  })
+}
+const openFile = async(path)=>{
+  const ext = path.split('.').pop().toLowerCase();
+  if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+    ElMessageBox.confirm(`暂不支持线上预览.${ext}文件,是否下载查看?`, '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+      window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+    }).catch(() => {
+      console.log('取消预览')
+    });
+    return
+  }else if(ext === 'pdf' || ext === 'jpg'||  ext === 'jpeg' || ext === 'png' ){
+    window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+  }else{
+    try {
+      // 1. 获取文件
+      const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+      const arrayBuffer = await response.arrayBuffer();
+      // 2. 创建新窗口
+      const win = window.open('', '_blank');
+      win.document.write(`
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <title>预览</title>
+          <style>
+            body { margin: 20px; font-family: Arial; }
+            .docx-container { width: 100%; height: 100%; }
+          </style>
+        </head>
+        <body>
+          <div id="container" class="docx-container"></div>
+        </body>
+      </html>
+    `);
+      // 3. 渲染 DOCX
+      await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+    } catch (error) {
+      console.error('预览失败:', error);
+      alert(`预览失败: ${error.message}`);
+    }
+  }
+}
+
+</script>
diff --git a/src/views/hazardousChemicals/subscribeApplyManage/record/components/editDialog.vue b/src/views/hazardousChemicals/subscribeApplyManage/record/components/editDialog.vue
new file mode 100644
index 0000000..c439bd3
--- /dev/null
+++ b/src/views/hazardousChemicals/subscribeApplyManage/record/components/editDialog.vue
@@ -0,0 +1,201 @@
+<template>
+  <div class="notice">
+    <el-dialog
+        v-model="dialogVisible"
+        :title="title"
+        width="800px"
+        :before-close="handleClose"
+        :close-on-press-escape="false"
+        :close-on-click-modal="false"
+    >
+      <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" >
+        <el-form-item required label= "危化品列表" >
+          <div style="display: flex;width: 100%;margin-top: 5px">
+            <el-table :data="state.form.hazardousTargets" :border="true">
+              <el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
+              <el-table-column label="危化品名称" align="center"  >
+                <template #default="{row,$index}">
+                  <el-form-item :prop="'hazardousTargets.' + '[' + $index + ']' + '.name'" >
+                    <span>{{row.name}}</span>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="数量" align="center"  >
+                <template #default="{row,$index}">
+                  <el-form-item :prop="'hazardousTargets.' + '[' + $index + ']' + '.num'">
+                    <span>{{row.num}}</span>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" align="center" class-name="small-padding fixed-width" v-if="title !== '查看'" >
+                <template #default="scope" >
+                  <el-button link type="danger"  @click="handleDelete(scope.row)" >删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+            <el-button
+                v-if="title !== '查看'"
+                style="margin-left: 20px"
+                type="primary"
+                @click="addObject"
+            >新增</el-button>
+          </div>
+        </el-form-item>
+        <el-form-item label="申购文件:">
+          <div>
+            <el-link  type="primary" @click="openFile(state.form.filePath)">{{state.form.fileName}}</el-link>
+          </div>
+        </el-form-item>
+        <el-form-item label="申购人:" >
+          <span>{{state.form.people }}</span>
+        </el-form-item>
+        <el-form-item label="审批人:" >
+          <span>{{state.form.people }}</span>
+        </el-form-item>
+        <el-form-item label="审批状态:" v-if="title === '查看' ">
+          <span>{{state.form.state == 1 ? '审批通过' : state.form.state == 2 ?'审批驳回': '未审批' }}</span>
+        </el-form-item>
+        <el-form-item label="审批意见:" v-if="title === '查看' && state.form.state == 2" style="width: 70%">
+          <el-input v-model="state.form.regest" type="textarea" :rows="5"></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer v-if="title !=='查看'">
+        <span class="dialog-footer">
+            <el-button @click="handleClose" size="default">取 消</el-button>
+            <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus";
+import {addCompany, checkName, distributeCompany, editCompany} from "@/api/hazardousChemicals/company";
+import {verifyPhone, verifyPwd} from "@/utils/validate";
+import {getUser} from "@/api/hazardousChemicals/user";
+import {getToken} from "@/utils/auth";
+import {renderAsync} from "docx-preview";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const emit = defineEmits(["getList"]);
+const state = reactive({
+  form: {
+    id: '',
+    creditCode: '',
+    name: '',
+    major: '',
+    phone: '',
+    code: '',
+    hazardousTargets:[],
+  },
+})
+
+
+const openDialog = async (type, value) => {
+  title.value = type === 'approval' ? '审批' : type ==='edit' ? '申购编辑' : '查看' ;
+  state.form = JSON.parse(JSON.stringify(value));
+  dialogVisible.value = true;
+}
+
+
+
+const handleClose = () => {
+  busRef.value.clearValidate();
+  reset();
+  dialogVisible.value = false;
+  emit("getList")
+}
+const reset = () => {
+  state.form = {
+    id: '',
+    creditCode: '',
+    name: '',
+    major: '',
+    phone: '',
+    code: ''
+  }
+}
+const addObject = () => {
+
+  state.form.hazardousTargets.push({name:'',num:null})
+}
+const handleDelete = (val) => {
+  state.form.hazardousTargets = state.form.hazardousTargets.filter(item=> item != val)
+}
+const selectValue =  (val) => {
+  if(!val){
+    state.form.userId = null
+  }
+  state.peopleList.forEach(item => {
+    if(item.name === val){
+      state.form.userId  = item.id
+    }
+  })
+}
+
+
+const openFile = async(path)=>{
+  const ext = path.split('.').pop().toLowerCase();
+  if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+    ElMessageBox.confirm(`暂不支持线上预览.${ext}文件,是否下载查看?`, '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+      window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+    }).catch(() => {
+      console.log('取消预览')
+    });
+    return
+  }else if(ext === 'pdf' || ext === 'jpg'||  ext === 'jpeg' || ext === 'png' ){
+    window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+  }else{
+    try {
+      // 1. 获取文件
+      const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+      const arrayBuffer = await response.arrayBuffer();
+      // 2. 创建新窗口
+      const win = window.open('', '_blank');
+      win.document.write(`
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <title>预览</title>
+          <style>
+            body { margin: 20px; font-family: Arial; }
+            .docx-container { width: 100%; height: 100%; }
+          </style>
+        </head>
+        <body>
+          <div id="container" class="docx-container"></div>
+        </body>
+      </html>
+    `);
+      // 3. 渲染 DOCX
+      await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+    } catch (error) {
+      console.error('预览失败:', error);
+      alert(`预览失败: ${error.message}`);
+    }
+  }
+}
+defineExpose({
+  openDialog
+});
+
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+  :deep(.el-form .el-form-item__label) {
+    font-size: 15px;
+  }
+  .file {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
+}
+</style>
diff --git a/src/views/hazardousChemicals/subscribeApplyManage/record/index.vue b/src/views/hazardousChemicals/subscribeApplyManage/record/index.vue
new file mode 100644
index 0000000..15f27ae
--- /dev/null
+++ b/src/views/hazardousChemicals/subscribeApplyManage/record/index.vue
@@ -0,0 +1,266 @@
+<template>
+  <div class="app-container">
+    <div style="display: flex;justify-content: space-between">
+      <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+<!--        <el-form-item>-->
+<!--          <el-button-->
+<!--              type="primary"-->
+<!--              plain-->
+<!--              icon="Plus"-->
+<!--              @click="openDialog('add',{})"-->
+<!--          >新增</el-button>-->
+<!--        </el-form-item>-->
+        <el-form-item label="审批状态:" >
+          <el-select v-model="data.queryParams.state" placeholder="请选择" >
+            <el-option
+                v-for="item in data.stateOptions"
+                :key="item.id"
+                :label="item.value"
+                :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="审批人:" prop="userId" >
+          <el-select
+              clearable
+              v-model="data.userName"
+              filterable
+              remote
+              @change="selectValue"
+              reserve-keyword
+              placeholder="请输入审批人名称"
+              remote-show-suffix
+              :remote-method="getPeopleList"
+              style="width: 100%"
+          >
+            <el-option
+                v-for="item in data.peopleList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.name"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item >
+          <el-button
+              type="primary"
+              @click="getList"
+          >查询</el-button>
+          <el-button
+              type="primary"
+              plain
+              @click="reset"
+          >重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <!-- 表格数据 -->
+    <el-table v-loading="loading" :data="dataList" :border="true">
+      <el-table-column label="序号" type="index" align="center" width="80" />
+      <el-table-column label="申购单号" prop="creditCode" align="center"  />
+      <el-table-column label="危化品名称" prop="code" align="center" />
+      <el-table-column label="申购数量" prop="name" align="center" />
+      <el-table-column label="申购人" prop="major" align="center"  />
+      <el-table-column label="审批人" prop="phone" align="center"/>
+      <el-table-column label="申购文件" prop="phone" align="center">
+        <template #default="scope">
+          <el-link v-if="scope.row.fileName" style="" type="primary" @click="openFile(scope.row.filePath)">{{scope.row.fileName}}</el-link>
+        </template>
+      </el-table-column>
+      <el-table-column label="审批状态" prop="phone" align="center">
+        <template #default="scope">
+          <span> {{scope.row.state == 0 ? '未审批' :scope.row.state == 1 ?'审批通过':scope.row.state == 2 ?'审批驳回':''}}</span><span></span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200" >
+        <template #default="scope">
+          <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <editDialog ref="dialogRef" @getList=getList></editDialog>
+  </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/hazardousChemicals/company";
+import editDialog from "./components/editDialog.vue";
+import {getUser} from "@/api/hazardousChemicals/user";
+import {renderAsync} from "docx-preview";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    state: null,
+    userId:null
+  },
+  total: 0,
+  dataList: [
+    {
+      id:1,
+      state:2
+    }
+  ],
+  stateOptions:[
+    {
+      id: 0,
+      value: '未审批'
+    },
+    {
+      id: 1,
+      value: '审批通过'
+    },
+    {
+      id: 2,
+      value: '审批驳回'
+    },
+  ],
+  peopleList:[],
+  userName:''
+});
+
+const { queryParams, total, dataList } = toRefs(data);
+const classHourRef = ref();
+onMounted(()=>{
+  getList()
+  getPeopleList("")
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+  loading.value = true
+  // const res = await getCompany(data.queryParams)
+  // if(res.code == 200){
+  //   data.dataList = res.data.list
+  //   data.total = res.data.total
+  // }else{
+  //   ElMessage.warning(res.message)
+  // }
+  loading.value = false
+}
+
+const openDialog = (type, value) => {
+  dialogRef.value.openDialog(type, value);
+}
+
+/** 重置新增的表单以及其他数据  */
+function reset() {
+  data.queryParams = {
+    pageNum: 1,
+    pageSize: 10,
+    state: null,
+    userId:null
+  }
+  data.userName = ''
+  getList()
+  getPeopleList("")
+}
+const handleDelete = (val) => {
+  ElMessageBox.confirm(
+      '确定删除此条数据?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        const res = await delCompany(val.id)
+        if(res.code == 200){
+          ElMessage.success('数据删除成功')
+          await getList()
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+const getPeopleList = async (val)=>{
+  let queryParams = {}
+  if(val != ""){
+     queryParams = {
+      name: val
+    }
+  }else {
+     queryParams = {
+      pageNum: 1,
+      pageSize: 10
+    }
+  }
+  const res = await getUser(queryParams)
+  if (res.code == 200) {
+    data.peopleList = res.data.list
+  } else {
+    ElMessage.warning(res.message)
+  }
+}
+const selectValue =  (val) => {
+  if(!val){
+    data.queryParams.userId = null
+  }
+  data.peopleList.forEach(item => {
+    if(item.name === val){
+      data.queryParams.userId = item.id
+    }
+  })
+}
+const openFile = async(path)=>{
+  const ext = path.split('.').pop().toLowerCase();
+  if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+    ElMessageBox.confirm(`暂不支持线上预览.${ext}文件,是否下载查看?`, '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+      window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+    }).catch(() => {
+      console.log('取消预览')
+    });
+    return
+  }else if(ext === 'pdf' || ext === 'jpg'||  ext === 'jpeg' || ext === 'png' ){
+    window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+  }else{
+    try {
+      // 1. 获取文件
+      const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+      const arrayBuffer = await response.arrayBuffer();
+      // 2. 创建新窗口
+      const win = window.open('', '_blank');
+      win.document.write(`
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <title>预览</title>
+          <style>
+            body { margin: 20px; font-family: Arial; }
+            .docx-container { width: 100%; height: 100%; }
+          </style>
+        </head>
+        <body>
+          <div id="container" class="docx-container"></div>
+        </body>
+      </html>
+    `);
+      // 3. 渲染 DOCX
+      await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+    } catch (error) {
+      console.error('预览失败:', error);
+      alert(`预览失败: ${error.message}`);
+    }
+  }
+}
+
+</script>
diff --git a/src/views/hazardousChemicals/subscribeApplyManage/subscribe/components/editDialog.vue b/src/views/hazardousChemicals/subscribeApplyManage/subscribe/components/editDialog.vue
new file mode 100644
index 0000000..0ec353e
--- /dev/null
+++ b/src/views/hazardousChemicals/subscribeApplyManage/subscribe/components/editDialog.vue
@@ -0,0 +1,335 @@
+<template>
+  <div class="notice">
+    <el-dialog
+        v-model="dialogVisible"
+        :title="title"
+        width="800px"
+        :before-close="handleClose"
+        :close-on-press-escape="false"
+        :close-on-click-modal="false"
+    >
+      <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" >
+        <el-form-item required label= "危化品列表" >
+          <div style="display: flex;width: 100%;margin-top: 5px">
+            <el-table :data="state.form.hazardousTargets" :border="true">
+              <el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
+              <el-table-column label="危化品名称" align="center"  >
+                <template #default="{row,$index}">
+                  <el-form-item :prop="'hazardousTargets.' + '[' + $index + ']' + '.name'" :rules="state.formRules.name">
+                    <el-input :disabled="title === '查看'" type="textarea" v-model="row.name" placeholder="请输入危化品名称"></el-input>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="数量" align="center"  >
+                <template #default="{row,$index}">
+                  <el-form-item :prop="'hazardousTargets.' + '[' + $index + ']' + '.num'" :rules="state.formRules.num">
+                    <el-input :disabled="title === '查看'"  v-model="row.num" @input="row.num = row.num.replace(/[^0-9]/g,'')" placeholder="请输入数量"></el-input>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" align="center" class-name="small-padding fixed-width" v-if="title !== '查看'" >
+                <template #default="scope" >
+                  <el-button link type="danger"  @click="handleDelete(scope.row)" >删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+            <el-button
+                v-if="title !== '查看'"
+                style="margin-left: 20px"
+                type="primary"
+                @click="addObject"
+            >新增</el-button>
+          </div>
+        </el-form-item>
+        <el-form-item label="审批人:" prop="userId" >
+          <el-select
+              clearable
+              v-model="state.userName"
+              filterable
+              remote
+              @change="selectValue"
+              reserve-keyword
+              placeholder="请输入审批人名称"
+              remote-show-suffix
+              :remote-method="getPeopleList"
+              style="width: 50%"
+          >
+            <el-option
+                v-for="item in state.peopleList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.name"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="申购文件:">
+          <el-upload accept=".doc,.docx,.xls,.xlsx" v-if="title!=='查看'" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file)=>handleRemove(file)" >
+            <el-button type="primary">点击上传</el-button>
+            <template #tip>
+              <div class="el-upload__tip">支持上传.doc、.docx、.xls、.xlsx格式文档,尺寸小于50M,最多可上传1张</div>
+            </template>
+          </el-upload>
+          <div v-else>
+            <el-link v-if="state.form.fileName" style="" type="primary" @click="openFile(state.form.filePath)">{{state.form.fileName}}</el-link>
+          </div>
+        </el-form-item>
+        <el-form-item label="审批意见:" v-if="title === '查看' && state.form.state == 2" style="width: 70%">
+          <el-input v-model="state.form.regest" type="textarea" :rows="2"></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer v-if="title !=='查看'">
+        <span class="dialog-footer">
+            <el-button @click="handleClose" size="default">取 消</el-button>
+            <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus";
+import {addCompany, checkName, distributeCompany, editCompany} from "@/api/hazardousChemicals/company";
+import {verifyPhone, verifyPwd} from "@/utils/validate";
+import {getUser} from "@/api/hazardousChemicals/user";
+import {getToken} from "@/utils/auth";
+import {renderAsync} from "docx-preview";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const emit = defineEmits(["getList"]);
+const state = reactive({
+  form: {
+    id: '',
+    creditCode: '',
+    name: '',
+    major: '',
+    phone: '',
+    code: '',
+    hazardousTargets:[],
+  },
+  formRules:{
+    creditCode: [{ required: true, message: '请输入企业信用代码', trigger: 'blur' }],
+    major:[{ required: true, message: '请输入负责人', trigger: 'blur' }],
+    type: [{ required: true, message: '请选择企业类型', trigger: 'blur' }],
+    name: [{ required: true, message: '', trigger: 'blur' }],
+    num: [{ required: true, message: '', trigger: 'blur' }],
+  },
+
+  peopleList:[],
+  fileList:[],
+  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
+  header: {
+    Authorization: getToken()
+  },
+  fileLimit: 1,
+})
+
+
+const openDialog = async (type, value) => {
+  await getPeopleList("")
+  title.value = type === 'add' ? '申购申请' : type ==='edit' ? '申购编辑' : '查看' ;
+  if(type === 'edit') {
+    state.form = JSON.parse(JSON.stringify(value));
+  }
+  dialogVisible.value = true;
+}
+
+const onSubmit = async () => {
+  const valid = await busRef.value.validate();
+  if(valid){
+    if(title.value === '新增'){
+      const {id, ...data} = JSON.parse(JSON.stringify(state.form))
+      data.code = data.code.toUpperCase()
+      const res = await addCompany(data)
+      if(res.code === 200){
+        ElMessage({
+          type: 'success',
+          message: '新增成功'
+        });
+      }else{
+        ElMessage.warning(res.message)
+      }
+      emit("getList")
+      busRef.value.clearValidate();
+      reset();
+      dialogVisible.value = false;
+    }else if(title.value === '编辑'){
+      const {...data} = JSON.parse(JSON.stringify(state.form))
+      data.code = data.code.toUpperCase()
+      const res = await editCompany(data)
+      if(res.code === 200){
+        ElMessage({
+          type: 'success',
+          message: '编辑成功'
+        });
+      }else{
+        ElMessage.warning(res.message)
+      }
+      emit("getList")
+      busRef.value.clearValidate();
+      reset();
+      dialogVisible.value = false;
+    }
+  }
+}
+
+const handleClose = () => {
+  busRef.value.clearValidate();
+  reset();
+  dialogVisible.value = false;
+  emit("getList")
+}
+const reset = () => {
+  state.form = {
+    id: '',
+    creditCode: '',
+    name: '',
+    major: '',
+    phone: '',
+    code: ''
+  }
+}
+const requiredDurationEventMetering =(value) =>{
+  let dat =
+      ("" + value)
+          .replace(/[^\d^\.]+/g, "")
+          .replace(/^0+(\d)/, "$1")
+          .replace(/^\./, "0.")
+          .match(/^\d*(\.?\d{0,2})/g)[0] || "";
+  return dat
+}
+const addObject = () => {
+
+  state.form.hazardousTargets.push({name:'',num:null})
+}
+const handleDelete = (val) => {
+  state.form.hazardousTargets = state.form.hazardousTargets.filter(item=> item != val)
+}
+const selectValue =  (val) => {
+  if(!val){
+    state.form.userId = null
+  }
+  state.peopleList.forEach(item => {
+    if(item.name === val){
+      state.form.userId  = item.id
+    }
+  })
+}
+const getPeopleList = async (val)=>{
+  let queryParams = {}
+  if(val != ""){
+    queryParams = {
+      name: val
+    }
+  }else {
+    queryParams = {
+      pageNum: 1,
+      pageSize: 10
+    }
+  }
+  const res = await getUser(queryParams)
+  if (res.code == 200) {
+    state.peopleList = res.data.list
+  } else {
+    ElMessage.warning(res.message)
+  }
+}
+const handleAvatarSuccess = (res, uploadFile) => {
+  if(res.code == 200){
+    state.form.fileName = res.data.originName
+    state.form.filePath = res.data.path
+    state.form.format = '.' + res.data.filename.split('.')[1]
+  }else{
+    state.fileList = []
+    ElMessage({
+      type: 'warning',
+      message: '文件上传失败'
+    })
+  }
+}
+
+const showTip =()=>{
+  ElMessage({
+    type: 'warning',
+    message: '超出文件上传数量'
+  });
+}
+const picSize = async (rawFile) => {
+  if(rawFile.size / 1024 / 1024 > 50){
+    ElMessage({
+      type: 'warning',
+      message: '文件大小不能超过50M'
+    });
+    return false
+  }
+};
+const handleRemove = async (file) => {
+  const index = state.fileList.indexOf(file)
+  const newFileList = state.fileList.slice()
+  newFileList.splice(index, 1)
+  state.fileList = newFileList;
+}
+const openFile = async(path)=>{
+  const ext = path.split('.').pop().toLowerCase();
+  if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+    ElMessageBox.confirm(`暂不支持线上预览.${ext}文件,是否下载查看?`, '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+      window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+    }).catch(() => {
+      console.log('取消预览')
+    });
+    return
+  }else if(ext === 'pdf' || ext === 'jpg'||  ext === 'jpeg' || ext === 'png' ){
+    window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+  }else{
+    try {
+      // 1. 获取文件
+      const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+      const arrayBuffer = await response.arrayBuffer();
+      // 2. 创建新窗口
+      const win = window.open('', '_blank');
+      win.document.write(`
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <title>预览</title>
+          <style>
+            body { margin: 20px; font-family: Arial; }
+            .docx-container { width: 100%; height: 100%; }
+          </style>
+        </head>
+        <body>
+          <div id="container" class="docx-container"></div>
+        </body>
+      </html>
+    `);
+      // 3. 渲染 DOCX
+      await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+    } catch (error) {
+      console.error('预览失败:', error);
+      alert(`预览失败: ${error.message}`);
+    }
+  }
+}
+defineExpose({
+  openDialog
+});
+
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+  :deep(.el-form .el-form-item__label) {
+    font-size: 15px;
+  }
+  .file {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
+}
+</style>
diff --git a/src/views/hazardousChemicals/subscribeApplyManage/subscribe/index.vue b/src/views/hazardousChemicals/subscribeApplyManage/subscribe/index.vue
new file mode 100644
index 0000000..8539ec7
--- /dev/null
+++ b/src/views/hazardousChemicals/subscribeApplyManage/subscribe/index.vue
@@ -0,0 +1,263 @@
+<template>
+  <div class="app-container">
+    <div style="display: flex;justify-content: space-between">
+      <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+        <el-form-item>
+          <el-button
+              type="primary"
+              plain
+              icon="Plus"
+              @click="openDialog('add',{})"
+          >新增</el-button>
+        </el-form-item>
+        <el-form-item label="审批状态:" >
+          <el-select v-model="data.queryParams.state" placeholder="请选择" >
+            <el-option
+                v-for="item in data.stateOptions"
+                :key="item.id"
+                :label="item.value"
+                :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="审批人:" prop="userId" >
+          <el-select
+              clearable
+              v-model="data.userName"
+              filterable
+              remote
+              @change="selectValue"
+              reserve-keyword
+              placeholder="请输入审批人名称"
+              remote-show-suffix
+              :remote-method="getPeopleList"
+              style="width: 100%"
+          >
+            <el-option
+                v-for="item in data.peopleList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.name"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item >
+          <el-button
+              type="primary"
+              @click="getList"
+          >查询</el-button>
+          <el-button
+              type="primary"
+              plain
+              @click="reset"
+          >重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <!-- 表格数据 -->
+    <el-table v-loading="loading" :data="dataList" :border="true">
+      <el-table-column label="序号" type="index" align="center" width="80" />
+      <el-table-column label="申购单号" prop="creditCode" align="center"  />
+      <el-table-column label="危化品名称" prop="code" align="center" />
+      <el-table-column label="申购数量" prop="name" align="center" />
+      <el-table-column label="申购人" prop="major" align="center"  />
+      <el-table-column label="审批人" prop="phone" align="center"/>
+      <el-table-column label="申购文件" prop="phone" align="center">
+        <template #default="scope">
+          <el-link v-if="scope.row.fileName" style="" type="primary" @click="openFile(scope.row.filePath)">{{scope.row.fileName}}</el-link>
+        </template>
+      </el-table-column>
+      <el-table-column label="审批状态" prop="phone" align="center">
+        <template #default="scope">
+          <span> {{scope.row.state == 0 ? '未审批' :scope.row.state == 1 ?'审批通过':scope.row.state == 2 ?'审批驳回':''}}</span><span></span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200" >
+        <template #default="scope">
+          <el-button v-if="scope.row.state == 0" link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+          <el-button v-if="scope.row.state == 0" link type="danger" @click="handleDelete(scope.row)">删除</el-button>
+          <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <editDialog ref="dialogRef" @getList=getList></editDialog>
+  </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/hazardousChemicals/company";
+import editDialog from "./components/editDialog.vue";
+import {getUser} from "@/api/hazardousChemicals/user";
+import {renderAsync} from "docx-preview";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    state: null,
+    userId:null
+  },
+  total: 0,
+  dataList: [],
+  stateOptions:[
+    {
+      id: 0,
+      value: '未审批'
+    },
+    {
+      id: 1,
+      value: '审批通过'
+    },
+    {
+      id: 2,
+      value: '审批驳回'
+    },
+  ],
+  peopleList:[],
+  userName:''
+});
+
+const { queryParams, total, dataList } = toRefs(data);
+const classHourRef = ref();
+onMounted(()=>{
+  getList()
+  getPeopleList("")
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+  loading.value = true
+  // const res = await getCompany(data.queryParams)
+  // if(res.code == 200){
+  //   data.dataList = res.data.list
+  //   data.total = res.data.total
+  // }else{
+  //   ElMessage.warning(res.message)
+  // }
+  loading.value = false
+}
+
+const openDialog = (type, value) => {
+  dialogRef.value.openDialog(type, value);
+}
+
+/** 重置新增的表单以及其他数据  */
+function reset() {
+  data.queryParams = {
+    pageNum: 1,
+    pageSize: 10,
+    state: null,
+    userId:null
+  }
+  data.userName = ''
+  getList()
+  getPeopleList("")
+}
+const handleDelete = (val) => {
+  ElMessageBox.confirm(
+      '确定删除此条数据?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        const res = await delCompany(val.id)
+        if(res.code == 200){
+          ElMessage.success('数据删除成功')
+          await getList()
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+const getPeopleList = async (val)=>{
+  let queryParams = {}
+  if(val != ""){
+     queryParams = {
+      name: val
+    }
+  }else {
+     queryParams = {
+      pageNum: 1,
+      pageSize: 10
+    }
+  }
+  const res = await getUser(queryParams)
+  if (res.code == 200) {
+    data.peopleList = res.data.list
+  } else {
+    ElMessage.warning(res.message)
+  }
+}
+const selectValue =  (val) => {
+  if(!val){
+    data.queryParams.userId = null
+  }
+  data.peopleList.forEach(item => {
+    if(item.name === val){
+      data.queryParams.userId = item.id
+    }
+  })
+}
+const openFile = async(path)=>{
+  const ext = path.split('.').pop().toLowerCase();
+  if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+    ElMessageBox.confirm(`暂不支持线上预览.${ext}文件,是否下载查看?`, '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+      window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+    }).catch(() => {
+      console.log('取消预览')
+    });
+    return
+  }else if(ext === 'pdf' || ext === 'jpg'||  ext === 'jpeg' || ext === 'png' ){
+    window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+  }else{
+    try {
+      // 1. 获取文件
+      const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+      const arrayBuffer = await response.arrayBuffer();
+      // 2. 创建新窗口
+      const win = window.open('', '_blank');
+      win.document.write(`
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <title>预览</title>
+          <style>
+            body { margin: 20px; font-family: Arial; }
+            .docx-container { width: 100%; height: 100%; }
+          </style>
+        </head>
+        <body>
+          <div id="container" class="docx-container"></div>
+        </body>
+      </html>
+    `);
+      // 3. 渲染 DOCX
+      await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+    } catch (error) {
+      console.error('预览失败:', error);
+      alert(`预览失败: ${error.message}`);
+    }
+  }
+}
+
+</script>
diff --git a/src/views/hazardousChemicals/systemManage/config/components/mapLocation.vue b/src/views/hazardousChemicals/systemManage/config/components/mapLocation.vue
index 115c24a..795fdfe 100644
--- a/src/views/hazardousChemicals/systemManage/config/components/mapLocation.vue
+++ b/src/views/hazardousChemicals/systemManage/config/components/mapLocation.vue
@@ -25,14 +25,14 @@
         <span>纬度:</span>
         <el-input class="mapLocation_latlng_input" id="lat" v-model.trim="state.latitude" @change="getAdress"></el-input>
       </div>
-      <div class="mapLocation_latlng">
-        <span>地址:</span>
-        <el-input class="mapLocation_latlng_input" id="lat" v-model.trim="state.BAddress"></el-input>
-      </div>
+<!--      <div class="mapLocation_latlng">-->
+<!--        <span>地址:</span>-->
+<!--        <el-input class="mapLocation_latlng_input" id="lat" v-model.trim="state.BAddress"></el-input>-->
+<!--      </div>-->
 
     </div>
     <div class="mapLocation_body">
-      <baidu-map class="map"  @ready="getAdress" ak="BkZdiHBj9aGrMdVFM48r2njNiMzsekga" v="3.0" type="API" :center="state.center" :zoom="state.zoom" scroll-wheel-zoom  @click="getPosition">
+      <baidu-map class="map"  @ready="getAdress" ak="oF71jf1ELX29VmdqXBBNveZ7DevpqsuI" v="3.0" type="API" :center="state.center" :zoom="state.zoom" scroll-wheel-zoom  @click="getPosition">
 <!--        <div style="position: absolute;z-index: 999;margin-top: -495px">-->
 <!--          <label>搜索:<input v-model="state.keyword"></label>-->
 <!--          <bm-local-search-->
@@ -116,13 +116,13 @@
 }
 const myGeo = ref(null)
 const getAdress = () => {
-  myGeo.value = new BMap.Geocoder();
-  const pt = new BMap.Point(state.longitude, state.latitude);
-  myGeo.value.getLocation(pt,function(result){
-        state.BAddress = result.address; //获取到当前定位的详细地址信息
-      },
-      { enableHighAccuracy: true }
-  );
+  // myGeo.value = new BMap.Geocoder();
+  // const pt = new BMap.Point(state.longitude, state.latitude);
+  // myGeo.value.getLocation(pt,function(result){
+  //       state.BAddress = result.address; //获取到当前定位的详细地址信息
+  //     },
+  //     { enableHighAccuracy: true }
+  // );
 }
 const handleClose = () => {
   state.longitude = ''
diff --git a/src/views/hazardousChemicals/traceableQuery/index.vue b/src/views/hazardousChemicals/traceableQueryMenu/traceableQuery/index.vue
similarity index 96%
rename from src/views/hazardousChemicals/traceableQuery/index.vue
rename to src/views/hazardousChemicals/traceableQueryMenu/traceableQuery/index.vue
index 5210f24..3f56a5b 100644
--- a/src/views/hazardousChemicals/traceableQuery/index.vue
+++ b/src/views/hazardousChemicals/traceableQueryMenu/traceableQuery/index.vue
@@ -30,7 +30,7 @@
 </template>
 <script setup>
 import {nextTick, reactive, ref} from "vue";
-import flowDeail from '../../components/flowDetail.vue'
+import flowDeail from '../../../components/flowDetail.vue'
 import {getFlowByCode, getProFlow} from "@/api/hazardousChemicals/productRecord";
 import {ElMessage} from "element-plus";
 
diff --git a/src/views/hazardousChemicals/useCount/index.vue b/src/views/hazardousChemicals/useCountMenu/useCount/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/useCount/index.vue
rename to src/views/hazardousChemicals/useCountMenu/useCount/index.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/addProDialog.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/addProDialog.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/addProDialog.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/addProDialog.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/addRawDialog.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/addRawDialog.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/addRawDialog.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/addRawDialog.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/printCode.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/printCode.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/printCode.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/printCode.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/printCodeMore.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/printCodeMore.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/printCodeMore.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/printCodeMore.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/proDetail.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/proDetail.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/proDetail.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/proDetail.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/productTable.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/productTable.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/productTable.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/productTable.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/rawDetail.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/rawDetail.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/rawDetail.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/rawDetail.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/components/rawTable.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/rawTable.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/components/rawTable.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/components/rawTable.vue
diff --git a/src/views/hazardousChemicals/warehouseManage/index.vue b/src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/index.vue
similarity index 100%
rename from src/views/hazardousChemicals/warehouseManage/index.vue
rename to src/views/hazardousChemicals/warehouseManageMenu/warehouseManage/index.vue
diff --git a/src/views/homePage.vue b/src/views/homePage.vue
index f136db4..caebf23 100644
--- a/src/views/homePage.vue
+++ b/src/views/homePage.vue
@@ -218,6 +218,108 @@
 }, { immediate: true });
 
 const sidebarRouters = ref([])
+// function handleLogin() {
+//   proxy.$refs.loginRef.validate(valid => {
+//     if (valid) {
+//       loading.value = true;
+//       // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
+//       // if (loginForm.value.rememberMe) {
+//       Cookies.set("username", loginForm.value.username, { expires: 30 });
+//       Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
+//       //   Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
+//       // } else {
+//       // 否则移除
+//       //   Cookies.remove("username");
+//       //   Cookies.remove("password");
+//       //   Cookies.remove("rememberMe");
+//       // }
+//       // 调用action的登录方法
+//       // loginForm.value.password = Base64.encode(loginForm.value.password)
+//       const param = {
+//         username: loginForm.value.username,
+//         password: Base64.encode(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) {
+//         //   sidebarRouters.value =  menu.agencyMenu
+//         //   Cookies.set('routers',JSON.stringify(sidebarRouters.value))
+//         // }
+//         const userInfo = JSON.parse(Cookies.get('userInfo'))
+//
+//         if(userInfo.userType === 0) {
+//           sidebarRouters.value =  menu.adminMenu
+//           Cookies.set('routers',JSON.stringify(sidebarRouters.value))
+//         }else if(userInfo.userType === 1){
+//           const config = JSON.parse(Cookies.get('configInfo'))
+//           if(config){
+//             if(config.useProd === 0){
+//               sidebarRouters.value =  menu.companyMenu.filter(item => item.path != '/finishedBasicInfo')
+//             }else {
+//               sidebarRouters.value =  menu.companyMenu
+//
+//             }
+//           }else {
+//             ElMessage.warning('请联系管理员完善企业配置')
+//             sidebarRouters.value =  menu.companyMenu
+//           }
+//           Cookies.set('routers',JSON.stringify(sidebarRouters.value))
+//         }else if(userInfo.userType === 2){
+//           const config = JSON.parse(Cookies.get('configInfo'))
+//           if(config){
+//             if(config.useProd === 0){
+//               sidebarRouters.value =  menu.commonMenu.filter(item => item.path != '/finishedBasicInfo')
+//             }else {
+//               sidebarRouters.value =  menu.commonMenu
+//             }
+//           }else {
+//             // ElMessage.warning('请联系管理员完善企业配置')
+//             sidebarRouters.value =  menu.commonMenu
+//           }
+//           Cookies.set('routers',JSON.stringify(sidebarRouters.value))
+//         }else {
+//           ElMessage.warning('监管部门账号不可登录')
+//           loading.value = false
+//           return
+//         }
+//         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 });
+//       }).catch(() => {
+//         loading.value = false;
+//         // 重新获取验证码
+//         if (captchaEnabled.value) {
+//           getCode();
+//         }
+//       });
+//     }
+//   });
+// }
+
 function handleLogin() {
   proxy.$refs.loginRef.validate(valid => {
     if (valid) {
@@ -225,7 +327,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 {
       // 否则移除
@@ -240,75 +343,16 @@
         password: Base64.encode(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) {
-        //   sidebarRouters.value =  menu.agencyMenu
-        //   Cookies.set('routers',JSON.stringify(sidebarRouters.value))
-        // }
-        const userInfo = JSON.parse(Cookies.get('userInfo'))
-
-        if(userInfo.userType === 0) {
-          sidebarRouters.value =  menu.adminMenu
-          Cookies.set('routers',JSON.stringify(sidebarRouters.value))
-        }else if(userInfo.userType === 1){
-          const config = JSON.parse(Cookies.get('configInfo'))
-          if(config){
-            if(config.useProd === 0){
-              sidebarRouters.value =  menu.companyMenu.filter(item => item.path != '/finishedBasicInfo')
-            }else {
-              sidebarRouters.value =  menu.companyMenu
-
-            }
-          }else {
-            ElMessage.warning('请联系管理员完善企业配置')
-            sidebarRouters.value =  menu.companyMenu
+        const query = route.query;
+        const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
+          if (cur !== "redirect") {
+            acc[cur] = query[cur];
           }
-          Cookies.set('routers',JSON.stringify(sidebarRouters.value))
-        }else if(userInfo.userType === 2){
-          const config = JSON.parse(Cookies.get('configInfo'))
-          if(config){
-            if(config.useProd === 0){
-              sidebarRouters.value =  menu.commonMenu.filter(item => item.path != '/finishedBasicInfo')
-            }else {
-              sidebarRouters.value =  menu.commonMenu
-            }
-          }else {
-            // ElMessage.warning('请联系管理员完善企业配置')
-            sidebarRouters.value =  menu.commonMenu
-          }
-          Cookies.set('routers',JSON.stringify(sidebarRouters.value))
-        }else {
-          ElMessage.warning('监管部门账号不可登录')
-          loading.value = false
-          return
-        }
-        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;
         // 重新获取验证码
@@ -319,7 +363,6 @@
     }
   });
 }
-
 function getCode() {
   getCodeImg().then(res => {
     // captchaEnabled.value = res.data.captchaEnabled
diff --git a/src/views/index.vue b/src/views/index.vue
new file mode 100644
index 0000000..4b78d8e
--- /dev/null
+++ b/src/views/index.vue
@@ -0,0 +1,101 @@
+<template>
+  <div class="app-container">
+    <div style="margin: 150px 100px;color: #3173ea" class="login-img">
+      <div >
+        <div style="font-size:50px">欢迎进入</div>
+        <div style="font-size: 35px;margin-top: 20px">危化品全生命周期管理系统</div>
+      </div>
+
+    </div>
+  </div>
+</template>
+
+<script setup name="Index">
+const version = ref('3.8.6')
+
+function goTarget(url) {
+  window.open(url, '__blank')
+}
+</script>
+
+<style scoped lang="scss">
+
+.login-img{
+  //display: flex;
+  //justify-content: center;
+  //align-items: center;
+  font-family: 'AliMa';
+  color: #fff;
+  font-size: 3.2rem;
+  //text-align: center;
+  //line-height: 1.5;
+  //transform: translateY(-80px);
+  text-shadow: -10px 10px 20px rgba(0,0,0,.4);
+}
+.home {
+  font-size: 35px;
+  font-weight: 600;
+  text-align: center;
+  margin-top: 10%;
+  blockquote {
+
+    padding: 10px 20px;
+    margin: 0 0 20px;
+    //font-size: 17.5px;
+    border-left: 5px solid #eee;
+  }
+  hr {
+    margin-top: 20px;
+    margin-bottom: 20px;
+    border: 0;
+    border-top: 1px solid #eee;
+  }
+  .col-item {
+    margin-bottom: 20px;
+  }
+
+  ul {
+    padding: 0;
+    margin: 0;
+  }
+
+  font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+  color: #676a6c;
+  overflow-x: hidden;
+
+  ul {
+    list-style-type: none;
+  }
+
+  h4 {
+    margin-top: 0px;
+  }
+
+  h2 {
+    margin-top: 10px;
+    font-size: 26px;
+    font-weight: 100;
+  }
+
+  p {
+    margin-top: 10px;
+
+    b {
+      font-weight: 700;
+    }
+  }
+
+  .update-log {
+    ol {
+      display: block;
+      list-style-type: decimal;
+      margin-block-start: 1em;
+      margin-block-end: 1em;
+      margin-inline-start: 0;
+      margin-inline-end: 0;
+      padding-inline-start: 40px;
+    }
+  }
+}
+</style>
+
diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue
index f9b108a..4a904b1 100644
--- a/src/views/system/menu/index.vue
+++ b/src/views/system/menu/index.vue
@@ -37,7 +37,7 @@
             >新增</el-button>
          </el-col>
          <el-col :span="1.5">
-            <el-button 
+            <el-button
                type="info"
                plain
                icon="Sort"
diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue
index 66b5f5e..313cc8a 100644
--- a/src/views/system/role/authUser.vue
+++ b/src/views/system/role/authUser.vue
@@ -2,18 +2,18 @@
 <template>
    <div class="app-container">
       <el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true">
-         <el-form-item label="用户名称" prop="userName">
+         <el-form-item label="用户名称" prop="username">
             <el-input
-               v-model="queryParams.userName"
+               v-model="queryParams.username"
                placeholder="请输入用户名称"
                clearable
                style="width: 240px"
                @keyup.enter="handleQuery"
             />
          </el-form-item>
-         <el-form-item label="手机号码" prop="phonenumber">
+         <el-form-item label="手机号码" prop="phone">
             <el-input
-               v-model="queryParams.phonenumber"
+               v-model="queryParams.phone"
                placeholder="请输入手机号码"
                clearable
                style="width: 240px"
@@ -47,9 +47,9 @@
             >批量取消授权</el-button>
          </el-col>
          <el-col :span="1.5">
-            <el-button 
-               type="warning" 
-               plain 
+            <el-button
+               type="warning"
+               plain
                icon="Close"
                @click="handleClose"
             >关闭</el-button>
@@ -59,20 +59,24 @@
 
       <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" align="center" />
-         <el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" />
-         <el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" />
-         <el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" />
-         <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
-         <el-table-column label="状态" align="center" prop="status">
-            <template #default="scope">
-               <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-            </template>
-         </el-table-column>
-         <el-table-column label="创建时间" align="center" prop="createTime" width="180">
-            <template #default="scope">
-               <span>{{ parseTime(scope.row.createTime) }}</span>
-            </template>
-         </el-table-column>
+        <el-table-column label="用户名称" prop="username" :show-overflow-tooltip="true" />
+        <el-table-column label="姓名" prop="name" align="center"  />
+        <el-table-column label="性别" prop="sex" align="center">
+          <template #default="scope">
+            <span>{{scope.row.sex == 0 ?'男':'女'}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="手机" prop="phone" :show-overflow-tooltip="true" />
+        <el-table-column label="用户类型" prop="userType" align="center">
+          <template #default="scope">
+            <span>{{scope.row.userType == 0 ?'管理员':scope.row.userType == 1 ? '企业用户':scope.row.userType ==2 ? '普通用户' : '监管用户'}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="状态" align="center" prop="status">
+          <template #default="scope">
+            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+          </template>
+        </el-table-column>
          <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
             <template #default="scope">
                <el-button link type="primary" icon="CircleClose" @click="cancelAuthUser(scope.row)" v-hasPermi="['system:role:remove']">取消授权</el-button>
@@ -110,16 +114,16 @@
   pageNum: 1,
   pageSize: 10,
   roleId: route.params.roleId,
-  userName: undefined,
-  phonenumber: undefined,
+  username: undefined,
+  phone: undefined,
 });
 
 /** 查询授权用户列表 */
 function getList() {
   loading.value = true;
   allocatedUserList(queryParams).then(response => {
-    userList.value = response.rows;
-    total.value = response.total;
+    userList.value = response.data.list;
+    total.value = response.data.total;
     loading.value = false;
   });
 }
@@ -140,7 +144,7 @@
 }
 // 多选框选中数据
 function handleSelectionChange(selection) {
-  userIds.value = selection.map(item => item.userId);
+  userIds.value = selection.map(item => item.id);
   multiple.value = !selection.length;
 }
 /** 打开授权用户表弹窗 */
@@ -149,8 +153,8 @@
 }
 /** 取消授权按钮操作 */
 function cancelAuthUser(row) {
-  proxy.$modal.confirm('确认要取消该用户"' + row.userName + '"角色吗?').then(function () {
-    return authUserCancel({ userId: row.userId, roleId: queryParams.roleId });
+  proxy.$modal.confirm('确认要取消该用户"' + row.username + '"角色吗?').then(function () {
+    return authUserCancel({ userId: row.id, roleId: queryParams.roleId });
   }).then(() => {
     getList();
     proxy.$modal.msgSuccess("取消授权成功");
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
index 65c8216..b7d6b64 100644
--- a/src/views/system/role/index.vue
+++ b/src/views/system/role/index.vue
@@ -121,9 +121,9 @@
               <el-tooltip content="删除" placement="top" v-if="scope.row.roleId !== 1">
                 <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']"></el-button>
               </el-tooltip>
-              <el-tooltip content="数据权限" placement="top" v-if="scope.row.roleId !== 1">
-                <el-button link type="primary" icon="CircleCheck" @click="handleDataScope(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
-              </el-tooltip>
+<!--              <el-tooltip content="数据权限" placement="top" v-if="scope.row.roleId !== 1">-->
+<!--                <el-button link type="primary" icon="CircleCheck" @click="handleDataScope(scope.row)" v-hasPermi="['system:role:edit']"></el-button>-->
+<!--              </el-tooltip>-->
               <el-tooltip content="分配用户" placement="top" v-if="scope.row.roleId !== 1">
                 <el-button link type="primary" icon="User" @click="handleAuthUser(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
               </el-tooltip>
@@ -300,8 +300,8 @@
 function getList() {
   loading.value = true;
   listRole(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
-    roleList.value = response.rows;
-    total.value = response.total;
+    roleList.value = response.data.list;
+    total.value = response.data.total;
     loading.value = false;
   });
 }
@@ -422,7 +422,7 @@
     open.value = true;
     nextTick(() => {
       roleMenu.then((res) => {
-        let checkedKeys = res.checkedKeys;
+        let checkedKeys = res.data.checkedKeys;
         checkedKeys.forEach((v) => {
           nextTick(() => {
             menuRef.value.setChecked(v, true, false);
@@ -436,7 +436,7 @@
 /** 根据角色ID查询菜单树结构 */
 function getRoleMenuTreeselect(roleId) {
   return roleMenuTreeselect(roleId).then(response => {
-    menuOptions.value = response.menus;
+    menuOptions.value = response.data.menus;
     return response;
   });
 }
diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue
index 9be1ec9..b64033c 100644
--- a/src/views/system/role/selectUser.vue
+++ b/src/views/system/role/selectUser.vue
@@ -2,18 +2,18 @@
    <!-- 授权用户 -->
    <el-dialog title="选择用户" v-model="visible" width="800px" top="5vh" append-to-body>
       <el-form :model="queryParams" ref="queryRef" :inline="true">
-         <el-form-item label="用户名称" prop="userName">
+         <el-form-item label="用户名称" prop="username">
             <el-input
-               v-model="queryParams.userName"
+               v-model="queryParams.username"
                placeholder="请输入用户名称"
                clearable
                style="width: 200px"
                @keyup.enter="handleQuery"
             />
          </el-form-item>
-         <el-form-item label="手机号码" prop="phonenumber">
+         <el-form-item label="手机号码" prop="phone">
             <el-input
-               v-model="queryParams.phonenumber"
+               v-model="queryParams.phone"
                placeholder="请输入手机号码"
                clearable
                style="width: 200px"
@@ -28,18 +28,22 @@
       <el-row>
          <el-table @row-click="clickRow" ref="refTable" :data="userList" @selection-change="handleSelectionChange" height="260px">
             <el-table-column type="selection" width="55"></el-table-column>
-            <el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" />
-            <el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" />
-            <el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" />
-            <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
+            <el-table-column label="用户名称" prop="username" :show-overflow-tooltip="true" />
+           <el-table-column label="姓名" prop="name" align="center"  />
+           <el-table-column label="性别" prop="sex" align="center">
+             <template #default="scope">
+               <span>{{scope.row.sex == 0 ?'男':'女'}}</span>
+             </template>
+           </el-table-column>
+           <el-table-column label="手机" prop="phone" :show-overflow-tooltip="true" />
+           <el-table-column label="用户类型" prop="userType" align="center">
+             <template #default="scope">
+               <span>{{scope.row.userType == 0 ?'管理员':scope.row.userType == 1 ? '企业用户':scope.row.userType ==2 ? '普通用户' : '监管用户'}}</span>
+             </template>
+           </el-table-column>
             <el-table-column label="状态" align="center" prop="status">
                <template #default="scope">
                   <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-               </template>
-            </el-table-column>
-            <el-table-column label="创建时间" align="center" prop="createTime" width="180">
-               <template #default="scope">
-                  <span>{{ parseTime(scope.row.createTime) }}</span>
                </template>
             </el-table-column>
          </el-table>
@@ -81,8 +85,8 @@
   pageNum: 1,
   pageSize: 10,
   roleId: undefined,
-  userName: undefined,
-  phonenumber: undefined
+  username: undefined,
+  phone: undefined
 });
 
 // 显示弹框
@@ -97,13 +101,13 @@
 }
 // 多选框选中数据
 function handleSelectionChange(selection) {
-  userIds.value = selection.map(item => item.userId);
+  userIds.value = selection.map(item => item.id);
 }
 // 查询表数据
 function getList() {
   unallocatedUserList(queryParams).then(res => {
-    userList.value = res.rows;
-    total.value = res.total;
+    userList.value = res.data.list;
+    total.value = res.data.total;
   });
 }
 /** 搜索按钮操作 */
@@ -126,7 +130,7 @@
     return;
   }
   authUserSelectAll({ roleId: roleId, userIds: uIds }).then(res => {
-    proxy.$modal.msgSuccess(res.msg);
+    proxy.$modal.msgSuccess('分配成功');
     if (res.code === 200) {
       visible.value = false;
       emit("ok");

--
Gitblit v1.9.2