liujiejie 1 年間 前
コミット
7122653424

ファイルの差分が大きいため隠しています
+ 14176 - 1
package-lock.json


+ 2 - 1
package.json

@@ -15,7 +15,8 @@
     "svg-sprite-loader": "^6.0.11",
     "vue": "^2.6.14",
     "vue-router": "^3.5.1",
-    "vuex": "^3.6.2"
+    "vuex": "^3.6.2",
+    "vuex-persistedstate": "^4.1.0"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~5.0.0",

+ 15 - 14
src/App.vue

@@ -4,8 +4,9 @@
   </div>
 </template>
 <script>
-import { login } from '@/api/login'
-import { testApi } from '@/api/test'
+import { login } from "@/api/login";
+import { testApi } from "@/api/test";
+import axios from "axios";
 export default {
   created() {
     // this.test('2122')
@@ -15,23 +16,23 @@ export default {
     // 调取后端api方法
     addLog() {
       const data = {
-        userName: '测试1',
-        password: '1111'
-      }
-      login(data).then((res) => {})
+        userName: "测试1",
+        password: "1111",
+      };
+      login(data).then((res) => {});
     },
     // 调取后端api方法
     test(id) {
       const data = {
-        userName: '测试2',
-        password: '1111'
-      }
+        userName: "测试2",
+        password: "1111",
+      };
       testApi(data, id).then((res) => {
-        console.log(res)
-      })
-    }
-  }
-}
+        console.log(res);
+      });
+    },
+  },
+};
 </script>
 <style lang="scss">
 body {

+ 7 - 7
src/api/login.js

@@ -1,9 +1,9 @@
-import request from '@/utils/request'
+import request from "@/utils/request";
 
-export function login (data) {
+export function login(data) {
   return request({
-    url: '/login',
-    method: 'post',
-    data
-  })
-}
+    url: "/energy-manage-service/sysuserinfo/open/userLogin",
+    method: "post",
+    data,
+  });
+}

+ 33 - 33
src/router/index.js

@@ -1,62 +1,62 @@
-import Vue from 'vue'
-import VueRouter from 'vue-router'
-import Home from '../views/home/Index.vue'
+import Vue from "vue";
+import VueRouter from "vue-router";
+import Home from "../views/home/Index.vue";
 
-Vue.use(VueRouter)
+Vue.use(VueRouter);
 
 const routes = [
   {
-    path: '/',
-    redirect: '/login'
+    path: "/",
+    redirect: "/login",
   },
   {
-    path: '/home',
-    redirect: '/home/cockpitManage',
-    name: 'home',
+    path: "/home",
+    redirect: "/home/cockpitManage",
+    name: "home",
     component: Home,
     children: [
       // 驾驶舱
       {
-        path: 'cockpitManage',
-        name: 'cockpitManage',
-        component: () => import('../views/admin/cockpitManage/Index.vue')
+        path: "cockpitManage",
+        name: "cockpitManage",
+        component: () => import("../views/admin/cockpitManage/Index.vue"),
       },
       // 电子地图
       {
-        path: 'electronic-map',
-        name: 'electronicMap',
+        path: "electronic-map",
+        name: "electronicMap",
         component: () =>
-          import('../views/admin/cockpitManage/electronicMap.vue')
-      }
-    ]
+          import("../views/admin/cockpitManage/electronicMap.vue"),
+      },
+    ],
   },
   {
-    path: '/login',
-    name: 'login',
-    component: () => import('../views/login/Index.vue')
+    path: "/login",
+    name: "login",
+    component: () => import("../views/login/Index.vue"),
   },
 
   {
-    path: '/:pathMatch(.*)*',
-    component: () => import('@/views/error/404.vue'),
-    meta: { hidden: true }
-  }
+    path: "/:pathMatch(.*)*",
+    component: () => import("@/views/error/404.vue"),
+    meta: { hidden: true },
+  },
   // {
   //   path: '*',
   //   redirect: '/'
   // }
