Procházet zdrojové kódy

feat: 接口api组织架构登录

ystl_myq před 7 měsíci
rodič
revize
c7bdb49077
33 změnil soubory, kde provedl 1816 přidání a 562 odebrání
  1. 1 1
      .env.production
  2. 1 0
      package.json
  3. 8 0
      pnpm-lock.yaml
  4. 25 0
      src/api/department.ts
  5. 16 0
      src/api/menu.ts
  6. 11 0
      src/api/password.ts
  7. 33 0
      src/api/roles.ts
  8. 4 5
      src/api/user.ts
  9. 33 0
      src/api/userGroup.ts
  10. 25 0
      src/api/userSetting.ts
  11. 105 0
      src/components/UserPageTable/index.vue
  12. 1 0
      src/layout/components/sidebar/mixNav.vue
  13. 1 2
      src/router/index.ts
  14. 38 10
      src/router/utils.ts
  15. 10 0
      src/store/modules/permission.ts
  16. 1 0
      src/store/modules/types.ts
  17. 2 1
      src/store/modules/user.ts
  18. 23 0
      src/utils/encrypt.ts
  19. 3 2
      src/utils/http/index.ts
  20. 55 8
      src/views/background/framework/proson/components/changeRole.vue
  21. 81 33
      src/views/background/framework/proson/components/newDepartment.vue
  22. 36 8
      src/views/background/framework/proson/components/personDetailsDrawer.vue
  23. 45 12
      src/views/background/framework/proson/components/prosonEditDrawer.vue
  24. 141 110
      src/views/background/framework/proson/prosonDepartment.vue
  25. 29 21
      src/views/background/framework/roles/components/addRole.vue
  26. 213 57
      src/views/background/framework/roles/rolePower.vue
  27. 81 25
      src/views/background/framework/users/components/addUsers.vue
  28. 38 13
      src/views/background/framework/users/components/editPerson.vue
  29. 126 57
      src/views/background/framework/users/index.vue
  30. 1 3
      src/views/evaluate/children/change/components/evaluate.ts
  31. 490 165
      src/views/evaluate/children/change/components/settingIndexDrawer.vue
  32. 43 14
      src/views/login/index.vue
  33. 96 15
      src/views/password/index.vue

+ 1 - 1
.env.production

@@ -3,7 +3,7 @@ VITE_PUBLIC_PATH = /
 
 # 线上环境路由历史模式(Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数")
 VITE_ROUTER_HISTORY = "hash"
-
+VITE_BASE_URL = "http://116.148.231.158:9087"
 # 是否在打包时使用cdn替换本地库 替换 true 不替换 false
 VITE_CDN = false
 

+ 1 - 0
package.json

@@ -62,6 +62,7 @@
     "echarts": "^5.5.0",
     "element-plus": "^2.6.2",
     "js-cookie": "^3.0.5",
+    "jsencrypt": "^3.3.2",
     "localforage": "^1.10.0",
     "mitt": "^3.0.1",
     "nprogress": "^0.2.0",

+ 8 - 0
pnpm-lock.yaml

@@ -50,6 +50,9 @@ importers:
       js-cookie:
         specifier: ^3.0.5
         version: 3.0.5
+      jsencrypt:
+        specifier: ^3.3.2
+        version: 3.3.2
       localforage:
         specifier: ^1.10.0
         version: 1.10.0
@@ -2265,6 +2268,9 @@ packages:
     resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
     hasBin: true
 
+  jsencrypt@3.3.2:
+    resolution: {integrity: sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==}
+
   jsesc@2.5.2:
     resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
     engines: {node: '>=4'}
@@ -5998,6 +6004,8 @@ snapshots:
     dependencies:
       argparse: 2.0.1
 
+  jsencrypt@3.3.2: {}
+
   jsesc@2.5.2: {}
 
   json-buffer@3.0.1: {}

+ 25 - 0
src/api/department.ts

@@ -0,0 +1,25 @@
+import { http } from "@/utils/http";
+
+type addDept = {
+  code: number;
+  msg: string;
+  data: boolean;
+};
+type addDeptList = {
+  code: number;
+  msg: string;
+  data: Array<any>;
+};
+
+export const postAddDept = data => {
+  return http.request<addDept>("post", "/sysDept/addDept", { data });
+};
+export const postDelDept = data => {
+  return http.request<addDept>("post", "/sysDept/delDept", { data });
+};
+export const postListTree = () => {
+  return http.request<addDeptList>("post", "/sysDept/listTree");
+};
+export const postUpdateDept = data => {
+  return http.request<addDept>("post", "/sysDept/updateDept", { data });
+};

+ 16 - 0
src/api/menu.ts

@@ -0,0 +1,16 @@
+import { http } from "@/utils/http";
+
+type ResultList = {
+  code: number;
+  msg: string;
+  data: Array<any>;
+};
+
+export const getMenuList = () => {
+  return http.request<ResultList>("get", "/sysMenu/menuList");
+};
+export const getMenuListCodeForRole = data => {
+  return http.request<ResultList>("get", "/sysMenu/menuListCodeForRole", {
+    data
+  });
+};

+ 11 - 0
src/api/password.ts

@@ -0,0 +1,11 @@
+import { http } from "@/utils/http";
+
+type Result = {
+  code: number;
+  msg: string;
+  data: boolean;
+};
+
+export const postUpdatePassword = (data: any) => {
+  return http.request<Result>("post", "/user/updatePassword", { data });
+};

+ 33 - 0
src/api/roles.ts

@@ -0,0 +1,33 @@
+import { http } from "@/utils/http";
+
+type pageRole = {
+  code: number;
+  msg: string;
+  data: boolean;
+};
+type pageRoleList = {
+  code: number;
+  msg: string;
+  data: Array<any>;
+};
+
+export const postPageRole = data => {
+  return http.request<pageRoleList>("post", "/sysRole/pageRole", { data });
+};
+export const postDelRole = data => {
+  return http.request<pageRole>("post", "/sysRole/delRole", { data });
+};
+// 添加角色信息
+export const postAddRole = data => {
+  return http.request<pageRole>("post", "/sysRole/addRole", { data });
+};
+// 修改角色名称
+export const postUpdateRole = data => {
+  return http.request<pageRole>("post", "/sysRole/updateRole", { data });
+};
+// 查询角色下用户
+export const postPageUserByRole = data => {
+  return http.request<pageRoleList>("post", "/sysRole/pageUserByRole", {
+    data
+  });
+};

+ 4 - 5
src/api/user.ts

@@ -1,5 +1,4 @@
 import { http } from "@/utils/http";