-]
+];
 
 const router = new VueRouter({
-  mode: 'history',
+  mode: "history",
   base: process.env.BASE_URL,
   scrollBehavior: () => ({
-    y: 0
+    y: 0,
   }),
-  routes
-})
-const originalPush = VueRouter.prototype.push
+  routes,
+});
+const originalPush = VueRouter.prototype.push;
 VueRouter.prototype.push = function push(location) {
-  return originalPush.call(this, location).catch((err) => err)
-}
-export default router
+  return originalPush.call(this, location).catch((err) => err);
+};
+export default router;

+ 38 - 0
src/store/auth.js

@@ -0,0 +1,38 @@
+/*
+ * @Author: your name
+ * @Date: 2024-05-17 14:57:38
+ * @LastEditTime: 2024-05-17 16:21:14
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /dasheng/performance-test/src/store/auth.js
+ */
+import { login } from "../api/login";
+import routerInit from "../router/index";
+import { getAuthRouterFn } from "@/utils/getAuth";
+export default {
+  namespaced: true, //子模块一定要开启命名空间
+  state: {
+    userInfo: {},
+  },
+  getters: {},
+  mutations: {
+    SET_USERINFO(state, payload) {
+      state.userInfo = payload;
+    },
+  },
+  actions: {
+    async goLogin({ commit, dispatch }, obj) {
+      try {
+        const result = await login(obj);
+        commit("SET_USERINFO", result.data);
+        dispatch("setAddRouter", result.data.permission);
+      } catch (error) {
+        console.error("Login error:", error);
+      }
+    },
+    setAddRouter({ commit, dispatch }, router) {
+      console.log(router, "router");
+      getAuthRouterFn(router);
+    },
+  },
+};

+ 17 - 9
src/store/index.js