-// import { baseUrlApi } from "./utils";
 export type UserResult = {
   success: boolean;
   data: {
@@ -29,12 +28,12 @@ export type RefreshTokenResult = {
 };
 
 /** 登录 */
-// export const getLogin = (data?: object) => {
-//   return http.request<UserResult>("post", baseUrlApi("/user/login"), { data });
-// };
 export const getLogin = (data?: object) => {
-  return http.request<UserResult>("post", "/login", { data });
+  return http.request<UserResult>("post", "/user/login", { data });
 };
+// export const getLogin = (data?: object) => {
+//   return http.request<UserResult>("post", "/login", { data });
+// };
 
 /** 刷新token */
 export const refreshTokenApi = (data?: object) => {

+ 33 - 0
src/api/userGroup.ts

@@ -0,0 +1,33 @@
+import { http } from "@/utils/http";
+
+type addDept = {
+  code: number;
+  msg: string;
+  data: boolean;
+};
+type addDeptList = {
+  code: number;
+  msg: string;
+  data: Array<any>;
+};
+
+// 新增用户组
+export const postAddUserGroup = data => {
+  return http.request<addDept>("post", "/userGroup/addUserGroup", { data });
+};
+// 分页用户组
+export const postPageGroup = data => {
+  return http.request<addDeptList>("post", "/userGroup/pageGroup", { data });
+};
+// 根据编码删除
+export const postDelUserGroup = data => {
+  return http.request<addDept>("post", "/userGroup/removeGroupByCode", {
+    data
+  });
+};
+// 根据编码更新
+export const postUpdateGroupByCode = data => {
+  return http.request<addDept>("post", "/userGroup/updateGroupByCode", {
+    data
+  });
+};

+ 25 - 0
src/api/userSetting.ts

@@ -0,0 +1,25 @@
+import { http } from "@/utils/http";
+// 用户设置
+type addDept = {
+  code: number;
+  msg: string;
+  data: boolean;
+};
+type userList = {
+  code: number;
+  msg: string;
+  data: Array<any>;
+};
+
+// 查询用户列表
+export const postUserList = data => {
+  return http.request<userList>("post", "/user/userList", { data });
+};
+// 查看不同组织架构下用户
+export const postOrganizationUserPage = data => {
+  return http.request<userList>("post", "/user/organizationUserPage", { data });
+};
+// 组织架构关联动作
+export const postAssignmentUser = data => {
+  return http.request<addDept>("post", "/user/assignmentUser", { data });
+};

+ 105 - 0
src/components/UserPageTable/index.vue

@@ -0,0 +1,105 @@
+<script setup lang="ts">
+defineOptions({
+  name: ""
+});
+import { ref, reactive } from "vue";
+import { ElMessageBox, ElMessage } from "element-plus";
+import { Search } from "@element-plus/icons-vue";
+import { postOrganizationUserPage } from "@/api/userSetting";
+const tableData = reactive({
+  list: [],
+  params: {
+    pageNumber: 1,
+    pageSize: 10,
+    organizationCode: "",
+    organizationType: ""
+  },
+  total: 0
+});
+const handleNodeClick = (data: any, userType: string) => {
+  if (userType == "group") {
+    tableData.params.organizationCode = data.groupCode;
+    tableData.params.organizationType = userType;
+  } else {
+    tableData.params.organizationCode = data.deptCode;
+    tableData.params.organizationType = userType;
+  }
+  postOrganizationUserPageApi();
+  setTimeout(() => {}, 0);
+};
+const postOrganizationUserPageApi = async () => {
+  const { code, data } = await postOrganizationUserPage(tableData.params);
+  if (code == 200) {
+    console.log("res", data);
+    tableData.list = data.records;
+    tableData.total = data.totalPage;
+  }
+};
+const handleSizeChange = val => {
+  tableData.params.pageSize = val;
+  postOrganizationUserPageApi();
+};
+const handleCurrentChange = val => {
+  tableData.params.pageSize = val;
+  postOrganizationUserPageApi();
+};
+defineExpose({
+  handleNodeClick
+});
+</script>
+
+<template>
+  <div>
+    <div class="flex justify-between mb-3">
+      <el-input
+        :prefix-icon="Search"
+        placeholder="搜索"
+        class="mb-2"
+        style="max-width: 300px"
+      />
+      <slot name="add-button" />
+      <!-- <el-button type="primary" @click="AddPerson">添加成员</el-button> -->
+    </div>
+    <el-table
+      v-if="(tableData.params.organizationType = 'dept')"
+      :data="tableData.list"
+      style="width: 100%"
+    >
+      <el-table-column prop="realName" label="姓名" />
+      <el-table-column prop="hospitalCode" label="工号" />
+      <el-table-column prop="address" label="性别" />
+      <el-table-column prop="address" label="年龄" />
+      <el-table-column prop="jobTitle" label="职称" />
+      <el-table-column prop="dept" label="部门" />
+      <el-table-column label="操作">
+        <template #default="{ row }">
+          <slot name="actions" :row="row" />
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-table v-else :data="tableData.list" style="width: 100%">
+      <el-table-column prop="realName" label="姓名" />
+      <el-table-column prop="hospitalCode" label="工号" />
+      <el-table-column prop="jobTitle" label="职称" />
+      <el-table-column prop="dept" label="部门" />
+      <el-table-column prop="phone" label="手机号" />
+      <el-table-column label="操作">
+        <template #default="{ row }">
+          <slot name="actions" :row="row" />
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="absolute right-0 mr-20 mt-3">
+      <el-pagination
+        v-model:current-page="tableData.params.pageNumber"
+        v-model:page-size="tableData.params.pageSize"
+        :page-sizes="[10, 15, 20, 30]"
+        size="small"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="tableData.total"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+  </div>
+</template>

+ 1 - 0
src/layout/components/sidebar/mixNav.vue

@@ -10,6 +10,7 @@ import { ref, toRaw, watch, onMounted, nextTick } from "vue";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import { getParentPaths, findRouteByPath } from "@/router/utils";
 import { usePermissionStoreHook } from "@/store/modules/permission";
+
 import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
 import Setting from "@iconify-icons/ri/settings-3-line";
 const router = useRouter();

+ 1 - 2
src/router/index.ts

@@ -41,7 +41,6 @@ const modules: Record<string, any> = import.meta.glob(
     eager: true
   }
 );
-
 /** 原始静态路由(未做任何处理) */
 const routes = [];
 
@@ -58,7 +57,7 @@ export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
 export const constantMenus: Array<RouteComponent> = ascending(
   routes.flat(Infinity)
 ).concat(...remainingRouter);
-
+console.log("remainingRouter", remainingRouter);
 /** 不参与菜单的路由 */
 export const remainingPaths = Object.keys(remainingRouter).map(v => {
   return remainingRouter[v].path;

+ 38 - 10
src/router/utils.ts

@@ -22,12 +22,34 @@ import { buildHierarchyTree } from "@/utils/tree";
 import { userKey, type DataInfo } from "@/utils/auth";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 import { usePermissionStoreHook } from "@/store/modules/permission";
+// 路由静态 对接接口后需删除-----------------------------
+// 搜索---代码删除-----下面打印代码删除遍历路由的代码
+// import { getMenuList } from "@/api/menu";
+import background from "./modules/background";
+import draw from "./modules/draw";
+import evaluate from "./modules/evaluate";
+import home from "./modules/home";
+import _import from "./modules/import";
+import index from "./modules/index";
+import other from "./modules/other";
+import password from "./modules/password";
+const muenList = [
+  background,
+  draw,
+  evaluate,
+  home,
+  _import,
+  index,
+  other,
+  password
+];
+// ------------------------------------
 const IFrame = () => import("@/layout/frameView.vue");
 // https://cn.vitejs.dev/guide/features.html#glob-import
 const modulesRoutes = import.meta.glob("/src/views/**/*.{vue,tsx}");
 
 // 动态路由
-import { getAsyncRoutes } from "@/api/routes";
+// import { getAsyncRoutes } from "@/api/routes";
 
 function handRank(routeInfo: any) {
   const { name, path, parentId, meta } = routeInfo;
@@ -194,19 +216,25 @@ function initRouter() {
       });
     } else {
       return new Promise(resolve => {
-        getAsyncRoutes().then(({ data }) => {
-          handleAsyncRoutes(cloneDeep(data));
-          storageLocal().setItem(key, data);
-          resolve(router);
-        });
+        handleAsyncRoutes(cloneDeep(muenList));
+        storageLocal().setItem(key, muenList);
+        resolve(router);
+        // getAsyncRoutes().then(({ data }) => {
+        //   // console.log("data", data);
+        //   handleAsyncRoutes(cloneDeep(data));
+        //   storageLocal().setItem(key, data);
+        //   resolve(router);
+        // });
       });
     }
   } else {
     return new Promise(resolve => {
-      getAsyncRoutes().then(({ data }) => {
-        handleAsyncRoutes(cloneDeep(data));
-        resolve(router);
-      });
+      // getAsyncRoutes().then(({ data }) => {
+      //   handleAsyncRoutes(cloneDeep(data));
+      // resolve(router);
+      // });
+      handleAsyncRoutes(cloneDeep(muenList));
+      resolve(router);
     });
   }
 }

+ 10 - 0
src/store/modules/permission.ts

@@ -22,6 +22,16 @@ export const usePermissionStore = defineStore({
       this.wholeMenus = filterNoPermissionTree(
         filterTree(ascending(this.constantMenus.concat(routes)))
       );
+      // 代码删除
+      this.wholeMenus = this.wholeMenus.reduce((accumulator, current) => {
+        const x = accumulator.find(item => item.path === current.path);
+        if (!x) {
+          return accumulator.concat([current]);
+        } else {
+          return accumulator;
+        }
+      }, []);
+      // --------------
     },
     cacheOperate({ mode, name }: cacheType) {
       const delIndex = this.cachePageList.findIndex(v => v === name);

+ 1 - 0
src/store/modules/types.ts

@@ -38,6 +38,7 @@ export type setType = {
 
 export type userType = {
   username?: string;
+  password?: string;
   roles?: Array<string>;
   isRemembered?: boolean;
   loginDay?: number;

+ 2 - 1
src/store/modules/user.ts

@@ -13,7 +13,8 @@ export const useUserStore = defineStore({
   id: "pure-user",
   state: (): userType => ({
     // 用户名
-    username: storageLocal().getItem<DataInfo<number>>(userKey)?.username ?? "",
+    username: localStorage.getItem("userName") ?? "",
+    password: "",
     // 页面级别权限
     roles: storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [],
     // 是否勾选了登录页的免登录

+ 23 - 0
src/utils/encrypt.ts

@@ -0,0 +1,23 @@
+import JSEncrypt from "jsencrypt";
+
+// 公钥
+const PUBLICK_KEY =
+  "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALM5Ng98GCAQLcUwdPmxZQ2+QUaWbrWfkg4BLY0u0twGHKC7upBPvpr7f1uvfv6EiMsOCEtELN1I5nY9nmuvIk8CAwEAAQ==";
+
+// 创建实例
+const encrypt = new JSEncrypt();
+encrypt.setPublicKey(PUBLICK_KEY);
+
+// 加密
+const encryption = (data = "") => {
+  if (!data) return data;
+  return encrypt.encrypt(data);
+};
+
+// 解密
+const decryption = (data = "") => {
+  if (!data) return data;
+  return encrypt.decrypt(data);
+};
+
+export { encryption, decryption };

+ 3 - 2
src/utils/http/index.ts

@@ -13,12 +13,11 @@ import { stringify } from "qs";
 import NProgress from "../progress";
 import { getToken, formatToken } from "@/utils/auth";
 import { useUserStoreHook } from "@/store/modules/user";
-
 // 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
 const defaultConfig: AxiosRequestConfig = {
   // 请求超时时间
   timeout: 10000,
-  // baseURL: import.meta.env.VITE_BASE_URL,
+  baseURL: import.meta.env.VITE_BASE_URL,
   headers: {
     Accept: "application/json, text/plain, */*",
     "Content-Type": "application/json",
@@ -64,6 +63,8 @@ class PureHttp {
       async (config: PureHttpRequestConfig): Promise<any> => {
         // 开启进度条动画
         NProgress.start();
+        const token = localStorage.getItem("token") || "";
+        config.headers["satoken"] = token;
         // 优先判断post/get等方法是否传入回调,否则执行初始化设置等回调
         if (typeof config.beforeRequestCallback === "function") {
           config.beforeRequestCallback(config);

+ 55 - 8
src/views/background/framework/proson/components/changeRole.vue

@@ -2,6 +2,8 @@
 import { ref, reactive } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 const dialogVisibleAdd = ref(false);
+import { postPageRole } from "@/api/roles";
+import { postAssignmentUser } from "@/api/userSetting";
 const form = reactive({
   name: "",
   region: "",
@@ -25,16 +27,56 @@ const handleClose = () => {
       // catch error
     });
 };
+const rolesList = reactive({
+  list: [],
+  assignmentParams: {
+    sourceCodes: [],
+    targetCodes: [],
+    linkAction: "link",
+    correlatedModel: "deptRole"
+  },
+  rolesName: ""
+});
+const postAddUserGroupApi = async () => {
+  const { code } = await postAssignmentUser(rolesList.assignmentParams);
+  if (code === 200) {
+    ElMessage({
+      message: "添加成功",
+      type: "success"
+    });
+  }
+};
+
+const rolesData = async () => {
+  const { code, data } = await postPageRole({
+    pageNumber: 1,
+    pageSize: 100
+  });
+  if (code === 200) {
+    rolesList.list = data.records;
+  }
+};
+const changeRoles = () => {
+  rolesList.assignmentParams.sourceCodes = [];
+  rolesList.assignmentParams.sourceCodes.push(rolesList.rolesName);
+};
 // 添加部门保存
 const saveDepartment = () => {
   dialogVisibleAdd.value = false;
-  ElMessage({
-    message: "添加成功",
-    type: "success"
-  });
+  postAddUserGroupApi();
 };
-const open = () => {
+const open = (item, user) => {
   dialogVisibleAdd.value = true;
+  if (user == "用户") {
+    // console.log("item", item);
+    rolesList.assignmentParams.targetCodes = [];
+    rolesList.assignmentParams.targetCodes.push(item.data.userCode);
+  } else {
+    // console.log("item", item);
+    rolesList.assignmentParams.targetCodes = [];
+    rolesList.assignmentParams.targetCodes.push(item.data.deptCode);
+  }
+  rolesData();
 };
 defineExpose({
   open
@@ -53,10 +95,15 @@ defineExpose({
         <el-form-item label="配置角色">
           <el-select
             v-model="form.region"
-            placeholder="please select your zone"
+            placeholder="请选择角色"
+            @change="changeRoles"
           >
-            <el-option label="Zone one" value="shanghai" />
-            <el-option label="Zone two" value="beijing" />
+            <el-option
+              v-for="(item, index) in rolesList.list"
+              :key="index"
+              :label="item.roleName"
+              :value="item.roleCode"
+            />
           </el-select>
         </el-form-item>
       </el-form>

+ 81 - 33
src/views/background/framework/proson/components/newDepartment.vue

@@ -1,25 +1,63 @@
 <script setup lang="ts">
-import { ref, reactive } from "vue";
+import { ref, reactive, defineEmits } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
+import { postAddDept, postListTree } from "@/api/department";
+import { postUserList } from "@/api/userSetting";
+import { encryption } from "@/utils/encrypt";
 const dialogVisibleAdd = ref(false);
+const emit = defineEmits(["handleClick"]);
 const form = reactive({
-  name: "",
-  region: "",
-  date1: "",
-  date2: "",
-  delivery: false,
-  type: [],
-  resource: "",
-  desc: ""
+  deptName: "",
+  deptCode: "",
+  leader: "",
+  parentCode: ""
 });
+const optiones = reactive({
+  parentOptions: [],
+  leaderOptions: []
+});
+// 添加
+const postAddDeptApi = async () => {
+  const { code } = await postAddDept(form);
+  if (code === 200) {
+    ElMessage({
+      message: "添加成功",
+      type: "success"
+    });
+  }
+};
+// 上级部门
+const postListTreeApi = async () => {
+  const { code, data } = await postListTree();
+  if (code === 200) {
+    optiones.parentOptions = data;
+  }
+};
+postListTreeApi();
+// 负责人
+const userList = ref({
+  username: "",
+  password: ""
+});
+const postUserListApi = async () => {
+  // @ts-ignore
+  userList.value.username = encryption(localStorage.getItem("rolesName"));
+  // @ts-ignore
+  userList.value.password = encryption(localStorage.getItem("password"));
+  const { code, data } = await postUserList(userList.value);
+  if (code === 200) {
+    optiones.leaderOptions = data;
+  }
+};
+postUserListApi();
 const handleClose = () => {
   ElMessageBox.confirm("确认关闭弹窗吗?")
     .then(() => {
       dialogVisibleAdd.value = !dialogVisibleAdd.value;
-      ElMessage({
-        message: "已关闭",
-        type: "success"
-      });
+      form.deptName = "";
+      form.deptCode = "";
+      form.leader = "";
+      form.parentCode = "";
     })
     .catch(() => {
       // catch error
@@ -28,14 +66,22 @@ const handleClose = () => {
 // 添加部门保存
 const saveDepartment = () => {
   dialogVisibleAdd.value = false;
-  ElMessage({
-    message: "添加成功",
-    type: "success"
-  });
+  postAddDeptApi();
+  emit("handleClick");
 };
-const open = () => {
+const open = node => {
   dialogVisibleAdd.value = true;
+  if (node) {
+    // form.leader
+    form.deptName = "";
+    form.deptCode = "";
+    form.leader = "";
+    form.parentCode = "";
+    optiones.parentOptions = [];
+    optiones.parentOptions.push(node.data);
+  }
 };
+// 添加子部门数据
 defineExpose({
   open
 });
@@ -51,7 +97,7 @@ defineExpose({
     >
       <el-form :model="form" label-width="auto" style="max-width: 600px">
         <el-form-item
-          prop="name"
+          prop="deptName"
           label="部门名称"
           :rules="[
             {
@@ -61,27 +107,29 @@ defineExpose({
             }
           ]"
         >
-          <el-input v-model="form.name" />
+          <el-input v-model="form.deptName" />
         </el-form-item>
         <el-form-item label="部门编号">
-          <el-input v-model="form.name" />
+          <el-input v-model="form.deptCode" />
         </el-form-item>
         <el-form-item label="上级部门">
-          <el-select
-            v-model="form.region"
-            placeholder="please select your zone"
-          >
-            <el-option label="Zone one" value="shanghai" />
-            <el-option label="Zone two" value="beijing" />
+          <el-select v-model="form.parentCode" placeholder="请选择上级部门">
+            <el-option
+              v-for="item in optiones.parentOptions"
+              :key="item.value"
+              :label="item.deptName"
+              :value="item.deptCode"
+            />
           </el-select>
         </el-form-item>
         <el-form-item label="部门负责人">
-          <el-select
-            v-model="form.region"
-            placeholder="please select your zone"
-          >
-            <el-option label="Zone one" value="shanghai" />
-            <el-option label="Zone two" value="beijing" />
+          <el-select v-model="form.leader" placeholder="请选择部门负责人">
+            <el-option
+              v-for="item in optiones.leaderOptions"
+              :key="item.value"
+              :label="item.userName"
+              :value="item.userCode"
+            />
           </el-select>
         </el-form-item>
       </el-form>

+ 36 - 8
src/views/background/framework/proson/components/personDetailsDrawer.vue

@@ -7,9 +7,19 @@ const drawer = ref(false);
 const disabledValue = ref(true);
 const direction = ref<DrawerProps["direction"]>("rtl");
 const formLabelAlign = reactive({
-  name: "",
-  region: "",
-  type: ""
+  realName: "",
+  hospitalCode: "",
+  userCode: "",
+  userName: "",
+  phone: "",
+  remark: "",
+  headUrl: "",
+  token: "",
+  menuRole: "",
+  columnRole: "",
+  dept: "",
+  group: "",
+  jobTitle: ""
 });
 const handleClose = (done: () => void) => {
   ElMessageBox.confirm("配置项未保存,确认关闭", {
@@ -36,6 +46,9 @@ function confirmClick() {
 }
 const open = row => {
   drawer.value = true;
+  console.log("111", row);
+  Object.assign(formLabelAlign, row);
+  console.log("formLabelAlign", formLabelAlign);
 };
 const editShow = ref(true);
 // 编辑
@@ -67,16 +80,25 @@ const timer = ref("");
             :model="formLabelAlign"
           >
             <el-form-item label="姓名" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.realName"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="工号" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.hospitalCode"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="员工ID" label-position="top">
               <el-input :disabled="disabledValue" />
             </el-form-item>
             <el-form-item label="部门" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.dept"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="性别" label-position="top">
               <el-input :disabled="disabledValue" />
@@ -85,10 +107,16 @@ const timer = ref("");
               <el-input :disabled="disabledValue" />
             </el-form-item>
             <el-form-item label="职称" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.jobTitle"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="手机号" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.phone"
+                :disabled="disabledValue"
+              />
             </el-form-item>
           </el-form>
         </div>

+ 45 - 12
src/views/background/framework/proson/components/prosonEditDrawer.vue

@@ -2,14 +2,16 @@
 import { ref, reactive } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 import type { DrawerProps, FormItemProps, FormProps } from "element-plus";
+import { postUpdateDept } from "@/api/department";
 // const itemLabelPosition = ref<FormItemProps["labelPosition"]>("");
 const drawer = ref(false);
 const disabledValue = ref(true);
 const direction = ref<DrawerProps["direction"]>("rtl");
 const formLabelAlign = reactive({
-  name: "",
-  region: "",
-  type: ""
+  deptName: "",
+  deptCode: "",
+  type: "",
+  leader: ""
 });
 const handleClose = (done: () => void) => {
   ElMessageBox.confirm("配置项未保存,确认关闭", {
@@ -25,19 +27,31 @@ function cancelClick() {
   disabledValue.value = true;
   editShow.value = true;
 }
+const postUpdateDeptApi = async () => {
+  const res = await postUpdateDept(formLabelAlign);
+  if (res.code == 200) {
+    ElMessage({
+      message: "保存成功",
+      type: "success"
+    });
+  }
+};
 function confirmClick() {
-  console.log(1111);
+  postUpdateDeptApi();
   disabledValue.value = true;
   editShow.value = true;
   drawer.value = !drawer.value;
-  ElMessage({
-    message: "保存成功",
-    type: "success"
-  });
 }
 const open = row => {
+  // formLabelAlign = row.data;
+  formLabelAlign.deptName = row.data.deptName;
+  formLabelAlign.deptCode = row.data.deptCode;
+  formLabelAlign.leader = row.data.leader;
+  // console.log("数据", row.data);
+  console.log("数据", row);
   drawer.value = true;
 };
+
 const editShow = ref(true);
 // 编辑
 const editClick = () => {
@@ -67,17 +81,36 @@ const timer = ref("");
             label-width="auto"
             :model="formLabelAlign"
           >
-            <el-form-item label="消化科" label-position="top">
-              <el-input :disabled="disabledValue" />
+            <el-form-item
+              label="部门名称"
+              label-position="top"
+              :rules="[
+                {
+                  required: true,
+                  message: '请填写部门名称',
+                  trigger: 'change'
+                }
+              ]"
+            >
+              <el-input
+                v-model="formLabelAlign.deptName"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="部门编号" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.deptCode"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="部门ID" label-position="top">
               <el-input :disabled="disabledValue" />
             </el-form-item>
             <el-form-item label="部门负责人" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.leader"
+                :disabled="disabledValue"
+              />
             </el-form-item>
           </el-form>
         </div>

+ 141 - 110
src/views/background/framework/proson/prosonDepartment.vue

@@ -11,7 +11,9 @@ import newDepartment from "./components/newDepartment.vue";
 import addPerson from "./components/addPerson.vue";
 import personDetailsDrawer from "./components/personDetailsDrawer.vue";
 import changeRole from "./components/changeRole.vue";
-import { addDeptPost } from "@/api/system.ts";
+import { postListTree, postDelDept } from "@/api/department";
+import { postOrganizationUserPage } from "@/api/userSetting";
+import UserPageTable from "@/components/UserPageTable/index.vue";
 // 添加部门
 const newDepartmentRef = ref(null);
 const newDepartmentShow = ref(false);
@@ -27,94 +29,52 @@ const personDetailsDrawerShow = ref(false);
 // 配置角色
 const changeRoleRef = ref(null);
 const changeRoleShow = ref(false);
-const data = [
-  {
-    label: "Level one 1",
-    children: [
-      {
-        label: "Level two 1-1",
-        children: [
-          {
-            label: "Level three 1-1-1"
-          }
-        ]
-      }
-    ]
-  },
-  {
-    label: "Level one 2",
-    children: [
-      {
-        label: "Level two 2-1",
-        children: [
-          {
-            label: "Level three 2-1-1"
-          }
-        ]
-      },
-      {
-        label: "Level two 2-2",
-        children: [
-          {
-            label: "Level three 2-2-1"
-          }
-        ]
-      }
-    ]
-  },
-  {
-    label: "Level one 3",
-    children: [
-      {
-        label: "Level two 3-1",
-        children: [
-          {
-            label: "Level three 3-1-1"
-          }
-        ]
-      },
-      {
-        label: "Level two 3-2",
-        children: [
-          {
-            label: "Level three 3-2-1"
-          }
-        ]
-      }
-    ]
-  }
-];
-const tableData = [
-  {
-    date: "2016-05-03",
-    name: "Tom",
-    address: "No. 189, Grove St, Los Angeles"
-  },
-  {
-    date: "2016-05-02",
-    name: "Tom",
-    address: "No. 189, Grove St, Los Angeles"
-  },
-  {
-    date: "2016-05-04",
-    name: "Tom",
-    address: "No. 189, Grove St, Los Angeles"
-  },
-  {
-    date: "2016-05-01",
-    name: "Tom",
-    address: "No. 189, Grove St, Los Angeles"
-  }
-];
+// table表格
+const UserTable = ref();
+const dataTree = ref([]);
+const defaultProps = {
+  children: "childrenRes",
+  label: "deptName"
+};
+// const tableData = [
+//   {
+//     date: "2016-05-03",
+//     name: "Tom",
+//     address: "No. 189, Grove St, Los Angeles"
+//   },
+//   {
+//     date: "2016-05-02",
+//     name: "Tom",
+//     address: "No. 189, Grove St, Los Angeles"
+//   },
+//   {
+//     date: "2016-05-04",
+//     name: "Tom",
+//     address: "No. 189, Grove St, Los Angeles"
+//   },
+//   {
+//     date: "2016-05-01",
+//     name: "Tom",
+//     address: "No. 189, Grove St, Los Angeles"
+//   }
+// ];
 // 添加部门弹窗
 const addDepartment = () => {
   newDepartmentRef.value.open();
 };
-const addDeptPostApi = async () => {
-  let res = await addDeptPost();
-  console.log(res);
+// 添加子部门
+const adddeptChild = node => {
+  newDepartmentRef.value.open(node);
+};
+// 查询部门树
+const postListTreeApi = async () => {
+  const { code, data } = await postListTree();
+  if (code == 200) {
+    console.log(data);
+    dataTree.value = data;
+  }
 };
-// addDeptPostApi();
+postListTreeApi();
 // 删除人员
 const deletePerson = row => {
   console.log(row);
@@ -132,11 +92,22 @@ const deletePerson = row => {
     });
 };
 // 编辑部门弹窗
-const editDepartment = () => {
-  prosonEditDrawerRef.value.open();
+const editDepartment = node => {
+  prosonEditDrawerRef.value.open(node);
 };
 // 删除部门
-const deleteDepartment = () => {
+const postDelDeptApi = async data => {
+  const { code } = await postDelDept(data);
+  if (code == 200) {
+    ElMessage({
+      message: "删除成功",
+      type: "success"
+    });
+    postListTreeApi();
+  }
+};
+const deleteDepartment = node => {
+  console.log("删除部门", node);
   ElMessageBox.confirm(
     "请先移除部门内的所有人员再进行删除部门操作",
     "确认删除该部门吗?",
@@ -145,10 +116,7 @@ const deleteDepartment = () => {
     }
   )
     .then(() => {
-      ElMessage({
-        message: "删除成功",
-        type: "success"
-      });
+      postDelDeptApi(node.data);
     })
     .catch(() => {
       // catch error
@@ -159,17 +127,47 @@ const AddPerson = () => {
   addPersonDrawerRef.value.open();
 };
 const personDetails = row => {
-  personDetailsDrawerRef.value.open();
-  console.log(row);
+  personDetailsDrawerRef.value.open(row);
+  // console.log(row);
 };
 const ChangeRole = row => {
-  changeRoleRef.value.open();
-  console.log(row);
+  changeRoleRef.value.open(row, "用户");
 };
 // 部门配置角色
 const editRoles = row => {
-  changeRoleRef.value.open();
-  console.log(row);
+  changeRoleRef.value.open(row);
+  // console.log(row);
+};
+// 人员表格
+const tableData = reactive({
+  list: [],
+  params: {
+    pageNumber: 1,
+    pageSize: 10,
+    organizationCode: "",
+    organizationType: "dept"
+  }
+});
+const handleNodeClick = data => {
+  // console.log("UserPageTable", UserTable);
+  UserTable.value.handleNodeClick(data, "dept");
+  // tableData.params.organizationCode = data.deptCode;
+  // postOrganizationUserPageApi();
+};
+const postOrganizationUserPageApi = async () => {
+  const { code, data } = await postOrganizationUserPage(tableData.params);
+  if (code == 200) {
+    console.log(data);
+    tableData.list = data.records;
+    // tableData.value = res.records;
+    // total.value = res.total;
+  }
+};
+const handleSizeChange = val => {
+  console.log(`${val} items per page`);
+};
+const handleCurrentChange = val => {
+  console.log(`current page: ${val}`);
 };
 </script>
 
@@ -181,7 +179,11 @@ const editRoles = row => {
       v-model="prosonEditDrawerShow"
     />
     <!-- 添加部门 -->
-    <newDepartment ref="newDepartmentRef" v-model="newDepartmentShow" />
+    <newDepartment
+      ref="newDepartmentRef"
+      v-model="newDepartmentShow"
+      @handleClick="postListTreeApi"
+    />
     <!-- 添加成员 -->
     <addPerson ref="addPersonDrawerRef" v-model="addPersonDrawerShow" />
     <!-- 成员详情 -->
@@ -197,10 +199,12 @@ const editRoles = row => {
       <el-tree
         class="m-2 mr-8"
         style="max-width: 600px"
-        :data="data"
+        :data="dataTree"
+        :props="defaultProps"
         node-key="id"
         default-expand-all
         :expand-on-click-node="false"
+        @node-click="handleNodeClick"
       >
         <template #default="{ node }">
           <span>{{ node.label }}</span>
@@ -210,15 +214,17 @@ const editRoles = row => {
             </span>
             <template #dropdown>
               <el-dropdown-menu class="setting">
-                <el-dropdown-item @click="editDepartment">
+                <el-dropdown-item @click="editDepartment(node)">
                   编辑部门
                 </el-dropdown-item>
-                <el-dropdown-item> 添加子部门 </el-dropdown-item>
-                <el-dropdown-item @click="editRoles">
+                <el-dropdown-item @click="adddeptChild(node)">
+                  添加子部门
+                </el-dropdown-item>
+                <el-dropdown-item @click="editRoles(node)">
                   配置角色
                 </el-dropdown-item>
                 <el-dropdown-item>
-                  <el-link type="danger" @click="deleteDepartment"
+                  <el-link type="danger" @click="deleteDepartment(node)"
                     >删除</el-link
                   >
                 </el-dropdown-item>
@@ -232,7 +238,32 @@ const editRoles = row => {
       >
     </div>
     <div class="box-right">
-      <div class="flex justify-between mb-3">
+      <UserPageTable ref="UserTable">
+        <template #add-button>
+          <el-button type="primary" @click="AddPerson">添加成员</el-button>
+        </template>
+        <template #actions="{ row }">
+          <el-dropdown trigger="click" class="mr-2">
+            <el-icon @click="personDetails(row)"><View /></el-icon>
+          </el-dropdown>
+          <el-dropdown trigger="click">
+            <el-icon><Operation /></el-icon>
+            <template #dropdown>
+              <el-dropdown-menu class="setting">
+                <el-dropdown-item>
+                  <el-link type="danger" @click="deletePerson(row)"
+                    >删除</el-link
+                  >
+                </el-dropdown-item>
+                <el-dropdown-item @click="ChangeRole(row)">
+                  配置角色
+                </el-dropdown-item>
+              </el-dropdown-menu>
+            </template>
+          </el-dropdown>
+        </template>
+      </UserPageTable>
+      <!-- <div class="flex justify-between mb-3">
         <el-input
           :prefix-icon="Search"
           placeholder="搜索"
@@ -241,13 +272,13 @@ const editRoles = row => {
         />
         <el-button type="primary" @click="AddPerson">添加成员</el-button>
       </div>
-      <el-table :data="tableData" style="width: 100%">
-        <el-table-column prop="date" label="姓名" />
-        <el-table-column prop="name" label="工号" />
+      <el-table :data="tableData.list" style="width: 100%">
+        <el-table-column prop="realName" label="姓名" />
+        <el-table-column prop="hospitalCode" label="工号" />
         <el-table-column prop="address" label="性别" />
         <el-table-column prop="address" label="年龄" />
-        <el-table-column prop="address" label="职称" />
-        <el-table-column prop="address" label="部门" />
+        <el-table-column prop="jobTitle" label="职称" />
+        <el-table-column prop="dept" label="部门" />
         <el-table-column label="操作">
           <template #default="{ row }">
             <el-dropdown trigger="click" class="mr-2">
@@ -270,7 +301,7 @@ const editRoles = row => {
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table> -->
     </div>
   </div>
 </template>

+ 29 - 21
src/views/background/framework/roles/components/addRole.vue

@@ -1,18 +1,27 @@
 <script setup lang="ts">
 import { ref, reactive } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
+import { postAddRole, postUpdateRole } from "@/api/roles";
+const emit = defineEmits(["handleClick"]);
 const dialogVisibleAdd = ref(false);
-const dialogTitle = ref("新增角色");
+const dialogTitle = ref("新增");
 const form = reactive({
-  name: "",
-  region: "",
-  date1: "",
-  date2: "",
-  delivery: false,
-  type: [],
-  resource: "",
-  desc: ""
+  roleName: "",
+  roleCode: ""
 });
+const postAddRoleApi = async () => {
+  const res =
+    dialogTitle.value == "新增"
+      ? await postAddRole(form)
+      : await postUpdateRole(form);
+  if (res.code === 200) {
+    emit("handleClick");
+    ElMessage({
+      message: `${dialogTitle.value}成功`,
+      type: "success"
+    });
+  }
+};
 const handleClose = () => {
   ElMessageBox.confirm("确认关闭弹窗吗?")
     .then(() => {
@@ -29,18 +38,17 @@ const handleClose = () => {
 // 添加部门保存
 const saveDepartment = () => {
   dialogVisibleAdd.value = false;
-  ElMessage({
-    message: "添加成功",
-    type: "success"
-  });
+  postAddRoleApi();
 };
 const open = item => {
+  console.log(item);
   if (item) {
-    dialogTitle.value = "编辑角色";
-    form.name = item.name;
+    form.roleCode = item.roleCode;
+    dialogTitle.value = "编辑";
+    form.roleName = item.roleName;
   } else {
-    dialogTitle.value = "新增角色";
-    form.name = "";
+    dialogTitle.value = "新增";
+    form.roleName = "";
   }
   dialogVisibleAdd.value = true;
   console.log(item);
@@ -54,23 +62,23 @@ defineExpose({
   <div>
     <el-dialog
       v-model="dialogVisibleAdd"
-      :title="dialogTitle"
+      :title="dialogTitle + '角色'"
       width="500"
       :before-close="handleClose"
     >
       <el-form :model="form" label-width="auto" style="max-width: 600px">
         <el-form-item
-          prop="name"
+          prop="roleName"
           label="角色"
           :rules="[
             {
               required: true,
-              message: '请填写部门名称',
+              message: '请填写角色名称',
               trigger: 'blur'
             }
           ]"
         >
-          <el-input v-model="form.name" placeholder="请输入" />
+          <el-input v-model="form.roleName" placeholder="请输入" />
         </el-form-item>
       </el-form>
       <template #footer>

+ 213 - 57
src/views/background/framework/roles/rolePower.vue

@@ -8,6 +8,8 @@ import { ElMessageBox, ElMessage } from "element-plus";
 import { Search } from "@element-plus/icons-vue";
 import addRole from "./components/addRole.vue";
 import addPerson from "./components/addPerson.vue";
+import { getMenuList, getMenuListCodeForRole } from "@/api/menu";
+import { postPageRole, postDelRole, postPageUserByRole } from "@/api/roles";
 // 新增角色
 const addRoleRef = ref();
 const addRoleShow = ref(false);
@@ -42,23 +44,73 @@ const tableData = ref([
     show: true
   }
 ]);
-const rolesList = reactive({
-  data: [
-    { name: "管理员", id: 1 },
-    { name: "科室主任", id: 2 },
-    { name: "医生", id: 3 },
-    { name: "员工", id: 4 },
-    { name: "张三", id: 5 },
-    { name: "李四", id: 6 }
-  ],
+interface Role {
+  id?: number;
+  roleName: string;
+  records: Array<string>;
+}
+interface ApiResponse {
+  code: number;
+  data: {
+    records: Role[];
+    // 可能还有其他字段,比如 total, page, etc.
+  };
+}
+const rolesList = reactive<any>({
+  data: [],
+  dataUser: [],
   rolesName: ""
 });
+// 角色列表
+let pageSize = reactive({
+  pageNumber: 1,
+  pageSize: 5
+});
+const load = () => {
+  pageSize.pageSize += 5;
+  postPageRoleApi();
+};
+const loadSystem = async () => {
+  pageSize.pageSize += 5;
+  postPageRoleApi();
+};
+
+// 系统角色
+const postPageRoleApi = async () => {
+  const { code, data }: ApiResponse = await postPageRole({
+    ...pageSize,
+    roleType: "system"
+  });
+  const res: ApiResponse = await postPageRole({
+    ...pageSize,
+    roleType: "user"
+  });
+  if (code === 200) {
+    rolesList.data = [];
+    data.records.map((item, index) => {
+      rolesList.data.push({ ...item, id: index + 2 });
+    });
+  }
+  if (res.code === 200) {
+    rolesList.dataUser = [];
+    res.data.records.map((item, index) => {
+      rolesList.dataUser.push({ ...item, id: index + 3 });
+    });
+  }
+};
+// 自定义角色
+postPageRoleApi();
 // 查看角色组
 const bgColor = ref(null);
 const lookRoles = item => {
-  console.log(item);
+  // console.log(item);
+  paramsPageUser.roleName = item.roleName;
+  paramsPageUser.roleCode = item.roleCode;
   bgColor.value = item.id;
-  rolesList.rolesName = item.name;
+  rolesList.rolesName = item.roleName;
+  postPageUserByRoleApi();
+  // getMenuListApi();
+  getMenuListCodeForRoleApi(item);
 };
 // 添加角色
 const addRoles = () => {
@@ -71,20 +123,27 @@ const editRoleName = item => {
   addRoleShow.value = true;
 };
 // 删除角色
+const postDelRoleApi = async item => {
+  console.log("item", item);
+  const { code } = await postDelRole(item);
+  if (code === 200) {
+    ElMessage({
+      message: "删除成功",
+      type: "success"
+    });
+    postPageRoleApi();
+  }
+};
 const deleteRole = item => {
-  console.log(item);
   ElMessageBox.confirm(
-    `角色删除后不能恢复,是否确认删除角色【${item.name}】吗?`,
+    `角色删除后不能恢复,是否确认删除角色【${item.roleName}】吗?`,
     "确认删除角色吗",
     {
       type: "warning"
     }
   )
     .then(() => {
-      ElMessage({
-        message: "删除成功",
-        type: "success"
-      });
+      postDelRoleApi(item);
     })
     .catch(() => {
       // catch error
@@ -96,9 +155,6 @@ const deleteRole = item => {
 // 标签选择
 const activeName = ref("first");
 
-const handleClick = (tab, event) => {
-  console.log(tab, event);
-};
 // 添加角色组成员
 const AddRolesPerson = () => {
   addPersonRef.value.open();
@@ -108,7 +164,7 @@ const AddRolesPerson = () => {
 const deltetePerson = item => {
   console.log(item);
   ElMessageBox.confirm(
-    `人员删除后不能恢复,是否确认删除【${item.name}】吗?`,
+    `人员删除后不能恢复,是否确认删除【${item.realName}】吗?`,
     "确认删除人员吗",
     {
       type: "warning"
@@ -127,12 +183,46 @@ const deltetePerson = item => {
       });
     });
 };
+// 成员管理
+const paramsPageUser = reactive({
+  pageNumber: 1,
+  pageSize: 10,
+  roleName: "",
+  roleCode: "",
+  userCodes: []
+});
+const postPageUserByRoleApi = async () => {
+  const { code, data } = await postPageUserByRole(paramsPageUser);
+  console.log(data);
+  if (code === 200) {
+    tableData.value = data.records;
+  }
+};
+// 菜单权限
+const handleClick = (tab, event) => {
+  console.log(tab, event);
+};
+const getMenuListApi = async () => {
+  const { code, data } = await getMenuList();
+  // console.log("菜单", data);
+};
+const getMenuListCodeForRoleApi = async item => {
+  console.log("item", item);
+  const { code, data } = await getMenuListCodeForRole({
+    roleCode: item.roleCode
+  });
+  // console.log("菜单", data);
+};
 </script>
 
 <template>
   <div class="flex w-full h-full">
     <!-- 新增角色 -->
-    <addRole ref="addRoleRef" v-model="addRoleShow" />
+    <addRole
+      ref="addRoleRef"
+      v-model="addRoleShow"
+      @handleClick="postPageRoleApi"
+    />
     <!-- 新增角色组成员 -->
     <addPerson ref="addPersonRef" v-model="addPersonShow" />
     <!-- 主体内容 -->
@@ -140,42 +230,97 @@ const deltetePerson = item => {
       <div class="w-[100%]">
         <div><el-text type="info">系统角色</el-text></div>
       </div>
+      <!-- v-infinite-scroll="loadSystem" -->
       <div
-        v-for="item in rolesList.data"
-        :key="item.id"
-        class="w-[100%] flex justify-between items-center"
+        v-infinite-scroll="loadSystem"
+        infinite-scroll-immediate="false"
+        class="h-1/4 w-[100%] overflow-auto infinite-list"
       >
         <div
-          :class="[
-            'w-[100%] flex justify-between items-center mt-2 cursor-pointer',
-            { 'bg-blue-200': bgColor === item.id }
-          ]"
+          v-for="(item, index) in rolesList.data"
+          :key="index"
+          class="w-[100%] flex justify-between items-center"
         >
           <div
-            class="flex justify-between items-center"
-            @click="lookRoles(item)"
+            :class="[
+              'w-[100%] flex justify-between items-center mt-2 cursor-pointer',
+              { 'bg-blue-200': bgColor === item.id }
+            ]"
           >
-            <el-icon class="mr-2"><Avatar /></el-icon>
-            <el-text class="">{{ item.name }}</el-text>
+            <div
+              class="flex justify-between items-center"
+              @click="lookRoles(item)"
+            >
+              <el-icon class="mr-2"><Avatar /></el-icon>
+              <el-text class="">{{ item.roleName }}</el-text>
+            </div>
+            <div class="flex justify-between items-center">
+              <el-dropdown trigger="click">
+                <span>
+                  <el-icon><Operation /></el-icon>
+                </span>
+                <template #dropdown>
+                  <el-dropdown-menu class="setting">
+                    <el-dropdown-item @click="editRoleName(item)">
+                      编辑名称
+                    </el-dropdown-item>
+                    <el-dropdown-item>
+                      <el-link type="danger" @click="deleteRole(item)"
+                        >删除</el-link
+                      >
+                    </el-dropdown-item>
+                  </el-dropdown-menu>
+                </template>
+              </el-dropdown>
+            </div>
           </div>
-          <div class="flex justify-between items-center">
-            <el-dropdown trigger="click">
-              <span>
-                <el-icon><Operation /></el-icon>
-              </span>
-              <template #dropdown>
-                <el-dropdown-menu class="setting">
-                  <el-dropdown-item @click="editRoleName(item)">
-                    编辑名称
-                  </el-dropdown-item>
-                  <el-dropdown-item>
-                    <el-link type="danger" @click="deleteRole(item)"
-                      >删除</el-link
-                    >
-                  </el-dropdown-item>
-                </el-dropdown-menu>
-              </template>
-            </el-dropdown>
+        </div>
+      </div>
+      <el-divider />
+      <div class="w-[100%]">
+        <div><el-text type="info">自定义角色</el-text></div>
+      </div>
+      <div
+        v-infinite-scroll="load"
+        class="h-2/5 w-[100%] overflow-auto infinite-list"
+      >
+        <div
+          v-for="(item, index) in rolesList.dataUser"
+          :key="index"
+          class="w-[100%] flex justify-between items-center"
+        >
+          <div
+            :class="[
+              'w-[100%] flex justify-between items-center mt-2 cursor-pointer',
+              { 'bg-blue-200': bgColor === item.id }
+            ]"
+          >
+            <div
+              class="flex justify-between items-center"
+              @click="lookRoles(item)"
+            >
+              <el-icon class="mr-2"><Avatar /></el-icon>
+              <el-text class="">{{ item.roleName }}</el-text>
+            </div>
+            <div class="flex justify-between items-center">
+              <el-dropdown trigger="click">
+                <span>
+                  <el-icon><Operation /></el-icon>
+                </span>
+                <template #dropdown>
+                  <el-dropdown-menu class="setting">
+                    <el-dropdown-item @click="editRoleName(item)">
+                      编辑名称
+                    </el-dropdown-item>
+                    <el-dropdown-item>
+                      <el-link type="danger" @click="deleteRole(item)"
+                        >删除</el-link
+                      >
+                    </el-dropdown-item>
+                  </el-dropdown-menu>
+                </template>
+              </el-dropdown>
+            </div>
           </div>
         </div>
       </div>
@@ -200,12 +345,12 @@ const deltetePerson = item => {
             >
           </div>
           <el-table :data="tableData" style="width: 100%">
-            <el-table-column prop="date" label="姓名" />
-            <el-table-column prop="name" label="工号" />
-            <el-table-column prop="address" label="性别" />
-            <el-table-column prop="address" label="年龄" />
-            <el-table-column prop="address" label="职称" />
-            <el-table-column prop="address" label="部门" />
+            <el-table-column prop="realName" label="姓名" />
+            <el-table-column prop="hospitalCode" label="工号" />
+            <el-table-column prop="jobTitle" label="职称" />
+            <el-table-column prop="dept" label="部门" />
+            <el-table-column prop="phone" label="手机号" />
+            <!-- <el-table-column prop="address" label="部门" /> -->
             <el-table-column label="操作">
               <template #default="{ row }">
                 <el-dropdown trigger="click" class="mr-2">
@@ -281,6 +426,17 @@ const deltetePerson = item => {
   bottom: 70px;
   width: calc(100% - 50px);
 }
+
+.infinite-list {
+  -ms-overflow-style: none; /* IE和Edge */
+  scrollbar-width: none; /* Firefox */
+  // border: 1px solid red;
+}
+
+/* 隐藏滚动条 */
+.infinite-list::-webkit-scrollbar {
+  display: none; /* 对于 Webkit 浏览器(Chrome, Safari等) */
+}
 // ::v-deep .el-dropdown {
 //   line-height: 1;
 // }

+ 81 - 25
src/views/background/framework/users/components/addUsers.vue

@@ -1,19 +1,46 @@
 <script setup lang="ts">
 import { ref, reactive } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
+import { postAddUserGroup } from "@/api/userGroup";
+import { postAssignmentUser } from "@/api/userSetting";
+import { postPageRole } from "@/api/roles";
 const dialogVisibleAdd = ref(false);
+const emit = defineEmits(["handleClick"]);
 const dialogTitle = ref("");
 const dialogForm = ref(false);
 const form = reactive({
-  name: "",
-  region: "",
-  date1: "",
-  date2: "",
-  delivery: false,
-  type: [],
-  resource: "",
-  desc: ""
+  groupName: "",
+  groupCode: "",
+  leaderCode: ""
 });
+const rolesList = reactive({
+  list: [],
+  rolesName: "",
+  assignmentParams: {
+    sourceCodes: [],
+    targetCodes: [],
+    linkAction: "link",
+    correlatedModel: "groupRole"
+  }
+});
+const postAddUserGroupApi = async () => {
+  const { code } =
+    dialogTitle.value == "新建用户组"
+      ? await postAddUserGroup(form)
+      : await postAssignmentUser(rolesList.assignmentParams);
+  if (code === 200 && dialogTitle.value == "新建用户组") {
+    emit("handleClick");
+    ElMessage({
+      message: "添加成功",
+      type: "success"
+    });
+  } else {
+    ElMessage({
+      message: "添加成功",
+      type: "success"
+    });
+  }
+};
 const handleClose = () => {
   ElMessageBox.confirm("确认关闭弹窗吗?")
     .then(() => {
@@ -26,26 +53,43 @@ const handleClose = () => {
       // catch error
     });
 };
+// 角色数据
+
+const rolesData = async () => {
+  const { code, data } = await postPageRole({
+    pageNumber: 1,
+    pageSize: 100
+  });
+  if (code === 200) {
+    rolesList.list = data.records;
+  }
+};
+const changeRoles = () => {
+  // console.log(rolesList.rolesName);
+  rolesList.assignmentParams.sourceCodes = [];
+  rolesList.assignmentParams.sourceCodes.push(rolesList.rolesName);
+};
+
 // 添加部门保存
 const saveDepartment = () => {
   dialogVisibleAdd.value = false;
-  ElMessage({
-    message: "添加成功",
-    type: "success"
-  });
+  postAddUserGroupApi();
 };
 const open = item => {
   if (item) {
     dialogTitle.value = "配置角色";
-    form.name = item.name;
+    // console.log("部门", item);
+    rolesList.assignmentParams.targetCodes = [];
+    rolesList.assignmentParams.targetCodes.push(item.groupCode);
+    form.groupName = item.groupName;
     dialogForm.value = false;
   } else {
     dialogTitle.value = "新建用户组";
-    form.name = "";
+    form.groupName = "";
     dialogForm.value = true;
   }
   dialogVisibleAdd.value = true;
-  console.log(item);
+  rolesData();
 };
 defineExpose({
   open
@@ -56,7 +100,7 @@ defineExpose({
   <div>
     <el-dialog
       v-model="dialogVisibleAdd"
-      title="新增用户组"
+      :title="dialogTitle"
       width="500"
       :before-close="handleClose"
     >
@@ -67,7 +111,7 @@ defineExpose({
         style="max-width: 600px"
       >
         <el-form-item
-          prop="name"
+          prop="groupName"
           label="用户组名称"
           :rules="[
             {
@@ -77,23 +121,35 @@ defineExpose({
             }
           ]"
         >
-          <el-input v-model="form.name" placeholder="请输入" />
+          <el-input v-model="form.groupName" placeholder="请输入" />
         </el-form-item>
         <el-form-item label="用户组编号">
-          <el-input v-model="form.name" placeholder="请输入" />
+          <el-input v-model="form.groupCode" placeholder="请输入" />
         </el-form-item>
         <el-form-item label="用户组负责人">
-          <el-select v-model="form.name" placeholder="请选择">
-            <el-option label="Zone one" value="shanghai" />
-            <el-option label="Zone two" value="beijing" />
+          <el-select v-model="form.leaderCode" placeholder="请选择">
+            <el-option
+              v-for="(item, index) in rolesList.list"
+              :key="index"
+              :label="item.roleName"
+              :value="item.roleCode"
+            />
           </el-select>
         </el-form-item>
       </el-form>
       <el-form v-else :model="form" label-width="auto" style="max-width: 600px">
         <el-form-item label="配置角色">
-          <el-select v-model="form.name" placeholder="请选择">
-            <el-option label="Zone one" value="shanghai" />
-            <el-option label="Zone two" value="beijing" />
+          <el-select
+            v-model="rolesList.rolesName"
+            placeholder="请选择"
+            @change="changeRoles"
+          >
+            <el-option
+              v-for="(item, index) in rolesList.list"
+              :key="index"
+              :label="item.roleName"
+              :value="item.roleCode"
+            />
           </el-select>
         </el-form-item>
       </el-form>

+ 38 - 13
src/views/background/framework/users/components/editPerson.vue

@@ -2,15 +2,27 @@
 import { ref, reactive } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 import type { DrawerProps, FormItemProps, FormProps } from "element-plus";
-// const itemLabelPosition = ref<FormItemProps["labelPosition"]>("");
+import { postUpdateGroupByCode } from "@/api/userGroup";
 const drawer = ref(false);
+const emit = defineEmits(["handleClick"]);
 const disabledValue = ref(true);
 const direction = ref<DrawerProps["direction"]>("rtl");
 const formLabelAlign = reactive({
-  name: "",
-  region: "",
-  type: ""
+  groupName: "",
+  leaderCode: "",
+  groupCode: "",
+  hospitalCode: ""
 });
+const postUpdateGroupByCodeApi = async () => {
+  const { code } = await postUpdateGroupByCode(formLabelAlign);
+  if (code === 200) {
+    emit("handleClick");
+    ElMessage({
+      message: "保存成功",
+      type: "success"
+    });
+  }
+};
 const handleClose = (done: () => void) => {
   ElMessageBox.confirm("配置项未保存,确认关闭", {
     type: "warning"
@@ -26,21 +38,25 @@ function cancelClick() {
   editShow.value = true;
 }
 function confirmClick() {
-  console.log(1111);
   disabledValue.value = true;
   editShow.value = true;
   drawer.value = !drawer.value;
-  ElMessage({
-    message: "保存成功",
-    type: "success"
-  });
+  postUpdateGroupByCodeApi();
 }
 const open = row => {
+  if (row) {
+    console.log("11111", row);
+    formLabelAlign.groupName = row.groupName;
+    formLabelAlign.leaderCode = row.leaderCode;
+    formLabelAlign.groupCode = row.groupCode;
+    formLabelAlign.hospitalCode = row.hospitalCode;
+  }
   drawer.value = true;
 };
 const editShow = ref(true);
 // 编辑
 const editClick = () => {
+  console.log("11111", formLabelAlign);
   editShow.value = false;
   disabledValue.value = false;
 };
@@ -68,16 +84,25 @@ const timer = ref("");
             :model="formLabelAlign"
           >
             <el-form-item label="用户组名称" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.groupName"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="用户组编号" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.groupCode"
+                :disabled="disabledValue"
+              />
             </el-form-item>
             <el-form-item label="用户组ID" label-position="top">
-              <el-input disabled />
+              <el-input v-model="formLabelAlign.hospitalCode" disabled />
             </el-form-item>
             <el-form-item label="用户组负责人" label-position="top">
-              <el-input :disabled="disabledValue" />
+              <el-input
+                v-model="formLabelAlign.leaderCode"
+                :disabled="disabledValue"
+              />
             </el-form-item>
           </el-form>
         </div>

+ 126 - 57
src/views/background/framework/users/index.vue

@@ -9,6 +9,9 @@ import { Search } from "@element-plus/icons-vue";
 import addPerson from "./components/addPerson.vue";
 import addUsers from "./components/addUsers.vue";
 import editPerson from "./components/editPerson.vue";
+import { postPageGroup, postDelUserGroup } from "@/api/userGroup";
+import UserPageTable from "@/components/UserPageTable/index.vue";
+
 // 新增用户组
 const addUsersRef = ref();
 const addUsersShow = ref(false);
@@ -18,7 +21,8 @@ const addPersonShow = ref(false);
 // 编辑
 const editPersonRef = ref();
 const editPersonShow = ref(false);
-
+// table表格
+const UserTable = ref();
 const tableData = [
   {
     date: "2016-05-03",
@@ -42,22 +46,41 @@ const tableData = [
   }
 ];
 const rolesList = reactive({
-  data: [
-    { name: "管理员", id: 1 },
-    { name: "科室主任", id: 2 },
-    { name: "医生", id: 3 },
-    { name: "员工", id: 4 },
-    { name: "张三", id: 5 },
-    { name: "李四", id: 6 }
-  ],
-  rolesName: ""
+  data: [],
+  rolesName: "",
+  params: {
+    pageNumber: 1,
+    pageSize: 10,
+    groupName: ""
+  }
 });
+const load = () => {
+  rolesList.params.pageSize += 10;
+  postPageGroupApi();
+};
+// 用户组分页
+const postPageGroupApi = async () => {
+  const { code, data } = await postPageGroup(rolesList.params);
+  if (code === 200) {
+    rolesList.data = [];
+    data.records.forEach((item, index) => {
+      rolesList.data.push({
+        ...item,
+        id: index + 1
+      });
+    });
+  }
+};
+postPageGroupApi();
+
 // 查看角色组
 const bgColor = ref(null);
 const lookRoles = item => {
-  console.log(item);
+  console.log("111", item);
   bgColor.value = item.id;
-  rolesList.rolesName = item.name;
+  rolesList.rolesName = item.groupName;
+  UserTable.value.handleNodeClick(item, "group");
+  console.log(UserTable.value);
 };
 // 标签选择
 const activeName = ref("first");
@@ -66,9 +89,20 @@ const handleClick = (tab, event) => {
   console.log(tab, event);
 };
 // 删除用户组
+const postDelUserGroupApi = async row => {
+  const { code } = await postDelUserGroup(row);
+  if (code === 200) {
+    postPageGroupApi();
+    ElMessage({
+      type: "success",
+      message: "删除成功"
+    });
+  }
+};
 const deleteUsers = row => {
+  console.log(row);
   ElMessageBox.confirm(
-    `角色删除不能恢复,是否确认删除用户组【${row.name}】吗`,
+    `角色删除不能恢复,是否确认删除用户组【${row.groupName}】吗`,
     "确定删除该用户组吗?",
     {
       confirmButtonText: "确定",
@@ -76,16 +110,12 @@ const deleteUsers = row => {
       type: "warning"
     }
   ).then(() => {
-    ElMessage({
-      type: "success",
-      message: "删除成功"
-    });
+    postDelUserGroupApi(row);
   });
 };
 const AddUsersPerson = () => {
   addPersonRef.value.open();
 };
-// 新增用户组
 const addUsersList = () => {
   addUsersRef.value.open();
 };
@@ -126,61 +156,78 @@ const deltetePerson = row => {
   <div class="flex w-full h-full">
     <!-- 添加成员 -->
     <addPerson ref="addPersonRef" v-model="addPersonShow" />
-    <!-- 添加成员 -->
-    <addUsers ref="addUsersRef" v-model="addUsersShow" />
+    <!-- 添加用户组 -->
+    <addUsers
+      ref="addUsersRef"
+      v-model="addUsersShow"
+      @handleClick="postPageGroupApi"
+    />
     <!-- 编辑 -->
-    <editPerson ref="editPersonRef" v-model="editPersonShow" />
+    <editPerson
+      ref="editPersonRef"
+      v-model="editPersonShow"
+      @handleClick="postPageGroupApi"
+    />
     <!-- 主体内容 -->
     <div class="box-left">
       <div class="w-[100%]">
         <div>
           <el-input
+            v-model="rolesList.params.groupName"
             placeholder="搜索姓名"
             class="mb-2"
+            clearable
             style="max-width: 300px"
             :prefix-icon="Search"
+            @change="postPageGroupApi"
           />
         </div>
       </div>
       <div
-        v-for="item in rolesList.data"
-        :key="item.id"
-        class="w-[100%] flex justify-between items-center"
+        v-infinite-scroll="load"
+        infinite-scroll-immediate="false"
+        class="h-2/3 w-[100%] overflow-auto infinite-list"
       >
         <div
-          :class="[
-            'w-[100%] flex justify-between items-center mt-2 cursor-pointer',
-            { 'bg-blue-200': bgColor === item.id }
-          ]"
+          v-for="item in rolesList.data"
+          :key="item.id"
+          class="w-[100%] flex justify-between items-center"
         >
           <div
-            class="flex justify-between items-center'"
-            @click="lookRoles(item)"
+            :class="[
+              'w-[100%] flex justify-between items-center mt-2 cursor-pointer',
+              { 'bg-blue-200': bgColor === item.id }
+            ]"
           >
-            <el-icon class="mr-2"><Avatar /></el-icon>
-            <el-text class="">{{ item.name }}</el-text>
-          </div>
-          <div class="flex justify-between items-center">
-            <el-dropdown trigger="click">
-              <span>
-                <el-icon><Operation /></el-icon>
-              </span>
-              <template #dropdown>
-                <el-dropdown-menu class="setting">
-                  <el-dropdown-item @click="editUsers(item)">
-                    编辑
-                  </el-dropdown-item>
-                  <el-dropdown-item @click="changeUsers(item)">
-                    配置角色
-                  </el-dropdown-item>
-                  <el-dropdown-item>
-                    <el-link type="danger" @click="deleteUsers(item)"
-                      >删除</el-link
-                    >
-                  </el-dropdown-item>
-                </el-dropdown-menu>
-              </template>
-            </el-dropdown>
+            <div
+              class="flex justify-between items-center'"
+              @click="lookRoles(item)"
+            >
+              <el-icon class="mr-2"><Avatar /></el-icon>
+              <el-text class="">{{ item.groupName }}</el-text>
+            </div>
+            <div class="flex justify-between items-center">
+              <el-dropdown trigger="click">
+                <span>
+                  <el-icon><Operation /></el-icon>
+                </span>
+                <template #dropdown>
+                  <el-dropdown-menu class="setting">
+                    <el-dropdown-item @click="editUsers(item)">
+                      编辑
+                    </el-dropdown-item>
+                    <el-dropdown-item @click="changeUsers(item)">
+                      配置角色
+                    </el-dropdown-item>
+                    <el-dropdown-item>
+                      <el-link type="danger" @click="deleteUsers(item)"
+                        >删除</el-link
+                      >
+                    </el-dropdown-item>
+                  </el-dropdown-menu>
+                </template>
+              </el-dropdown>
+            </div>
           </div>
         </div>
       </div>
@@ -189,9 +236,10 @@ const deltetePerson = row => {
         >新增用户组</el-button
       >
     </div>
-    <div v-if="rolesList.rolesName" class="box-right">
+    <!-- <div v-if="rolesList.rolesName" class="box-right"> -->
+    <div class="box-right">
       <h3>{{ rolesList.rolesName }}</h3>
-      <div class="flex justify-between mb-3">
+      <!-- <div class="flex justify-between mb-3">
         <el-input
           placeholder="搜索医生姓名"
           class="mb-2"
@@ -216,7 +264,17 @@ const deltetePerson = row => {
             </el-dropdown>
           </template>
         </el-table-column>
-      </el-table>
+      </el-table> -->
+      <UserPageTable ref="UserTable">
+        <template #add-button>
+          <el-button type="primary" @click="AddUsersPerson">添加成员</el-button>
+        </template>
+        <template #actions="{ row }">
+          <el-dropdown trigger="click" class="mr-2">
+            <el-text type="danger" @click="deltetePerson(row)"> 移除 </el-text>
+          </el-dropdown>
+        </template>
+      </UserPageTable>
     </div>
   </div>
 </template>
@@ -245,6 +303,17 @@ const deltetePerson = row => {
 .userName {
   background-color: #022bbd80;
 }
+
+.infinite-list {
+  -ms-overflow-style: none; /* IE和Edge */
+  scrollbar-width: none; /* Firefox */
+  // border: 1px solid red;
+}
+
+/* 隐藏滚动条 */
+.infinite-list::-webkit-scrollbar {
+  display: none; /* 对于 Webkit 浏览器(Chrome, Safari等) */
+}
 // ::v-deep .el-dropdown {
 //   line-height: 1;
 // }

+ 1 - 3
src/views/evaluate/children/change/components/evaluate.ts

@@ -195,7 +195,6 @@ class Counter {
 
   // 词法分析,将字符串分割为token
   private tokenize(expression: string): Array<string> {
-    // 使用正则表达式来允许负数
     return expression.match(/-?\d+(\.\d+)?|[-+*/()]/g) || [];
   }
 
@@ -253,7 +252,6 @@ class Counter {
 
   private showWarning(message: string): void {
     // 假设 ElMessage 是某个库的消息提示函数
-    // 假设 ElMessage 是某个库的消息提示函数
     ElMessage({
       message: message,
       type: "warning"
@@ -263,7 +261,6 @@ class Counter {
   // 计算解析后的表达式
   private evaluate(parsedExpression: Array<Decimal | string>): number {
     const stack: Array<Decimal> = [];
-
     for (const token of parsedExpression) {
       if (token instanceof Decimal) {
         stack.push(token);
@@ -294,6 +291,7 @@ class Counter {
     return stack[0].toNumber(); // 返回计算结果
   }
 }
+
 // 使用示例
 // const calculator = new Counter();
 // calculator.calculate("3.5 + 2.3 * (2 - 8)");

+ 490 - 165
src/views/evaluate/children/change/components/settingIndexDrawer.vue

@@ -11,7 +11,7 @@ const formLabelAlign = reactive({
   name: "",
   region: "",
   grade: "",
-  compute: "",
+  compute: "1",
   type: ""
 });
 const handleClose = (done: () => void) => {
@@ -104,24 +104,181 @@ const removeVoid = () => {
 const count = item => {
   try {
     calculator.calculate(rolesList.value);
-    // console.log(calculator.get()); // 输出结果
     rolesList.num = calculator.get();
-    // if (calculator.get()) {
-    // } else {
-    //   rolesList.num = 0;
-    //   ElMessage({
-    //     message: "计算错误",
-    //     type: "warning"
-    //   });
-    // }
   } catch (error) {
-    // ElMessage({
-    //   message: "计算错误",
-    //   type: "warning"
-    // });
+    ElMessage({
+      message: "计算错误",
+      type: "warning"
+    });
     console.log(error);
   }
 };
+// 多条件公式
+const manyChange = reactive({
+  newData: "",
+  dataList: [
+    {
+      compare: "0", // 比较符号
+      compareList: [
+        {
+          value: "0",
+          label: ">"
+        },
+        {
+          value: "1",
+          label: "≥"
+        }
+      ],
+      formula: "0",
+      formulaList: [
+        {
+          value: "0",
+          label: "数值"
+        },
+        {
+          value: "1",
+          label: "公式"
+        }
+      ],
+      value: "",
+      newData: "",
+      dataList: [
+        {
+          compare: "0", // 比较符号
+          compareList: [
+            {
+              value: "0",
+              label: ">"
+            },
+            {
+              value: "1",
+              label: "≥"
+            }
+          ],
+          formula: "0",
+          formulaList: [
+            {
+              value: "0",
+              label: "数值"
+            },
+            {
+              value: "1",
+              label: "公式"
+            }
+          ],
+          value: "",
+          grade: ""
+        }
+      ]
+    }
+  ]
+});
+const deleteItem = index => {
+  if (manyChange.dataList.length > 1) {
+    manyChange.dataList.splice(index, 1);
+  } else {
+    ElMessage({
+      message: "必须保留一条计算规则",
+      type: "warning"
+    });
+  }
+};
+const dataleListItem = (index, indexList) => {
+  if (manyChange.dataList[index].dataList.length > 1) {
+    manyChange.dataList[index].dataList.splice(indexList, 1);
+  } else {
+    ElMessage({
+      message: "必须保留一条计算规则",
+      type: "warning"
+    });
+  }
+};
+const addNewItem = () => {
+  manyChange.dataList.push({
+    compare: "0", // 比较符号
+    compareList: [
+      {
+        value: "0",
+        label: ">"
+      },
+      {
+        value: "1",
+        label: "≥"
+      }
+    ],
+    formula: "0",
+    formulaList: [
+      {
+        value: "0",
+        label: "数值"
+      },
+      {
+        value: "1",
+        label: "公式"
+      }
+    ],
+    value: "",
+    newData: "",
+    dataList: [
+      {
+        compare: "0", // 比较符号
+        compareList: [
+          {
+            value: "0",
+            label: ">"
+          },
+          {
+            value: "1",
+            label: "≥"
+          }
+        ],
+        formula: "0",
+        formulaList: [
+          {
+            value: "0",
+            label: "数值"
+          },
+          {
+            value: "1",
+            label: "公式"
+          }
+        ],
+        value: "",
+        grade: ""
+      }
+    ]
+  });
+};
+const addItemDataList = (index: number, itemListValue: string) => {
+  console.log(index, itemListValue);
+  manyChange.dataList[index].dataList.push({
+    title: itemListValue,
+    compare: "0", // 比较符号
+    compareList: [
+      {
+        value: "0",
+        label: ">"
+      },
+      {
+        value: "1",
+        label: "≥"
+      }
+    ],
+    formula: "0",
+    formulaList: [
+      {
+        value: "0",
+        label: "数值"
+      },
+      {
+        value: "1",
+        label: "公式"
+      }
+    ],
+    value: "",
+    grade: ""
+  });
+};
 </script>
 
 <template>
@@ -182,184 +339,339 @@ const count = item => {
                 label-position="top"
               >
                 <div>
-                  <el-text>得分 =</el-text>
-                  <el-input
-                    v-model="rolesList.num"
-                    class="ml-2 mr-2"
-                    style="width: 240px"
-                  />
-                  <el-text>
-                    <el-button type="primary">公式验证</el-button>
-                  </el-text>
-                </div>
-                <div
-                  class="w-[500px] compute h-64 mt-1 ml-12 flex justify-evenly items-center"
-                  style="user-select: none"
-                >
-                  <div class="w-1/3 h-60 pl-1 bg-white rounded-md">
-                    <div class="w-[100%] text-xs mt-2">
-                      <div><el-text type="info">::变量</el-text></div>
-                    </div>
-                    <div v-for="item in rolesList.data" :key="item.id">
-                      <div
-                        :class="[
-                          'cursor-pointer text-xs mt-1',
-                          { 'bg-blue-200': bgColor === item.id }
-                        ]"
-                        @click="lookRoles(item)"
-                      >
-                        <el-text class="">{{ item.name }}</el-text>
-                      </div>
-                    </div>
+                  <div>
+                    <el-text>得分 =</el-text>
+                    <el-input
+                      v-model="rolesList.num"
+                      class="ml-2 mr-2"
+                      style="width: 240px"
+                    />
+                    <el-text>
+                      <el-button type="primary">公式验证</el-button>
+                    </el-text>
                   </div>
-                  <div class="w-3/5 ml-2 h-60 flex flex-col">
-                    <div class="w-[100%] text-xs h-24 bg-white rounded-md">
-                      <div class="p-1"><el-text>得分 = </el-text></div>
-                      <!-- style="height: 95px" -->
-                      <el-input
-                        v-model="rolesList.value"
-                        :rows="3"
-                        type="textarea"
-                        placeholder=""
-                      />
-                    </div>
-                    <div class="w-[100%] h-32 mt-2 rounded-md flex flex-col">
-                      <div class="flex justify-between h-8">
-                        <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('1')"
-                        >
-                          1
-                        </div>
+                  <div
+                    class="w-[500px] compute h-64 mt-1 ml-12 flex justify-evenly items-center"
+                    style="user-select: none"
+                  >
+                    <div class="w-1/3 h-60 pl-1 bg-white rounded-md">
+                      <div class="w-[100%] text-xs mt-2">
+                        <div><el-text type="info">::变量</el-text></div>
+                      </div>
+                      <div v-for="item in rolesList.data" :key="item.id">
                         <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('2')"
+                          :class="[
+                            'cursor-pointer text-xs mt-1',
+                            { 'bg-blue-200': bgColor === item.id }
+                          ]"
+                          @click="lookRoles(item)"
                         >
-                          2
+                          <el-text class="">{{ item.name }}</el-text>
                         </div>
-                        <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('3')"
-                        >
-                          3
+                      </div>
+                    </div>
+                    <div class="w-3/5 ml-2 h-60 flex flex-col">
+                      <div class="w-[100%] text-xs h-24 bg-white rounded-md">
+                        <div class="p-1"><el-text>得分 = </el-text></div>
+                        <!-- style="height: 95px" -->
+                        <el-input
+                          v-model="rolesList.value"
+                          :rows="3"
+                          disabled
+                          type="textarea"
+                          placeholder='示例:"完成值" / "目标值" * 100'
+                        />
+                      </div>
+                      <div class="w-[100%] h-32 mt-2 rounded-md flex flex-col">
+                        <div class="flex justify-between h-8">
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('1')"
+                          >
+                            1
+                          </div>
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('2')"
+                          >
+                            2
+                          </div>
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('3')"
+                          >
+                            3
+                          </div>
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('+')"
+                          >
+                            +
+                          </div>
+                          <div
+                            class="h-full w-[50px] text-white bg-orange-400 mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="remove"
+                          >
+                            x
+                          </div>
                         </div>
-                        <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('+')"
-                        >
-                          +
+                        <div class="flex justify-between h-8 mt-1">
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('4')"
+                          >
+                            4
+                          </div>
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('5')"
+                          >
+                            5
+                          </div>
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('6')"
+                          >
+                            6
+                          </div>
+                          <div
+                            class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="countNumber('-')"
+                          >
+                            -
+                          </div>
+                          <div
+                            class="text-xs h-full w-[50px] text-white bg-orange-400 mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                            @click="removeVoid"
+                          >
+                            清空
+                          </div>
                         </div>
-                        <div
-                          class="h-full w-[50px] text-white bg-orange-400 mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="remove"
-                        >
-                          x
+                        <div class="flex justify-between h-16 mt-1">
+                          <div>
+                            <div class="flex justify-between">
+                              <div
+                                class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                                @click="countNumber('7')"
+                              >
+                                7
+                              </div>
+                              <div
+                                class="h-full ml-1 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                                @click="countNumber('8')"
+                              >
+                                8
+                              </div>
+                              <div
+                                class="h-full ml-2 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                                @click="countNumber('9')"
+                              >
+                                9
+                              </div>
+                              <div
+                                class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                                @click="countNumber('*')"
+                              >
+                                *
+                              </div>
+                            </div>
+                            <div class="flex mt-1 justify-between">
+                              <div
+                                class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                                @click="countNumber('0')"
+                              >
+                                0
+                              </div>
+                              <div
+                                class="h-full ml-1 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                                @click="countNumber('.')"
+                              >
+                                .
+                              </div>
+                              <div
+                                class="h-full ml-2 w-[50px] bg-white mx-1 flex justify-between items-center rounded-lg cursor-pointer"
+                              >
+                                <div
+                                  class="w-1/2 h-full text-center border-r text-gray-100"
+                                  @click="countNumber('(')"
+                                >
+                                  <span class="text-black"> (</span>
+                                </div>
+                                <div
+                                  class="w-1/2 h-full text-center"
+                                  @click="countNumber(')')"
+                                >
+                                  )
+                                </div>
+                              </div>
+                              <div
+                                class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                                @click="countNumber('/')"
+                              >
+                                /
+                              </div>
+                            </div>
+                          </div>
+                          <div
+                            class="h-full mr-1 w-[50px] text-white flex justify-center items-center rounded-lg cursor-pointer areYouOK"
+                            @click="count"
+                          >
+                            确认
+                          </div>
                         </div>
                       </div>
-                      <div class="flex justify-between h-8 mt-1">
-                        <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('4')"
-                        >
-                          4
-                        </div>
-                        <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('5')"
-                        >
-                          5
-                        </div>
-                        <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('6')"
-                        >
-                          6
+                    </div>
+                  </div>
+                </div>
+              </el-form-item>
+              <el-form-item v-else label="公式设置">
+                <div class="w-full">
+                  <div class="flex items-center">
+                    <el-text>条件填 = </el-text>
+                    <el-input
+                      v-model="manyChange.newData"
+                      class="ml-2"
+                      style="width: 240px"
+                    />
+                  </div>
+                  <div class="w-full mt-2">
+                    <div
+                      v-for="(item, index) in manyChange.dataList"
+                      :key="index"
+                      class="flex items-center mb-4"
+                    >
+                      <div>
+                        <div class="flex">
+                          <el-text class="w-[30px]" type="primary">
+                            {{ index + 1 }}
+                          </el-text>
+                          <div class="mr-2">条件值</div>
+                          <el-select
+                            v-model="item.compare"
+                            style="width: 60px"
+                            placeholder=""
+                          >
+                            <el-option
+                              v-for="compareItem in item.compareList"
+                              :key="compareItem.value"
+                              :label="compareItem.label"
+                              :value="compareItem.value"
+                            />
+                          </el-select>
+                          <el-select
+                            v-model="item.formula"
+                            class="ml-2"
+                            style="width: 80px"
+                            placeholder=""
+                          >
+                            <el-option
+                              v-for="formulaItem in item.formulaList"
+                              :key="formulaItem.value"
+                              :label="formulaItem.label"
+                              :value="formulaItem.value"
+                            />
+                          </el-select>
+                          <el-input
+                            v-model="item.value"
+                            class="ml-2 mr-5"
+                            style="width: 80px"
+                          />
+                          <el-text type="danger" @click="deleteItem(index)">
+                            <el-icon><Delete /></el-icon>
+                          </el-text>
                         </div>
-                        <div
-                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="countNumber('-')"
-                        >
-                          -
+                        <div class="flex mt-2 ml-7">
+                          <div class="mr-2">条件值{{ index + 1 }} =</div>
+                          <el-input
+                            v-model="item.value"
+                            class="ml-2"
+                            style="width: 240px"
+                          />
                         </div>
                         <div
-                          class="text-xs h-full w-[50px] text-white bg-orange-400 mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                          @click="removeVoid"
+                          v-for="(itemList, indexList) in item.dataList"
+                          :key="indexList"
                         >
-                          清空
-                        </div>
-                      </div>
-                      <div class="flex justify-between h-16 mt-1">
-                        <div>
-                          <div class="flex justify-between">
-                            <div
-                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('7')"
-                            >
-                              7
-                            </div>
-                            <div
-                              class="h-full ml-1 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('8')"
-                            >
-                              8
-                            </div>
-                            <div
-                              class="h-full ml-2 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('9')"
-                            >
-                              9
+                          <div class="flex mt-2 ml-7 items-center">
+                            <div class="text_border">{{ indexList + 1 }}</div>
+                            <!-- manyChange.dataList[index].dataList -->
+                            <div class="w-[40px] ml-2">
+                              {{ itemList?.title }}
                             </div>
-                            <div
-                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('*')"
+                            <div class="mr-2">></div>
+                            <div class="mr-2">条件值{{ indexList + 1 }}</div>
+                            <el-select
+                              v-model="itemList.compare"
+                              style="width: 60px"
+                              placeholder=""
                             >
-                              *
-                            </div>
-                          </div>
-                          <div class="flex mt-1 justify-between">
-                            <div
-                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('0')"
+                              <el-option
+                                v-for="compareItem in itemList.compareList"
+                                :key="compareItem.value"
+                                :label="compareItem.label"
+                                :value="compareItem.value"
+                              />
+                            </el-select>
+                            <el-select
+                              v-model="itemList.formula"
+                              class="ml-2"
+                              style="width: 80px"
+                              placeholder=""
                             >
-                              0
-                            </div>
+                              <el-option
+                                v-for="formulaItem in itemList.formulaList"
+                                :key="formulaItem.value"
+                                :label="formulaItem.label"
+                                :value="formulaItem.value"
+                              />
+                            </el-select>
+                            <el-input
+                              v-model="itemList.value"
+                              class="ml-2"
+                              style="width: 80px"
+                            />
                             <div
-                              class="h-full ml-1 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('.')"
+                              class="w-[100px] ml-2 mr-2 flex justify-between items-center"
                             >
-                              .
+                              <div>得分</div>
+                              <div>=</div>
+                              <el-input
+                                v-model="itemList.grade"
+                                class="ml-2"
+                                style="width: 50px"
+                              />
                             </div>
-                            <div
-                              class="h-full ml-2 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('()')"
+                            <el-text
+                              type="danger"
+                              @click="dataleListItem(index, indexList)"
                             >
-                              ()
-                            </div>
-                            <div
-                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
-                              @click="countNumber('/')"
+                              <el-icon><Delete /></el-icon>
+                            </el-text>
+                          </div>
+                          <div
+                            v-if="indexList + 1 == item.dataList.length"
+                            class="ml-7 mt-1 text-xs cursor-pointer"
+                          >
+                            <el-text
+                              type="primary"
+                              @click="addItemDataList(index, itemList.value)"
                             >
-                              /
-                            </div>
+                              <el-icon><Plus /></el-icon>
+                              添加条件
+                            </el-text>
                           </div>
                         </div>
-                        <div
-                          class="h-full mr-1 w-[50px] text-white flex justify-center items-center rounded-lg cursor-pointer areYouOK"
-                          @click="count"
-                        >
-                          确认
-                        </div>
                       </div>
                     </div>
+                    <div class="mt-5 text-xs cursor-pointer">
+                      <el-text type="primary" @click="addNewItem">
+                        <el-icon><Plus /></el-icon>
+                        添加条件
+                      </el-text>
+                    </div>
                   </div>
                 </div>
               </el-form-item>
-              <el-form-item v-else label="公式设置">
-                <div>
-                  <el-text>条件填 = </el-text
-                  ><el-input v-model="formLabelAlign.name" />
-                </div>
-              </el-form-item>
             </div>
           </el-form>
         </div>
@@ -387,4 +699,17 @@ const count = item => {
 .areYouOK {
   background-color: #409eff;
 }
+
+.text_border {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 14px;
+  height: 14px;
+  // margin-top: 5px;
+  margin-right: 5px;
+  font-size: 12px;
+  border: 1px solid gray;
+  border-radius: 50%;
+}
 </style>

+ 43 - 14
src/views/login/index.vue

@@ -10,14 +10,20 @@ import { useUserStoreHook } from "@/store/modules/user";
 import { initRouter, getTopMenu } from "@/router/utils";
 import { bg, avatar, illustration } from "./utils/static";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
-import { ref, reactive, toRaw, onMounted, onBeforeUnmount } from "vue";
+import {
+  ref,
+  reactive,
+  toRaw,
+  onMounted,
+  onBeforeUnmount,
+  computed
+} from "vue";
 import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
-
+import { encryption } from "@/utils/encrypt";
 import dayIcon from "@/assets/svg/day.svg?component";
 import darkIcon from "@/assets/svg/dark.svg?component";
 import Lock from "@iconify-icons/ri/lock-fill";
 import User from "@iconify-icons/ri/user-3-fill";
-
 defineOptions({
   name: "Login"
 });
@@ -33,10 +39,15 @@ dataThemeChange();
 const { title } = useNav();
 
 const ruleForm = reactive({
-  username: "",
-  password: ""
+  username: "admin",
+  password: "123456"
 });
-
+const handleBlur = () => {
+  // @ts-ignore
+  localStorage.setItem("password", ruleForm.password);
+  // @ts-ignore
+  localStorage.setItem("rolesName", ruleForm.username);
+};
 const onLogin = async (formEl: FormInstance | undefined) => {
   loading.value = true;
   if (!formEl) return;
@@ -44,17 +55,34 @@ const onLogin = async (formEl: FormInstance | undefined) => {
     if (valid) {
       useUserStoreHook()
         .loginByUsername({
-          username: ruleForm.username,
-          password: ruleForm.password
+          username: encryption(ruleForm.username),
+          password: encryption(ruleForm.password)
+          // username: ruleForm.username,
+          // password: ruleForm.password
         })
         .then(res => {
-          if (res.success) {
-            // 获取后端路由
-            initRouter().then(() => {
-              router.push(getTopMenu(true).path);
-              message("登录成功", { type: "success" });
-            });
+          // console.log(res);
+          // @ts-ignore
+          if (res.code === 200) {
+            // @ts-ignore
+            localStorage.setItem("token", res.data.token);
+            // @ts-ignore
+            localStorage.setItem("userName", res.data.realName);
+            // initRouter().then(() => {
+            //   // router.push(getTopMenu(true).path);
+            //   router.push("/");
+            //   message("登录成功", { type: "success" });
+            // });
+            router.push("/");
+            message("登录成功", { type: "success" });
           }
+          // if (res.success) {
+          //   // 获取后端路由
+          //   initRouter().then(() => {
+          //     router.push(getTopMenu(true).path);
+          //     message("登录成功", { type: "success" });
+          //   });
+          // }
         });
     } else {
       loading.value = false;
@@ -145,6 +173,7 @@ onBeforeUnmount(() => {
                       show-password
                       placeholder="密码"
                       :prefix-icon="useRenderIcon(Lock)"
+                      @blur="handleBlur"
                     />
                   </el-form-item>
                 </Motion>

+ 96 - 15
src/views/password/index.vue

@@ -3,36 +3,122 @@ defineOptions({
   name: "possword"
 });
 import { reactive, ref } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { postUpdatePassword } from "@/api/password";
+const router = useRouter();
+const formRef = ref();
 const formLabelAlign = reactive({
   name: "",
-  region: "",
-  type: ""
+  oldPwd: "",
+  newPwd: "",
+  reNewPwd: ""
 });
+const passWord = ref("");
+passWord.value = localStorage.getItem("password");
+formLabelAlign.name = localStorage.getItem("userName");
+const UpdatePasswordApi = async () => {
+  formRef.value.validate(async (valid: boolean) => {
+    console.log(valid);
+    if (valid) {
+      const { code } = await postUpdatePassword(formLabelAlign);
+      if (code === 200) {
+        ElMessage({
+          message: "修改成功",
+          type: "success"
+        });
+        ElMessageBox.confirm("密码已修改请重新登录", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          localStorage.clear();
+          router.push("/login");
+        });
+      } else {
+        ElMessage({
+          message: "修改失败",
+          type: "error"
+        });
+      }
+    } else {
+      return;
+    }
+  });
+};
+const rules = {
+  oldPwd: [
+    { required: true, message: "请输入密码", trigger: "blur" },
+    {
+      validator: (rule, value, callback) => {
+        if (value !== passWord.value) {
+          callback(new Error("旧密码不正确"));
+        } else {
+          callback();
+        }
+      },
+      trigger: "blur"
+    }
+  ],
+  newPwd: [
+    { required: true, message: "请输入 6 - 14 位密码", trigger: "blur" },
+    {
+      min: 6,
+      max: 14,
+      message: "请输入 6 - 14 位密码",
+      trigger: "blur"
+    }
+  ],
+  reNewPwd: [
+    { required: true, message: "请再次输入新密码", trigger: "blur" },
+    {
+      validator: (rule, value, callback) => {
+        if (value !== formLabelAlign.newPwd) {
+          callback(new Error("两次输入的密码不一致"));
+        } else {
+          callback();
+        }
+      },
+      trigger: "blur"
+    }
+  ]
+};
 </script>
 
 <template>
   <div class="box">
     <el-form
+      ref="formRef"
       class="m-auto form"
       label-position="top"
       label-width="auto"
+      status-icon
+      :rules="rules"
       :model="formLabelAlign"
       style="max-width: 400px"
     >
       <el-form-item label="账号">
-        <el-input v-model="formLabelAlign.name" />
+        <el-input v-model="formLabelAlign.name" disabled />
       </el-form-item>
-      <el-form-item label="密码">
-        <el-input v-model="formLabelAlign.region" />
+      <el-form-item label="密码" prop="oldPwd">
+        <el-input v-model="formLabelAlign.oldPwd" />
       </el-form-item>
-      <el-form-item label="新密码">
-        <el-input v-model="formLabelAlign.type" />
+      <el-form-item label="新密码" prop="newPwd">
+        <el-input
+          v-model="formLabelAlign.newPwd"
+          type="password"
+          show-password
+        />
       </el-form-item>
-      <el-form-item label="再次输入密码">
-        <el-input v-model="formLabelAlign.type" />
+      <el-form-item label="再次输入密码" prop="reNewPwd">
+        <el-input
+          v-model="formLabelAlign.reNewPwd"
+          type="password"
+          show-password
+        />
       </el-form-item>
       <el-form-item label="">
-        <el-button type="primary">提交</el-button>
+        <el-button type="primary" @click="UpdatePasswordApi()">提交</el-button>
       </el-form-item>
     </el-form>
   </div>
@@ -40,11 +126,6 @@ const formLabelAlign = reactive({
 
 <style lang="scss" scoped>
 .form {
-  // all: unset;
-  // position: absolute;
-  // top: 50%;
-  // left: 50%;
-  // transform: translate(-50%, -65%);
   margin-top: 10%;
 }
 </style>