@@ -1,7 +1,9 @@
-import Vuex from 'vuex'
-import Vue from 'vue'
-import breadStore from './breadStore.js' //引入子模块
-Vue.use(Vuex)
+import Vuex from "vuex";
+import Vue from "vue";
+import breadStore from "./breadStore.js"; //引入子模块
+import auth from "./auth.js";
+import createPersistedState from "vuex-persistedstate";
+Vue.use(Vuex);
 export const store = new Vuex.Store({
   state: {
     // 存放共有store下子模块数据
@@ -11,8 +13,8 @@ export const store = new Vuex.Store({
     // state的计算属性,监听state的变化时对state里的数据进行加工
     //如果其他组件都需要相同的函数,就可以把函数写到这里面
     getterPrice(state) {
-      return (state.price += 100)
-    }
+      return (state.price += 100);
+    },
     //调用this.$store.getters.getterPrice
   },
   mutations: {
@@ -25,6 +27,12 @@ export const store = new Vuex.Store({
   //然后在每一个module中写state, getters, mutations, actions等(注意在子模块中需要开启命名空间)。
   modules: {
     //面包屑模块
-    breadStore
-  }
-})
+    breadStore,
+    auth,
+  },
+  plugins: [
+    createPersistedState({
+      storage: window.sessionStorage, // 或者 localStorage
+    }),
+  ],
+});

+ 61 - 0
src/utils/getAuth.js

@@ -0,0 +1,61 @@
+/*
+ * @Author: your name
+ * @Date: 2024-05-17 16:09:03
+ * @LastEditTime: 2024-05-17 17:45:31
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/utils/getAuth.js
+ */
+import { orgList } from "@/views/home/components/mockData";
+//返回可动态添加的路由
+export const getAuthRouterFn = (list) => {
+  console.log(list, orgList, "权限路由 前后端");
+  // 将list 转成一维数组,按钮级别权限拿到 返回为[]格式
+  const { result, anthBtnList } = flattenTree(list);
+  const arr = filterTreeByPermissions(result, orgList);
+  console.log(arr, "routes");
+};
+
+const flattenTree = (tree) => {
+  let result = [];
+  let anthBtnList = [];
+  const flattenRecursive = (nodes) => {
+    nodes.forEach((node) => {
+      result.push(node);
+      if (node.children && node.children.length > 0) {
+        flattenRecursive(node.children);
+      }
+      if (node.permissionDepth === 2) {
+        anthBtnList.push(node);
+      }
+    });
+  };
+
+  flattenRecursive(tree);
+  return { result, anthBtnList };
+};
+const filterTreeByPermissions = (permissions, tree) => {
+  // 将 permissions 转换成一个 Set 以便于快速查找
+  const permissionSet = new Set(permissions.map((item) => item.permissionName));
+
+  const filterTreeRecursive = (nodes) => {
+    const filteredNodes = [];
+
+    nodes.forEach((node) => {
+      // 检查当前节点是否在权限列表中
+      if (permissionSet.has(node.name)) {
+        // 创建一个新的节点对象,避免修改原始树
+        const newNode = { ...node };
+        // 如果节点有子节点,则递归过滤子节点
+        if (node.children && node.children.length > 0) {
+          newNode.children = filterTreeRecursive(node.children);
+        }
+        filteredNodes.push(newNode);
+      }
+    });
+
+    return filteredNodes;
+  };
+
+  return filterTreeRecursive(tree);
+};

+ 45 - 44
src/utils/request.js

@@ -1,10 +1,10 @@
-import axios from 'axios'
-import { Message } from 'element-ui'
-console.log(window)
+import axios from "axios";
+import { Message } from "element-ui";
+console.log(window?._BASE_CONFIG?.API, "window?._BASE_CONFIG?.API");
 const service = axios.create({
-  baseURL: window?._BASE_CONFIG?.API || '/api',
-  withCredentials: true
-})
+  baseURL: window?._BASE_CONFIG?.API || "/api",
+  withCredentials: true,
+});
 
 /**
  * 请求拦截器
@@ -12,12 +12,12 @@ const service = axios.create({
  */
 service.interceptors.request.use(
   (config) => {
-    return config
+    return config;
   },
   (error) => {
-    return Promise.reject(error)
+    return Promise.reject(error);
   }
-)
+);
 
 /**
  * 响应拦截器
@@ -26,61 +26,62 @@ service.interceptors.request.use(
  */
 service.interceptors.response.use(
   async (response) => {
-    const { data } = response
+    const { data } = response;
     if (data?.code) {
-      if (data.code !== '0000') {
+      console.log(data?.code, "data?.code");
+      if (data.code !== 200) {
         Message({
-          message: data.msg || 'Error',
-          type: 'error',
-          duration: 5 * 1000
-        })
-        return Promise.reject(new Error(data.msg || 'Error'))
+          message: data.msg || "Error",
+          type: "error",
+          duration: 5 * 1000,
+        });
+        return Promise.reject(new Error(data.msg || "Error"));
       } else {
-        return data
+        return data;
       }
-    } else if (data.type === 'application/octet-stream') {
-      return response
-    } else if (data.type === 'application/json') {
-      const resData = JSON.parse(await data.text())
-      console.log(resData)
+    } else if (data.type === "application/octet-stream") {
+      return response;
+    } else if (data.type === "application/json") {
+      const resData = JSON.parse(await data.text());
+      console.log(resData);
       // 根据后端返回code码进行处理
-      if (resData.code !== '0000') {
+      if (resData.code !== 200) {
         Message({
-          message: resData.msg || 'Error',
-          type: 'error',
-          duration: 5 * 1000
-        })
-        return Promise.reject(new Error(resData.msg || 'Error'))
+          message: resData.msg || "Error",
+          type: "error",
+          duration: 5 * 1000,
+        });
+        return Promise.reject(new Error(resData.msg || "Error"));
       } else {
-        return resData
+        return resData;
       }
     }
   },
   (error) => {
-    const { response } = error
+    const { response } = error;
     if (response?.status === 401) {
-      window.location = response.data
-      return
+      window.location = response.data;
+      return;
     }
     Message({
       message: error.message,
-      type: 'error',
-      duration: 5 * 1000
-    })
-    return Promise.reject(error)
+      type: "error",
+      duration: 5 * 1000,
+    });
+    return Promise.reject(error);
   }
-)
+);
 
 const request = (requestObj) => {
-  const { url, method, data = {}, timeout, params, responseType } = requestObj
+  const { url, method, data = {}, timeout, params, responseType } = requestObj;
   return service({
     url,
-    method: method || 'post',
+    method: method || "post",
     data,
     timeout: timeout || 300000,
-    params: params || (method && method.toLowerCase() === 'get' ? data : {}),
-    responseType: responseType || 'json'
-  })
-}
+    params: params || (method && method.toLowerCase() === "get" ? data : {}),
+    responseType: responseType || "json",
+  });
+};
 
-export default request
+export default request;

+ 51 - 38
src/views/home/components/mockData.js

@@ -1,90 +1,103 @@
 export const orgList = [
   {
-    name: '驾驶舱',
+    name: "驾驶舱",
     id: "1",
-    path: 'cockpitManage',
-    iconName: 'gps',
+    path: "cockpitManage",
+    iconName: "gps",
+    component: () => import("@/views/admin/cockpitManage/Index.vue"),
     children: [
       {
         id: 11,
-        name: '电子地图',
-        path: 'electronic-map'
-      }
-    ]
+        name: "电子地图",
+        path: "electronic-map",
+        component: () =>
+          import("@/views/admin/cockpitManage/electronicMap.vue"),
+      },
+    ],
   },
   {
-    name: '性能分析',
+    name: "性能分析",
     id: "2",
-    iconName: 'analyse',
+    iconName: "analyse",
+    component: () =>
+      import("@/views/admin/performanceAnalysisManage/Index.vue"),
     children: [
       {
         id: 21,
-        name: '新能分析评估'
+        name: "新能分析评估",
       },
       {
         id: 22,
-        name: '批次管理'
-      }
-    ]
+        name: "批次管理",
+      },
+    ],
   },
   {
-    name: '数据管理',
-    iconName: 'dataManage',
+    name: "数据管理",
+    iconName: "dataManage",
     id: "3",
     children: [
       {
         id: 31,
-        name: '数据操作'
-      }
-    ]
+        name: "数据操作",
+      },
+    ],
   },
   {
-    name: '台账管理',
-    iconName: 'Ledger',
+    name: "台账管理",
+    iconName: "Ledger",
     id: "4",
     children: [
       {
         id: 41,
-        name: '企业信息'
+        name: "企业信息",
       },
       {
         id: 42,
-        name: '风场信息'
+        name: "风场信息",
       },
       {
         id: 43,
-        name: '风机信息'
+        name: "风机信息",
       },
       {
         id: 44,
-        name: '机型信息'
+        name: "机型信息",
       },
       {
         id: 45,
-        name: '测风塔信息'
-      }
-    ]
+        name: "测风塔信息",
+      },
+    ],
   },
   {
-    name: '权限管理',
-    iconName: 'jurisdiction',
+    name: "权限管理",
+    iconName: "jurisdiction",
     id: "5",
+    path: "system",
+    component: () => import("@/views/system/index.vue"),
     children: [
       {
         id: 51,
-        name: '员工管理'
+        name: "员工管理",
+        path: "userMag",
+        component: () => import("@/views/system/userMag/index.vue"),
       },
       {
         id: 52,
-        name: '角色管理'
+        name: "角色管理",
+        path: "roleMag",
+        component: () => import("@/views/system/roleMag/index.vue"),
       },
       {
         id: 53,
-        name: '菜单管理'
-      }
-    ]
-  }
-]
+        name: "菜单管理",
+        path: "menuMag",
+        component: () => import("@/views/system/menuMag/index.vue"),
+      },
+    ],
+  },
+];
 export default {
-  orgList
-}
+  orgList,
+};

+ 57 - 43
src/views/login/Index.vue

@@ -1,30 +1,43 @@
 <template>
   <div class="background-image">
-
-
     <div class="border">
       <div class="leftLogin">
-
         <h1>风机数据管理平台</h1>
         <el-divider></el-divider>
         <div class="loginText">
-          <el-form :model="loginForm" ref="ruleForm" label-width="0px" :rules="rules" class="demo-ruleForm">
-            <el-form-item prop="email">
-              <el-input placeholder="请输入用户名或账号" v-model="loginForm.email"></el-input>
+          <el-form
+            :model="loginForm"
+            ref="ruleForm"
+            label-width="0px"
+            :rules="rules"
+            class="demo-ruleForm"
+          >
+            <el-form-item prop="userName">
+              <el-input
+                placeholder="请输入用户名或账号"
+                v-model="loginForm.userName"
+              ></el-input>
             </el-form-item>
             <!-- TODO:删除placeholder -->
             <el-form-item prop="password">
-              <el-input type="password" placeholder="请输入密码" v-model="loginForm.password"></el-input>
+              <el-input
+                type="password"
+                placeholder="请输入密码"
+                v-model="loginForm.password"
+              ></el-input>
             </el-form-item>
 
             <el-form-item>
-              <el-button type="primary" class="custom-button" @click="login('ruleForm')">登录</el-button>
+              <el-button
+                type="primary"
+                class="custom-button"
+                @click="login('ruleForm')"
+                >登录</el-button
+              >
             </el-form-item>
           </el-form>
         </div>
-
       </div>
-
     </div>
   </div>
 </template>
@@ -33,61 +46,61 @@
 export default {
   data() {
     var validatePass = (rule, value, callback) => {
-      if (value === '') {
-        callback(new Error('请输入密码'))
+      if (value === "") {
+        callback(new Error("请输入密码"));
       } else {
-        callback()
+        callback();
       }
-    }
+    };
     return {
       loginForm: {
-        email: '',
-        password: ''
+        userName: "",
+        password: "",
       },
       rules: {
-        email: [
-          { required: true, message: '请输入用户名或账号', trigger: 'blur' },
+        userName: [
+          { required: true, message: "请输入用户名或账号", trigger: "blur" },
           {
-            type: '',
-            message: '请输入用户名或账号',
-            trigger: ['blur']
-          }
+            type: "",
+            message: "请输入用户名或账号",
+            trigger: ["blur"],
+          },
         ],
-        password: [{ validator: validatePass, trigger: 'blur' }]
-      }
-    }
+        password: [{ validator: validatePass, trigger: "blur" }],
+      },
+    };
   },
-  created() { },
+  created() {},
   methods: {
     // 登录
     login(formName) {
       // 自带校验
       this.$refs[formName].validate((valid) => {
         if (valid) {
-          this.$router.push('/')
+          this.$store.dispatch("auth/goLogin", this.loginForm);
+          // this.$router.push('/')
         } else {
-          console.log('error submit!!')
-          return false
+          console.log("error submit!!");
+          return false;
         }
-      })
+      });
     },
     //   忘记密码
     forgot() {
-      this.$router.push('/forgot')
-    }
-  }
-}
+      this.$router.push("/forgot");
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
 .background-image {
   width: 100vw;
   height: 100vh;
-  background-image: url('../../assets/login-img.png');
+  background-image: url("../../assets/login-img.png");
   background-size: cover;
   background-position: center;
   background-repeat: no-repeat;
-
 }
 
 .border {
@@ -113,29 +126,29 @@ export default {
       line-height: 50px;
       font-size: 26px;
       font-weight: 600;
-      color: #00BAAD;
+      color: #00baad;
       margin-top: 20px;
     }
 
     .el-divider--horizontal {
       margin: 10px 0;
       height: 4px;
-      background: #00BAAD;
+      background: #00baad;
     }
 
     .loginText {
       .custom-button {
         width: 300px;
         margin-bottom: 10px;
-        background-color: #00BAAD;
+        background-color: #00baad;
         color: white;
-        border: 2px solid #00BAAD;
+        border: 2px solid #00baad;
       }
 
       .custom-button:hover {
-        background-color:#00BAAD;
+        background-color: #00baad;
         color: white;
-        border: 2px solid #00BAAD;
+        border: 2px solid #00baad;
       }
     }
 
@@ -196,4 +209,5 @@ export default {
 
 // ::v-deep .el-form-item__error {
 //   left: 150;
-// }</style>
+// }
+</style>

+ 13 - 0
src/views/system/index.vue

@@ -0,0 +1,13 @@
+<!--
+ * @Author: your name
+ * @Date: 2024-05-17 16:02:11
+ * @LastEditTime: 2024-05-17 16:02:46
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /dasheng/performance-test/src/views/system/index.vue
+-->
+<template>
+  <div>权限管理</div>
+</template>
+<script></script>
+<style scoped lang="scss"></style>

+ 13 - 0
src/views/system/menuMag/index.vue

@@ -0,0 +1,13 @@
+<!--
+ * @Author: your name
+ * @Date: 2024-05-17 15:59:21
+ * @LastEditTime: 2024-05-17 15:59:21
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /dasheng/performance-test/src/views/system/menuMag/index.vue
+-->
+<template>
+  <div>菜单管理</div>
+</template>
+<script></script>
+<style lang="scss"></style>

+ 13 - 0
src/views/system/roleMag/index.vue

@@ -0,0 +1,13 @@
+<!--
+ * @Author: your name
+ * @Date: 2024-05-17 15:58:57
+ * @LastEditTime: 2024-05-17 15:59:09
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /dasheng/performance-test/src/views/system/roleMag/index.vue
+-->
+<template>
+  <div>角色管理</div>
+</template>
+<script></script>
+<style lang="scss"></style>

+ 5 - 0
src/views/system/userMag/index.vue

@@ -0,0 +1,5 @@
+<template>
+  <div>用户管理</div>
+</template>
+<script></script>
+<style lang="scss"></style>

+ 33 - 15
vue.config.js

@@ -1,33 +1,51 @@
-const path = require('path')
+const path = require("path");
 
 function resolve(dir) {
-  return path.join(__dirname, dir)
+  return path.join(__dirname, dir);
 }
 
 module.exports = {
   // 解析SVG组件
   chainWebpack(config) {
-    config.module.rule('svg').exclude.add(resolve('src/icons')).end()
+    config.module.rule("svg").exclude.add(resolve("src/icons")).end();
     config.module
-      .rule('icons')
+      .rule("icons")
       .test(/\.svg$/)
-      .include.add(resolve('src/icons'))
+      .include.add(resolve("src/icons"))
       .end()
-      .use('svg-sprite-loader')
-      .loader('svg-sprite-loader')
+      .use("svg-sprite-loader")
+      .loader("svg-sprite-loader")
       .options({
-        symbolId: 'icon-[name]'
+        symbolId: "icon-[name]",
       })
-      .end()
+      .end();
   },
   //vue.config.js
   css: {
     loaderOptions: {
       postcss: {
         postcssOptions: {
-          plugins: [require('tailwindcss'), require('autoprefixer')]
-        }
-      }
-    }
-  }
-}
+          plugins: [require("tailwindcss"), require("autoprefixer")],
+        },
+      },
+    },
+  },
+  devServer: {
+    proxy: {
+      "/api": {
+        target: "http://192.168.50.235:16200",
+        changeOrigin: true,
+        pathRewrite: {
+          "^/api": "", //需要rewrite重写的,
+        },
+      },
+    },
+  },
+  configureWebpack: {
+    resolve: {
+      alias: {
+        "@": resolve("src"),
+      },
+    },
+  },
+};

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません