Browse Source

登录,权限对接

guicheng 7 months ago
parent
commit
30dfa43c5c

+ 4 - 5
src/api/apiResult.ts

@@ -1,14 +1,13 @@
 /*
  * @Author: Gui
  * @Date: 2023-03-01 19:20:44
- * @LastEditors: Please set LastEditors
- * @LastEditTime: 2024-03-13 17:38:40
+ * @LastEditors: guicheng 1625811865@qq.com
+ * @LastEditTime: 2024-04-11 16:55:45
  * @Description: kxs files
  * @filePath:
  */
 export type dataResult = {
-  status: String;
-  message?: String;
-  info?: any;
+  status: number;
+  msg: string;
   data: any;
 };

+ 171 - 44
src/api/system.ts

@@ -2,91 +2,218 @@
  * @Author: Gui
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: guicheng 1625811865@qq.com
- * @LastEditTime: 2024-04-10 19:09:06
+ * @LastEditTime: 2024-04-12 17:40:28
  * @Description: kxs files
  * @filePath:
  */
 import { http } from "@/utils/http";
-import { baseUrlApi } from "./utils";
-
-type Result = {
-  success: boolean;
-  data?: {
-    /** 列表数据 */
-    list: Array<any>;
-    /** 总数 */
-    total?: number;
-  };
-};
+import { dataResult } from "./apiResult";
 
+// <*------用户板块--------*>
 /** 获取用户管理列表 */
-export const getUserList = (data?: object) => {
+export const getUserList = (data?: object): dataResult => {
   return http.get(
-    "http://test.apigateway.shuangkebang.com//v1/skb/sysServer/user/page",
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/user/page",
+    data
+  );
+};
+/** 修改用户密码 */
+export const changeUserPassword = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/user/password",
+    data
+  );
+};
+/** 锁定用户 */
+export const lockUserList = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/user/lock",
     data
   );
 };
 /** 删除用户 */
-export const deleteUserList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/deleteAdmin"), data);
+export const deleteUserList = (data?: object): dataResult => {
+  return http.delete(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/user/removeById",
+    data
+  );
 };
 /** 新增用户 */
-export const postUserList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/addAdmin"), data);
+export const AddUserList = (data?: object): dataResult => {
+  return http.post(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/user/add",
+    data
+  );
 };
 /** 编辑用户 */
-export const editUserList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/updateAdmin"), data);
+export const editUserList = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/user/update",
+    data
+  );
 };
 
+// <*------角色板块--------*>
+
+/** 获取全部角色管理列表 */
+export const getAllRoleList = (data?: object): dataResult => {
+  return http.get(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/role/list",
+    data
+  );
+};
 /** 获取角色管理列表 */
-export const getRoleList = (data?: object) => {
-  return http.get(baseUrlApi("/v1/cybmain/system/getRoleList"), data);
+export const getRoleList = (data?: object): dataResult => {
+  return http.get(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/role/page",
+    data
+  );
 };
 /** 获取当前角色权限列表 */
-export const getRoleRightList = (data?: object) => {
+export const getRoleRightList = (data?: object): dataResult => {
   return http.get(
-    baseUrlApi("/v1/cybmain/system/getMenuTreeByAdminList"),
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/menu/getRoleTree",
     data
   );
 };
 /** 添加系统角色 */
-export const postRoleList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/addRole"), data);
+export const postRoleList = (data?: object): dataResult => {
+  return http.post(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/role/add",
+    data
+  );
 };
 /** 编辑系统角色 */
-export const putRoleList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/updateRole"), data);
+export const putRoleList = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/role/update",
+    data
+  );
 };
 /** 删除系统角色 */
-export const deleteRoleList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/deleteRole"), data);
+export const deleteRoleList = (data?: object): dataResult => {
+  return http.delete(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/role/removeById",
+    data
+  );
 };
 /** 获取所有角色权限列表 */
-export const getRoleTreeList = (data?: object) => {
-  return http.get(baseUrlApi("/v1/cybmain/system/getMenuTreeList"), data);
+export const getRoleTreeList = (data?: object): dataResult => {
+  return http.get(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/menu/getRoleTree",
+    data
+  );
 };
 
-/** 获取权限列表 */
-export const getPermissionList = (data?: object) => {
-  return http.get(baseUrlApi("/v1/cybmain/system/getPermissionList"), data);
-};
+// <*------菜单板块--------*>
+
 /** 获取菜单列表 */
-export const getMenuList = (data?: object) => {
+export const getMenuList = (data?: object): dataResult => {
   return http.get(
-    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/menu/getById",
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/menu/tree",
+    data
+  );
+};
+/** 获取菜单列表 */
+export const putRoleMenuList = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/role/menu",
     data
   );
 };
 /** 添加菜单 */
-export const postMenuList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/addMenu"), data);
+export const postMenuList = (data?: object): dataResult => {
+  return http.post(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/menu/add",
+    data
+  );
 };
 /** 编辑菜单 */
-export const putMenuList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/updateMenu"), data);
+export const putMenuList = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/menu/update",
+    data
+  );
 };
 /** 删除菜单 */
-export const deleteMenuList = (data?: object) => {
-  return http.post(baseUrlApi("/v1/cybmain/system/deleteMenu"), data);
+export const deleteMenuList = (data?: object): dataResult => {
+  return http.delete(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/menu/removeById",
+    data
+  );
+};
+
+// <*------部门板块--------*>
+
+/** 获取全部部门列表 */
+export const getAllDeptList = (data?: object): dataResult => {
+  return http.get(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/dept/list",
+    data
+  );
+};
+/** 获取部门列表 */
+export const getDeptList = (data?: object): dataResult => {
+  return http.get(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/dept/tree",
+    data
+  );
+};
+/** 删除部门列表 */
+export const deleteDeptList = (data?: object): dataResult => {
+  return http.delete(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/dept/removeById",
+    data
+  );
+};
+/** 编辑部门 */
+export const putDeptList = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/dept/update",
+    data
+  );
+};
+/** 添加部门 */
+export const postDeptList = (data?: object): dataResult => {
+  return http.post(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/dept/add",
+    data
+  );
+};
+// <*------岗位板块--------*>
+
+/** 获取全部列表 */
+export const getAllPostList = (data?: object): dataResult => {
+  return http.get(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/post/list",
+    data
+  );
+};
+/** 获取分页岗位列表 */
+export const getPostList = (data?: object): dataResult => {
+  return http.get(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/post/page",
+    data
+  );
+};
+/** 删除岗位列表 */
+export const deletePostList = (data?: object): dataResult => {
+  return http.delete(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/post/removeById",
+    data
+  );
+};
+/** 编辑岗位 */
+export const putPostList = (data?: object): dataResult => {
+  return http.put(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/post/update",
+    data
+  );
+};
+/** 添加岗位 */
+export const postPostList = (data?: object): dataResult => {
+  return http.post(
+    "http://test.apigateway.shuangkebang.com/v1/skb/sysServer/post/add",
+    data
+  );
 };

+ 1 - 1
src/api/user.ts

@@ -2,7 +2,7 @@
  * @Author: Gui
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: guicheng 1625811865@qq.com
- * @LastEditTime: 2024-04-10 18:09:03
+ * @LastEditTime: 2024-04-12 14:45:18
  * @Description: kxs files
  * @filePath:
  */

+ 8 - 8
src/api/welcome.ts

@@ -1,27 +1,27 @@
 /*
- * @Author: 
+ * @Author:
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: Please set LastEditors
  * @LastEditTime: 2024-01-03 16:48:54
  * @Description: kxs files
- * @filePath: 
+ * @filePath:
  */
 import { http } from "@/utils/http";
-import { dataResult } from "@/api/apiResult"
+import { dataResult } from "@/api/apiResult";
 
 /** 饼图数据 */
-export const welcomePie = (data?: object) => {
-  return http.request<dataResult>("get", "/pie", { data });
+export const welcomePie = (data?: object): dataResult => {
+  return http.request("get", "/pie", { data });
 };
 /** 折线图数据 */
 export const line = (data?: object) => {
-  return http.request<dataResult>("get", "/line ", { data });
+  return http.request("get", "/line ", { data });
 };
 /** 柱状图数据 */
 export const bar = (data?: object) => {
-  return http.request<dataResult>("get", "/bar ", { data });
+  return http.request("get", "/bar ", { data });
 };
 /** 列表数据 */
 export const noticelist = (data?: object) => {
-  return http.request<dataResult>("get", "/list ", { data });
+  return http.request("get", "/list ", { data });
 };

+ 0 - 30
src/components/AccountInfo/index.tsx

@@ -1,30 +0,0 @@
-/*
- * @Author: Gui
- * @Date: 2023-10-09 17:36:20
- * @LastEditors: Please set LastEditors
- * @LastEditTime: 2023-10-13 13:42:38
- * @Description: kxs files
- * @filePath:
- */
-export const AccountInfo = props => (
-  <div>
-    {props.SettleBankName && props.SettleBankName !== "无" && (
-      <el-text size={props.size} class="mr-1">
-        <el-icon class="el-input__icon">
-          <OfficeBuilding />
-        </el-icon>
-        {props.SettleBankName}
-      </el-text>
-    )}
-    {props.SettleBankCardNo && props.SettleBankCardNo !== "无" && (
-      <el-text size={props.size} class="mr-1">
-        银行卡号:{props.SettleBankCardNo}
-      </el-text>
-    )}
-    {props.AlipayNo && props.AlipayNo !== "无" && (
-      <el-text size={props.size} class="mr-1">
-        支付宝账号:{props.AlipayNo}
-      </el-text>
-    )}
-  </div>
-);

+ 0 - 60
src/components/CreatorDate/index.tsx

@@ -1,60 +0,0 @@
-/*
- * @Author: Gui
- * @Date: 2023-10-09 14:58:55
- * @LastEditors: Please set LastEditors
- * @LastEditTime: 2023-10-16 11:03:21
- * @Description: kxs files
- * @filePath:
- */
-import { ListDate } from "@/utils/formateDate";
-export const CreatorDate = (props: any) => (
-  <div>
-    {props.AuthDate && (
-      <el-text size={props.size} class="justify-start">
-        {props.AuthDate !== "无" ? `实名时间:${ListDate(props.AuthDate)}` : ""}
-      </el-text>
-    )}
-    {props.CreateDate && (
-      <el-text size={props.size} class="justify-start mt-1">
-        注册时间:{ListDate(props.CreateDate)}
-      </el-text>
-    )}
-  </div>
-);
-export const CustomDate = (props: any) => (
-  <div>
-    {props.BeginDate && props.BeginDate.Date && (
-      <el-text size={props.size} class="justify-start mt-1">
-        {props.BeginDate.Remake}:{ListDate(props.BeginDate.Date)}
-      </el-text>
-    )}
-    {props.MiddleDate && props.MiddleDate.Date && (
-      <el-text size={props.size} class="justify-start mt-1">
-        {props.MiddleDate.Remake}:{ListDate(props.MiddleDate.Date)}
-      </el-text>
-    )}
-    {props.EndDate && props.EndDate.Date && (
-      <el-text size={props.size} class="justify-start mt-1">
-        {props.EndDate.Remake}:{ListDate(props.EndDate.Date)}
-      </el-text>
-    )}
-  </div>
-);
-export const CreatorMerchantDate = (props: any) => (
-  <div>
-    {props.MerchantType === "0" ? (
-      <el-tag size={props.size} type="danger" effect="plain">
-        非商户型创客
-      </el-tag>
-    ) : (
-      <div>
-        <el-tag size={props.size} type="success" effect="plain">
-          商户型创客
-        </el-tag>
-        <el-text size={props.size}>
-          转换时间:{ListDate(props.MerchantDate)}
-        </el-text>
-      </div>
-    )}
-  </div>
-);

+ 0 - 85
src/components/CreatorInfo/index.tsx

@@ -1,85 +0,0 @@
-/*
- * @Author: Gui
- * @Date: 2023-10-09 14:37:45
- * @LastEditors: Please set LastEditors
- * @LastEditTime: 2023-10-24 17:33:21
- * @Description: kxs files
- * @filePath:
- */
-export const CreatorInfo = props => (
-  <div>
-    <div class="flex justify-center">
-      {props.RealName && props.RealName !== "无" && (
-        <el-text size={props.size} class="mr-2">
-          <el-icon class="el-input__icon">
-            <Avatar />
-          </el-icon>
-          {props.RealName}
-        </el-text>
-      )}
-      {props.RealName && props.UserLevel && props.UserLevel !== "无" && (
-        <el-text size={props.size}>{`K${props.UserLevel}`}</el-text>
-      )}
-    </div>
-    {props.MakerCode && props.MakerCode !== "无" && (
-      <el-text size={props.size}>
-        <el-icon class="el-input__icon">
-          <Promotion />
-        </el-icon>
-        {`${props.MakerCode}`}
-      </el-text>
-    )}
-    {props.RealName && props.Mobile && props.Mobile !== "无" && (
-      <el-text size={props.size}>
-        <el-icon class="el-input__icon">
-          <Phone />
-        </el-icon>
-        {props.Mobile}
-      </el-text>
-    )}
-    {props.RealName && props.Address && props.Address !== "无" && (
-      <el-text size={props.size}>
-        <el-icon class="el-input__icon">
-          <LocationInformation />
-        </el-icon>
-        {props.Address}
-      </el-text>
-    )}
-    {!(props.RealName && props.RealName !== "无") &&
-      !(props.MakerCode && props.MakerCode !== "无") &&
-      "暂无信息"}
-  </div>
-);
-export const MerchantInfo = props => (
-  <div>
-    <div class="flex justify-center">
-      {props.RealName && props.RealName !== "无" && (
-        <el-text size={props.size} class="mr-2">
-          <el-icon class="el-input__icon">
-            <Avatar />
-          </el-icon>
-          {props.RealName}
-        </el-text>
-      )}
-    </div>
-    {props.RealName && props.Mobile && props.Mobile !== "无" && (
-      <el-text size={props.size}>
-        <el-icon class="el-input__icon">
-          <Phone />
-        </el-icon>
-        {props.Mobile}
-      </el-text>
-    )}
-    {props.RealName && props.Address && props.Address !== "无" && (
-      <el-text size={props.size}>
-        <el-icon class="el-input__icon">
-          <LocationInformation />
-        </el-icon>
-        {props.Address}
-      </el-text>
-    )}
-    {!(props.RealName && props.RealName !== "无") &&
-      !(props.MakerCode && props.MakerCode !== "无") &&
-      "暂无信息"}
-  </div>
-);

+ 30 - 6
src/layout/components/navbar.vue

@@ -18,6 +18,10 @@ const {
   device,
   logout,
   onPanel,
+  ChangePasswordFormSubmit,
+  dialogChangePasswordVisible,
+  handleChangePassword,
+  ChangePassword,
   pureApp,
   username,
   avatarsStyle,
@@ -66,10 +70,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
       <!-- 退出登录 -->
       <el-dropdown trigger="click">
         <span class="el-dropdown-link navbar-bg-hover select-none">
-          <!-- <img
-            src="https://avatars.githubusercontent.com/u/44761321?v=4"
-            :style="avatarsStyle"
-          /> -->
+          <img src="https://avatars.githubusercontent.com/u/44761321?v=4" :style="avatarsStyle" />
           <p v-if="username" class="dark:text-white">{{ username }}</p>
           <span class="arrow-down">
             <IconifyIconOffline :icon="ArrowDown" class="dark:text-white" />
@@ -77,10 +78,10 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
         </span>
         <template #dropdown>
           <el-dropdown-menu class="logout">
-            <!-- <el-dropdown-item @click="changepwd">
+            <el-dropdown-item @click="handleChangePassword">
               <IconifyIconOffline :icon="EditPen" style="margin: 5px" />
               {{ t("buttons.changePWD") }}
-            </el-dropdown-item> -->
+            </el-dropdown-item>
             <el-dropdown-item @click="logout">
               <IconifyIconOffline :icon="LogoutCircleRLine" style="margin: 5px" />
               {{ t("buttons.hsLoginOut") }}
@@ -92,6 +93,29 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
         <IconifyIconOffline :icon="Setting" />
       </span>
     </div>
+    <el-dialog v-model="dialogChangePasswordVisible" title="修改密码">
+      <el-form :model="ChangePassword" label-position="right" label-width="100px">
+        <el-form-item label="旧密码:">
+          <el-input v-model="ChangePassword.password" autocomplete="off" placeholder="请输入登录密码" />
+        </el-form-item>
+        <el-form-item label="新密码:">
+          <el-input v-model="ChangePassword.newpassword1" type="password" show-password autocomplete="off"
+            placeholder="请输入新密码" />
+        </el-form-item>
+        <el-form-item label="确认新密码:">
+          <el-input v-model="ChangePassword.newpassword2" type="password" show-password autocomplete="off"
+            placeholder="请确认新密码" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogChangePasswordVisible = false">关闭</el-button>
+          <el-button type="primary" @click="ChangePasswordFormSubmit">
+            确认修改
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
   </div>
 </template>
 

+ 64 - 1
src/layout/hooks/useNav.ts

@@ -15,6 +15,7 @@ import { usePermissionStoreHook } from "@/store/modules/permission";
 import { ElMessage, ElMessageBox } from "element-plus";
 import Cookies from "js-cookie";
 import { ShakeDownDecrypt } from "@/utils/CryptoJS";
+import { changeUserPassword } from "@/api/system";
 
 const errorInfo = "当前路由配置不正确,请检查配置";
 
@@ -89,6 +90,64 @@ export function useNav() {
     useUserStoreHook().logOut();
   }
 
+  // 修改密码
+  const dialogChangePasswordVisible = ref(false);
+  const ChangePassword = ref({
+    password: "", //密码
+    newpassword1: "", //新密码
+    newpassword2: "" //确认新密码
+  });
+  function handleChangePassword() {
+    dialogChangePasswordVisible.value = true;
+  }
+  async function ChangePasswordFormSubmit() {
+    if (!ChangePassword.value.password) {
+      return ElMessage({
+        message: "请输入旧密码",
+        type: "info"
+      });
+    }
+    if (!ChangePassword.value.newpassword1) {
+      return ElMessage({
+        message: "请输入新密码",
+        type: "info"
+      });
+    }
+    if (!ChangePassword.value.newpassword2) {
+      return ElMessage({
+        message: "请确认新密码",
+        type: "info"
+      });
+    }
+    if (
+      ChangePassword.value.newpassword1 !== ChangePassword.value.newpassword2
+    ) {
+      return ElMessage({
+        message: "两次密码输入不一致,请重新输入",
+        type: "warning"
+      });
+    }
+    if (ChangePassword.value.password === ChangePassword.value.newpassword1) {
+      return ElMessage({
+        message: "新旧密码一致,请重新输入",
+        type: "warning"
+      });
+    }
+
+    const { status, msg } = await changeUserPassword(ChangePassword.value);
+    if (status == 1) {
+      ElMessage({
+        message: "修改密码成功",
+        type: "success"
+      });
+      dialogChangePasswordVisible.value = false;
+    } else {
+      ElMessageBox.alert(msg, "提示", {
+        confirmButtonText: "关闭",
+        type: "warning"
+      });
+    }
+  }
 
   function backHome() {
     router.push("/welcome");
@@ -173,6 +232,10 @@ export function useNav() {
     avatarsStyle,
     tooltipEffect,
     getDropdownItemStyle,
-    getDropdownItemClass
+    getDropdownItemClass,
+    ChangePasswordFormSubmit,
+    dialogChangePasswordVisible,
+    ChangePassword,
+    handleChangePassword
   };
 }

+ 15 - 1
src/utils/encryptByDES.ts

@@ -2,7 +2,7 @@
  * @Author: guicheng 1625811865@qq.com
  * @Date: 2023-02-21 15:36:29
  * @LastEditors: guicheng 1625811865@qq.com
- * @LastEditTime: 2024-04-10 16:09:57
+ * @LastEditTime: 2024-04-11 11:35:19
  * @FilePath: /admin/src/utils/encryptByDES.ts
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -18,4 +18,18 @@ const encryptByDES = message => {
   const str = CryptoJS.enc.Utf8.parse(encrypted.toString());
   return CryptoJS.enc.Base64.stringify(str);
 };
+const decryptByDES = message => {
+  const encryptedHexStr = CryptoJS.enc.Base64.parse(message);
+  const str = encryptedHexStr.toString(CryptoJS.enc.Utf8);
+  const keyHex = CryptoJS.enc.Utf8.parse("CBTU1dD4Kd5pyiGWTsI10jRQ3SvKusSV");
+  const ivHex = CryptoJS.enc.Utf8.parse("DYgjCEIMVrj2W9xN");
+  const decrypt = CryptoJS.AES.decrypt(str, keyHex, {
+    iv: ivHex,
+    mode: CryptoJS.mode.CBC,
+    padding: CryptoJS.pad.Pkcs7
+  });
+  const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
+  return decryptedStr.toString();
+};
+export { decryptByDES };
 export default encryptByDES;

+ 13 - 10
src/utils/getUrl/getUrl.js

@@ -9,15 +9,15 @@
 import axios from "axios";
 import PublicLib from "./PublicLib";
 import CryptoJS from "crypto-js";
-var request = axios.create({
+const request = axios.create({
   // 请求超时时间
   timeout: 5000
 });
 
 // 加密函数
 const encryptByDES = function (message) {
-  var keyHex = CryptoJS.enc.Utf8.parse("&L^kg4N9");
-  var ivHex = CryptoJS.enc.Utf8.parse("&L^kg4N9");
+  const keyHex = CryptoJS.enc.Utf8.parse("&L^kg4N9");
+  const ivHex = CryptoJS.enc.Utf8.parse("&L^kg4N9");
   const encrypted = CryptoJS.DES.encrypt(message, keyHex, {
     iv: ivHex,
     mode: CryptoJS.mode.CBC,
@@ -29,7 +29,7 @@ const encryptByDES = function (message) {
 // 请求方法
 const postRequest = (url, params) => {
   console.log("请求参数:", params);
-  let param = new URLSearchParams();
+  const param = new URLSearchParams();
   param.append("value", encryptByDES(JSON.stringify(params)));
   return request({
     url,
@@ -63,9 +63,12 @@ const getURL = () => {
 // URL列表资源
 const getAllPlate = () => {
   return new Promise(async (resolve, reject) => {
-    postRequest("http://test.config.kexiaoshuang.com/api/apiinfo/groups", {
-      key: "kxs#2024"
-    })
+    postRequest(
+      "http://test.config.kexiaoshuang.com/api/apiinfo/groupsforadmin",
+      {
+        key: "kxs#2024"
+      }
+    )
       .then(async res => {
         resolve(res.data.data);
       })
@@ -79,7 +82,7 @@ const getAllPlate = () => {
 const getGroupUrl = async (checkPlate = []) => {
   return new Promise(async (resolve, reject) => {
     const URLLIST = (await getURL()) || {};
-    let parameters = { userId: 1, groups: []  };
+    const parameters = { userId: 1, groups: [] };
     if (checkPlate.length == 0) {
       checkPlate = await getAllPlate();
     }
@@ -96,7 +99,7 @@ const getGroupUrl = async (checkPlate = []) => {
       );
     }, 5000);
     postRequest(
-      "http://test.config.kexiaoshuang.com/api/apiinfo/list",
+      "http://test.config.kexiaoshuang.com/api/apiinfo/listforadmin",
       parameters
     )
       .then(async res => {
@@ -108,7 +111,7 @@ const getGroupUrl = async (checkPlate = []) => {
           if (res.data.status == "1") {
             // 全部接口循环读取更新
             const onlineurl = res.data.data;
-            for (let key in onlineurl) {
+            for (const key in onlineurl) {
               if (
                 URLLIST[key] &&
                 onlineurl[key].groupVersion > URLLIST[key].groupVersion

+ 21 - 20
src/utils/http/index.ts

@@ -2,7 +2,7 @@
  * @Author: Gui
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: guicheng 1625811865@qq.com
- * @LastEditTime: 2024-04-10 16:02:09
+ * @LastEditTime: 2024-04-12 15:23:17
  * @Description: kxs files
  * @filePath:
  */
@@ -30,6 +30,7 @@ import { useAppStoreHook } from "@/store/modules/app";
 import router, { resetRouter } from "@/router";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 import { routerArrays } from "@/layout/types";
+import { dataResult } from "@/api/apiResult";
 
 // 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
 const defaultConfig: AxiosRequestConfig = {
@@ -219,12 +220,12 @@ class PureHttp {
   }
 
   /** 通用请求工具函数 */
-  public request<T>(
+  public request(
     method: RequestMethods,
     url: string,
     param?: any,
     axiosConfig?: PureHttpRequestConfig
-  ): Promise<T> {
+  ): any {
     const config = {
       method,
       url,
@@ -235,6 +236,7 @@ class PureHttp {
       ...axiosConfig
     } as PureHttpRequestConfig;
     // 单独处理自定义请求/响应回掉
+    // console.log(config);
     return new Promise((resolve, reject) => {
       PureHttp.axiosInstance
         .request(config)
@@ -248,11 +250,11 @@ class PureHttp {
   }
 
   /** 单独抽离的post工具函数 */
-  public post<T, P>(
+  public post<T>(
     url: string,
     params?: AxiosRequestConfig<T>,
     config?: PureHttpRequestConfig
-  ): Promise<P> {
+  ): any {
     let legal = true;
     const paramskey = [];
     for (const key in params) {
@@ -267,7 +269,7 @@ class PureHttp {
     }
     if (legal) {
       const param = { data: encryptByDES(JSON.stringify(params)) };
-      return this.request<P>("post", url, param, config);
+      return this.request("post", url, param, config);
     } else {
       ElMessage({
         message: `params is illegal`,
@@ -283,15 +285,15 @@ class PureHttp {
     config?: PureHttpRequestConfig
   ): Promise<P> {
     const param = { data: encryptByDES(JSON.stringify(params)) };
-    return this.request<P>("post", url, param, config);
+    return this.request("post", url, param, config);
   }
 
   /** 单独抽离的get工具函数 */
-  public get<T, P>(
+  public get<T>(
     url: string,
     params?: AxiosRequestConfig<T>,
     config?: PureHttpRequestConfig
-  ): Promise<P> {
+  ): any {
     let legal = true;
     const paramskey = [];
     for (const key in params) {
@@ -305,10 +307,9 @@ class PureHttp {
       }
     }
     if (legal) {
-      const params = new URLSearchParams();
-      params.append("value", encryptByDES(JSON.stringify(params)));
-      const param = { params };
-      return this.request<P>("get", url, param, config);
+      const paramter = { value: encryptByDES(JSON.stringify(params)) };
+      const param = { params: paramter };
+      return this.request("get", url, param, config);
     } else {
       ElMessage({
         message: `params is illegal`,
@@ -318,11 +319,11 @@ class PureHttp {
     }
   }
   /** 单独抽离的put工具函数 */
-  public put<T, P>(
+  public put<T>(
     url: string,
     params?: AxiosRequestConfig<T>,
     config?: PureHttpRequestConfig
-  ): Promise<P> {
+  ): any {
     let legal = true;
     const paramskey = [];
     for (const key in params) {
@@ -337,7 +338,7 @@ class PureHttp {
     }
     if (legal) {
       const param = { data: encryptByDES(JSON.stringify(params)) };
-      return this.request<P>("put", url, param, config);
+      return this.request("put", url, param, config);
     } else {
       ElMessage({
         message: `params is illegal`,
@@ -347,15 +348,15 @@ class PureHttp {
     }
   }
   /** 单独抽离的delete工具函数 */
-  public delete<T, P>(
+  public delete<T>(
     url: string,
     params?: AxiosRequestConfig<T>,
     config?: PureHttpRequestConfig
-  ): Promise<P> {
+  ): dataResult {
     const param = { data: {} };
-    return this.request<P>(
+    return this.request(
       "delete",
-      `${url}/${encryptByDES(JSON.stringify(params))}`,
+      `${url}/${encryptByDES(params)}`,
       param,
       config
     );

+ 27 - 23
src/views/Template/template/components/add/index.vue

@@ -19,10 +19,10 @@ import { postUserList } from "@/api/system";
 import { ElMessage, ElMessageBox } from "element-plus";
 import { http } from "@/utils/http";
 // 获取URLLIST
-import { getGroupUrl } from "@/utils/getUrl/getUrl"
+import { getGroupUrl } from "@/utils/getUrl/getUrl";
 // 获取当前板块接口列表
-import Upload from "@iconify-icons/ri/upload-2-fill"
-import Close from "@iconify-icons/ri/close-fill"
+import Upload from "@iconify-icons/ri/upload-2-fill";
+import Close from "@iconify-icons/ri/close-fill";
 
 const props = defineProps<{
   submit: Function;
@@ -36,33 +36,37 @@ const props = defineProps<{
   };
 }>();
 // 表单数据
-let UpdateForm = ref({
+const UpdateForm = ref({
   RealName: "",
   AdminName: "",
   PassWord: "",
-  RoleId: "",
+  RoleId: ""
 });
 // 传参选项数据
 const optionList = [
-  { Id: '1', label: '推荐' },
-  { Id: '2', label: '实物' },
-  { Id: '3', label: '虚拟商品' },
-]
+  { Id: "1", label: "推荐" },
+  { Id: "2", label: "实物" },
+  { Id: "3", label: "虚拟商品" }
+];
 // 选项卡参数(默认值为列表某项的id)
-const activeId = ref('1')
+const activeId = ref("1");
 // 穿梭框数据
 const transferdata = ref([
-  { key: 1, label: '1', disabled: false },
-  { key: 2, label: '2', disabled: false },
-  { key: 3, label: '3', disabled: false },
-  { key: 4, label: '4', disabled: false },
-  { key: 5, label: '5', disabled: false },
-  { key: 6, label: '6', disabled: false },
-])
+  { key: 1, label: "1", disabled: false },
+  { key: 2, label: "2", disabled: false },
+  { key: 3, label: "3", disabled: false },
+  { key: 4, label: "4", disabled: false },
+  { key: 5, label: "5", disabled: false },
+  { key: 6, label: "6", disabled: false }
+]);
 // 提交函数
 const submit = async () => {
-  const UserUrl = await getGroupUrl(['User']);
-  const { status, info }: any = http.request(UserUrl.User.userSearch.method, UserUrl.User.userSearch.url, UpdateForm.value);
+  const UserUrl = await getGroupUrl(["User"]);
+  const { status, info }: any = http.request(
+    UserUrl.User.userSearch.method,
+    UserUrl.User.userSearch.url,
+    UpdateForm.value
+  );
   if (status === "1") {
     ElMessage({
       message: "新增成功",
@@ -72,23 +76,23 @@ const submit = async () => {
       AdminName: "",
       RealName: "",
       RoleId: "",
-      PassWord: "",
+      PassWord: ""
     };
   } else {
     ElMessageBox.alert(info, "提示", {
       confirmButtonText: "关闭",
       type: "warning"
     });
-  };
+  }
 };
-const closeFn: any = inject('closeAddVisible');
+const closeFn: any = inject("closeAddVisible");
 // 关闭弹窗回调函数
 const closeVisible = () => {
   UpdateForm.value = {
     AdminName: "",
     RealName: "",
     RoleId: "",
-    PassWord: "",
+    PassWord: ""
   };
   closeFn();
 };

+ 48 - 34
src/views/Template/template/hook.tsx

@@ -3,33 +3,36 @@ import { type PaginationProps } from "@pureadmin/table";
 import { ElMessage, ElMessageBox } from "element-plus";
 import { reactive, ref, computed, onMounted } from "vue";
 // 获取URLLIST
-import { getGroupUrl } from "@/utils/getUrl/getUrl"
+import { getGroupUrl } from "@/utils/getUrl/getUrl";
 import { http } from "@/utils/http";
 // 获取当前板块接口列表
-const UserUrl = await getGroupUrl(['User']);
+const UserUrl = await getGroupUrl(["User"]);
 export function useUser() {
   // 搜索表单参数
-  let form = reactive({
+  const form = reactive({
     Name: ""
   });
   // 级联选择器参数
-  const optionList = ref([{
-    value: 'resource', label: 'Resource',
-    children: [
-      {
-        value: 'axure',
-        label: 'Axure Components',
-      },
-      {
-        value: 'sketch',
-        label: 'Sketch Templates',
-      },
-      {
-        value: 'docs',
-        label: 'Design Documentation',
-      },
-    ],
-  }])
+  const optionList = ref([
+    {
+      value: "resource",
+      label: "Resource",
+      children: [
+        {
+          value: "axure",
+          label: "Axure Components"
+        },
+        {
+          value: "sketch",
+          label: "Sketch Templates"
+        },
+        {
+          value: "docs",
+          label: "Design Documentation"
+        }
+      ]
+    }
+  ]);
   const dataList = ref([]);
   const loading = ref(false);
   const dialogAddVisible = ref(false);
@@ -67,28 +70,36 @@ export function useUser() {
   // 当前页数量切换
   function handleSizeChange(val: number) {
     console.log(`${val} items per page`);
-    onSearch()
+    onSearch();
   }
   // 当前页码切换
   function handleCurrentChange(val: number) {
     console.log(`current page: ${val}`);
-    onSearch()
+    onSearch();
   }
   // 选择表格项
   function handleSelectionChange(val) {
     console.log("handleSelectionChange", val);
-    onSearch()
+    onSearch();
   }
   // 搜索列表
-  async function onSearch(type = 'search') {
-    if (type == 'search' && !Object.values(form).some(item => !!item)) {
+  async function onSearch(type = "search") {
+    if (type == "search" && !Object.values(form).some(item => !!item)) {
       return ElMessage({
         message: "请输入查询条件",
         type: "error"
       });
-    };
+    }
     loading.value = true;
-    const { data, other }: any = http.request(UserUrl.User.userSearch.method, UserUrl.User.userSearch.url, { ...form, page_size: pagination.pageSize, page_num: pagination.currentPage });
+    const { data, other }: any = http.request(
+      UserUrl.User.userSearch.method,
+      UserUrl.User.userSearch.url,
+      {
+        ...form,
+        page_size: pagination.pageSize,
+        page_num: pagination.currentPage
+      }
+    );
     dataList.value = data;
     pagination.total = other.Count;
     setTimeout(() => {
@@ -102,8 +113,7 @@ export function useUser() {
   // 删除
   function handleDelete(row) {
     ElMessageBox.confirm(
-      `是否删除该用户?  用户名称为:${row.AdminName
-      }`,
+      `是否删除该用户?  用户名称为:${row.AdminName}`,
       "提示",
       {
         confirmButtonText: "删除",
@@ -111,7 +121,11 @@ export function useUser() {
         type: "warning"
       }
     ).then(async () => {
-      const { status, info }: any = await http.request(UserUrl.User.userDelete.method, UserUrl.User.userDelete.url, { SysAdminId: row.Id });
+      const { status, info }: any = await http.request(
+        UserUrl.User.userDelete.method,
+        UserUrl.User.userDelete.url,
+        { SysAdminId: row.Id }
+      );
       if (status === "1") {
         ElMessage({
           message: "删除成功",
@@ -123,14 +137,14 @@ export function useUser() {
           confirmButtonText: "关闭",
           type: "warning"
         });
-      };
-    })
+      }
+    });
   }
   // 新增
   const addVisible = ref(false);
   function handleAdd() {
     addVisible.value = true;
-  };
+  }
   // 修改
   const editVisible = ref(false);
   const editFormData = ref({});
@@ -155,6 +169,6 @@ export function useUser() {
     addVisible,
     editVisible,
     editFormData,
-    optionList,
+    optionList
   };
 }

+ 247 - 0
src/views/admin/dept/hook.tsx

@@ -0,0 +1,247 @@
+import {
+  deleteDeptList,
+  getDeptList,
+  postDeptList,
+  putDeptList
+} from "@/api/system";
+import { type PaginationProps } from "@pureadmin/table";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { reactive, ref, computed, onMounted } from "vue";
+
+export function useUser() {
+  const form: any = ref({
+    deptName: ""
+  });
+  const UpdateForm: any = ref({
+    name: "", //菜单名称
+    sortOrder: "", //排序值,越小越靠前
+    parentId: "" //父级部门ID
+  });
+  const dialogType = ref(1);
+  const dataList = ref([]);
+  const deptList = ref([]);
+  const loading = ref(false);
+  const dialogUpdateVisible = ref(false);
+  const pagination = reactive<PaginationProps>({
+    total: 0,
+    pageSize: 10,
+    currentPage: 1,
+    background: true
+  });
+  const columns: TableColumnList = [
+    {
+      type: "selection",
+      width: 55,
+      align: "left",
+      hide: ({ checkList }) => !checkList.includes("勾选列")
+    },
+    {
+      label: "序号",
+      type: "index",
+      width: 70,
+      hide: ({ checkList }) => !checkList.includes("序号列")
+    },
+    {
+      label: "ID",
+      prop: "id",
+      minWidth: 130
+    },
+    {
+      label: "部门名称",
+      prop: "name",
+      minWidth: 130
+    },
+    {
+      label: "权重",
+      prop: "weight",
+      minWidth: 130
+    },
+    {
+      label: "操作",
+      fixed: "right",
+      width: 200,
+      slot: "operation"
+    }
+  ];
+  const buttonClass = computed(() => {
+    return [
+      "!h-[20px]",
+      "reset-margin",
+      "!text-gray-500",
+      "dark:!text-white",
+      "dark:hover:!text-primary"
+    ];
+  });
+
+  // 树形结构格式化
+  function TreeFormatter(data) {
+    const result = data.map(item => {
+      if (item.children && item.children.length != 0) {
+        return {
+          label: item.name,
+          value: item.id,
+          children: TreeFormatter(item.children)
+        };
+      } else if (item.menuType == 1) {
+        return {
+          disabled: true,
+          label: item.name,
+          value: item.id
+        };
+      } else {
+        return {
+          label: item.name,
+          value: item.id
+        };
+      }
+    });
+    return result;
+  }
+
+  async function UpdateFormSubmit() {
+    if (dialogType.value == 1) {
+      const { status, msg } = await postDeptList(UpdateForm.value);
+      if (status == 1) {
+        ElMessage({
+          message: "新增部门成功",
+          type: "success"
+        });
+        dialogUpdateVisible.value = false;
+        onSearch();
+      } else {
+        ElMessageBox.alert(msg, "提示", {
+          confirmButtonText: "关闭",
+          type: "warning"
+        });
+      }
+    } else {
+      const { status, msg } = await putDeptList(UpdateForm.value);
+      if (status == 1) {
+        ElMessage({
+          message: "部门修改成功",
+          type: "success"
+        });
+        dialogUpdateVisible.value = false;
+        onSearch();
+      } else {
+        ElMessageBox.alert(msg, "提示", {
+          confirmButtonText: "关闭",
+          type: "warning"
+        });
+      }
+    }
+  }
+  function handleDelete(row) {
+    ElMessageBox.confirm(`是否删除名称为:${row.name}的部门? `, "提示", {
+      confirmButtonText: "删除",
+      cancelButtonText: "取消",
+      type: "warning"
+    }).then(async () => {
+      const { status, msg } = await deleteDeptList(row.id);
+      if (status == 1) {
+        ElMessage({
+          message: "删除成功",
+          type: "success"
+        });
+        onSearch();
+      } else {
+        ElMessageBox.alert(msg, "提示", {
+          confirmButtonText: "关闭",
+          type: "warning"
+        });
+      }
+    });
+  }
+  function AddUser() {
+    UpdateForm.value = {
+      name: "", //菜单名称
+      sortOrder: "", //排序值,越小越靠前
+      parentId: "" //父级部门ID
+    };
+    dialogType.value = 1;
+    dialogUpdateVisible.value = true;
+  }
+  function handleUpdate(row) {
+    dialogType.value = 2;
+    dialogUpdateVisible.value = true;
+    UpdateForm.value = {
+      name: row.name,
+      deptId: row.id,
+      sortOrder: "",
+      parentId: row.parentId
+    };
+  }
+
+  function handleSizeChange(val: number) {
+    console.log(`${val} items per page`);
+    onSearch();
+  }
+
+  function handleCurrentChange(val: number) {
+    if (typeof val !== "number") return;
+    console.log(`current page: ${val}`);
+    onSearch();
+  }
+
+  function handleSelectionChange(val) {
+    console.log("handleSelectionChange", val);
+    onSearch();
+  }
+
+  // 搜索函数(请求表格数据列表)
+  function submit(e: { keyCode: number }) {
+    if (e.keyCode == 229) {
+      return;
+    } else {
+      onSearch();
+    }
+  }
+  async function onSearch(type = "") {
+    if (type == "search" && !Object.values(form).some(item => !!item)) {
+      return ElMessage({
+        message: "请输入查询条件",
+        type: "error"
+      });
+    }
+    if (type == "all") {
+      form.value.deptName = "";
+    }
+    loading.value = true;
+    const { data } = await getDeptList({
+      ...form.value,
+      pageSize: pagination.pageSize,
+      pageNum: pagination.currentPage
+    });
+    dataList.value = data;
+    deptList.value = TreeFormatter(data);
+    pagination.total = data.length;
+    setTimeout(() => {
+      loading.value = false;
+    }, 500);
+  }
+  onMounted(() => {
+    onSearch();
+  });
+
+  return {
+    loading,
+    columns,
+    dataList,
+    pagination,
+    buttonClass,
+    dialogUpdateVisible,
+    UpdateFormSubmit,
+    submit,
+    UpdateForm,
+    deptList,
+    dialogType,
+    AddUser,
+    onSearch,
+    handleUpdate,
+    handleDelete,
+    handleSizeChange,
+    handleCurrentChange,
+    handleSelectionChange,
+    form
+  };
+}

+ 194 - 0
src/views/admin/dept/index.vue

@@ -0,0 +1,194 @@
+<script lang="ts">
+// 声明额外的选项
+export default {
+  name: "dept"
+};
+</script>
+<script setup lang="ts">
+import { useUser } from "./hook";
+import { PureTableBar } from "@/components/RePureTableBar";
+import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+
+import Delete from "@iconify-icons/ep/delete";
+import Search from "@iconify-icons/ep/search";
+import Refresh from "@iconify-icons/ep/refresh";
+import AddFill from "@iconify-icons/ri/add-circle-line";
+
+const {
+  loading,
+  columns,
+  dataList,
+  pagination,
+  dialogUpdateVisible,
+  UpdateFormSubmit,
+  UpdateForm,
+  onSearch,
+  submit,
+  dialogType,
+  deptList,
+  AddUser,
+  handleUpdate,
+  handleDelete,
+  handleSizeChange,
+  handleCurrentChange,
+  handleSelectionChange,
+  form
+} = useUser();
+defineExpose({
+  loading,
+  columns,
+  dataList,
+  pagination,
+  dialogUpdateVisible,
+  UpdateFormSubmit,
+  UpdateForm,
+  submit,
+  onSearch,
+  dialogType,
+  deptList,
+  AddUser,
+  handleUpdate,
+  handleDelete,
+  handleSizeChange,
+  handleCurrentChange,
+  handleSelectionChange,
+  form
+});
+</script>
+
+<template lang="pug">
+.main
+  div
+    el-form.bg-bg_color.pl-8.pt-4.pr-8(
+      label-position="left"
+      label-width="100px"
+      ref="formRef",
+      :inline="true",
+      :model="form",
+      :rules="rules",
+      class="w-[99/100]"
+    )
+      el-form-item(label="部门名称:", prop="deptName")
+        el-input(
+          v-model="form.deptName",
+          placeholder="请输入部门名称",
+          clearable,@keydown.enter="submit"
+          class="!w-[230px]"
+        )
+      el-form-item
+        el-button(
+          type="primary",
+          :icon="useRenderIcon(Search)",
+          :loading="loading",
+          @click="onSearch('search')"
+        ) 查询
+      el-form-item
+        el-button(
+          type="primary",
+          :icon="useRenderIcon(Search)",
+          :loading="loading",
+          @click="onSearch('all')"
+        ) 全部
+
+  //- 表格组件
+  PureTableBar.mt12(title="后台部门管理", @refresh="onSearch" )
+    template(#buttons)
+      el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser") 新增部门
+    template(v-slot="{ size, checkList }")
+      pure-table(stripe 
+        border,
+        row-key="id",
+        align-whole="center",
+        table-layout="auto",
+        :loading="loading",
+        :size="size",
+        :data="dataList",
+        :columns="columns",
+        :checkList="checkList",
+        :pagination="pagination",
+        :paginationSmall="size === 'default' ? true : false",
+        :header-cell-style="{ background: 'var(--el-table-row-hover-bg-color)', color: 'var(--el-text-color-primary)' }",
+        @selection-change="handleSelectionChange",
+        @size-change="handleSizeChange",
+        @current-change="handleCurrentChange"
+      )          
+        template(#operation="{ row }")
+          el-button.reset-margin(
+            link
+            type="primary"
+            :size="size"
+            @click="handleUpdate(row)"
+            :icon="useRenderIcon(EditPen)"
+          ) 编辑
+          el-button.reset-margin(
+            link
+            type="primary"
+            :size="size"
+            @click="handleDelete(row)"
+            :icon="useRenderIcon(Delete)"
+          ) 删除
+
+  el-dialog(v-model='dialogUpdateVisible' width="40%" :close-on-click-modal="false" :title="dialogType == 1 ?'添加部门' : '修改部门'" :close-on-click-modal="false")
+    el-form(:model='UpdateForm' 
+      label-position="left"
+      label-width="100px")
+      el-form-item(label='部门名称' prop="name")
+        el-input(v-model='UpdateForm.name' autocomplete='off' class="!w-[300px]"
+          placeholder="请输入部门名称")
+      el-form-item(label='权重' prop="sortOrder")
+        el-input(v-model='UpdateForm.sortOrder' autocomplete='off' type="number" class="!w-[300px]"
+          placeholder="请输入权重值(越小越靠前)")
+      el-form-item(label='选择部门')
+        el-tree-select(
+          v-model="UpdateForm.parentId" 
+          :data="deptList" 
+          check-strictly
+          :render-after-expand="false"
+          show-checkbox
+          check-on-click-node
+          class="!w-[300px]")
+    template(#footer)
+      span.dialog-footer
+        el-button(@click='dialogUpdateVisible = false') 关闭
+        el-button(type='primary' @click='UpdateFormSubmit') 确认提交
+</template>
+
+<style scoped lang="scss">
+:deep(.el-dropdown-menu__item i) {
+  margin: 0;
+}
+
+:deep(.el-form-item__label) {
+  font-weight: 700;
+}
+
+:deep(.el-pagination) {
+  flex-flow: wrap;
+}
+
+:deep(.is-draggable) {
+  max-height: 80vh;
+  overflow: auto;
+}
+
+:deep(.el-dialog__header) {
+  position: sticky;
+  top: 0;
+  z-index: 2;
+  background: #fff;
+}
+
+.collapsedom {
+  padding: 0 20px;
+  background-color: #fff;
+}
+
+.ovh-x {
+  height: 40vh;
+  overflow-y: auto;
+}
+
+:deep(.el-descriptions__header) {
+  margin: 16px 0 !important;
+}
+</style>

+ 1 - 0
src/views/admin/dept/svg/expand.svg

@@ -0,0 +1 @@
+<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M22 4V2H2v2h9v14.17l-5.5-5.5-1.42 1.41L12 22l7.92-7.92-1.42-1.41-5.5 5.5V4h9Z"/></svg>

+ 1 - 0
src/views/admin/dept/svg/unexpand.svg

@@ -0,0 +1 @@
+<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M4 2H2v20h2v-9h14.17l-5.5 5.5l1.41 1.42L22 12l-7.92-7.92l-1.41 1.42l5.5 5.5H4V2Z"/></svg>

+ 79 - 109
src/views/admin/menu/hook.tsx

@@ -1,37 +1,32 @@
 import {
   deleteMenuList,
   getMenuList,
-  getPermissionList,
   postMenuList,
   putMenuList
 } from "@/api/system";
-import { ListDate } from "@/utils/formateDate";
-import {
-  UseFormatDatePickerHook,
-  UseValidTimeRangeHook
-} from "@/utils/hooks/format";
 import { type PaginationProps } from "@pureadmin/table";
-import { number } from "echarts";
 import { ElMessage, ElMessageBox } from "element-plus";
 import { reactive, ref, computed, onMounted } from "vue";
 
 export function useUser() {
-  const UpdateForm = ref({
-    name: "", // 菜单名
-    path: "", // 组件路径
-    title: "",
-    descs: "", // 描述
-    icon: "", // 图标
-    parentId: "", //父id
-    permissionId: "", //权限id
-    menuStatus: "1", // 按钮标识
-    version: "1", // 是否按钮
-    id: ""
+  //是否可见,0隐藏,1显示
+  const visibleswitchvalue = ref("1");
+  // 是否缓存,0否,1是
+  const keepAliveswitchvalue = ref("1");
+  const UpdateForm: any = ref({
+    name: "", //菜单名称
+    enName: "", //英文名称
+    permission: "", //权限标识
+    path: "", //路由路径
+    parentId: "-1", //父菜单ID
+    icon: "", //菜单图标
+    sortOrder: "", //排序值,越小越靠前
+    embedded: "0", //是否内嵌,0否,1是
+    menuType: "0" //菜单类型,0菜单,1按钮
   });
   const dialogType = ref(1);
   const dataList = ref([]);
   const menuList = ref([]);
-  const permissionList = ref([]);
   const loading = ref(false);
   const dialogUpdateVisible = ref(false);
   const pagination = reactive<PaginationProps>({
@@ -70,19 +65,12 @@ export function useUser() {
     },
     {
       label: "图标",
-      prop: "icon",
-      minWidth: 130
-    },
-    {
-      label: "描述",
-      prop: "descs",
-      minWidth: 130
+      prop: "meta.icon",
+      minWidth: 130,
+      cellRenderer: ({ props, row }) => (
+        <el-text size={props.size}>{row.meta.icon}</el-text>
+      )
     },
-    // {
-    //   label: "状态",
-    //   prop: "status",
-    //   minWidth: 130
-    // },
     {
       label: "操作",
       fixed: "right",
@@ -100,33 +88,16 @@ export function useUser() {
     ];
   });
 
-  // 获取权限列表
-  async function permission() {
-    const { data } = await getPermissionList({});
-    const permission = data.map(item => {
-      return {
-        label: item.name,
-        Id: item.id
-      };
-    });
-    permissionList.value = permission;
-    permissionList.value.unshift({
-      label: "作为菜单",
-      Id: ""
-    });
-  }
-  permission();
-
   // 树形结构格式化
-  function TreeFormatter(data, flag = false) {
+  function TreeFormatter(data) {
     const result = data.map(item => {
-      if (item.children.length != 0) {
+      if (item.children && item.children.length != 0) {
         return {
           label: item.name,
           value: item.id,
-          children: TreeFormatter(item.children, true)
+          children: TreeFormatter(item.children)
         };
-      } else if (item.version != 0) {
+      } else if (item.menuType == 1) {
         return {
           disabled: true,
           label: item.name,
@@ -143,29 +114,33 @@ export function useUser() {
   }
   // 获取全部菜单列表
   async function Menu() {
-    const { data } = await getMenuList({ id: "" });
+    const { data } = await getMenuList({});
+    console.log(data);
     menuList.value = TreeFormatter(data);
     console.log(menuList.value);
     menuList.value.unshift({
       label: "作为顶级菜单",
-      value: "null"
+      value: "-1"
     });
   }
   Menu();
   async function UpdateFormSubmit() {
     if (dialogType.value == 1) {
-      const { status, message } = await postMenuList({
-        name: UpdateForm.value.name, // 菜单名
-        path: UpdateForm.value.path, // 组件路径
-        descs: UpdateForm.value.descs, // 描述
-        title: UpdateForm.value.title, // 名称
-        icon: UpdateForm.value.icon, // 图标
+      const { status, msg } = await postMenuList({
+        name: UpdateForm.value.name,
+        enName: UpdateForm.value.enName,
+        permission: UpdateForm.value.permission,
+        path: UpdateForm.value.path,
         parentId:
           UpdateForm.value.parentId === "null"
             ? null
-            : UpdateForm.value.parentId, //父id
-        permissionId: UpdateForm.value.permissionId, //权限id
-        menuStatus: UpdateForm.value.permissionId === "" ? "0" : "1" // 按钮标识
+            : UpdateForm.value.parentId,
+        icon: UpdateForm.value.icon,
+        visible: visibleswitchvalue.value,
+        sortOrder: UpdateForm.value.sortOrder,
+        keepAlive: keepAliveswitchvalue.value,
+        embedded: UpdateForm.value.embedded,
+        menuType: UpdateForm.value.menuType
       });
       if (status == 1) {
         ElMessage({
@@ -174,28 +149,30 @@ export function useUser() {
         });
         dialogUpdateVisible.value = false;
         onSearch();
-        permission();
         Menu();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
       }
     } else {
-      const { status, message } = await putMenuList({
-        name: UpdateForm.value.name, // 菜单名
-        path: UpdateForm.value.path, // 组件路径
-        descs: UpdateForm.value.descs, // 描述
-        title: UpdateForm.value.title, // 名称
-        icon: UpdateForm.value.icon, // 图标
+      const { status, msg } = await putMenuList({
+        name: UpdateForm.value.name,
+        enName: UpdateForm.value.enName,
+        permission: UpdateForm.value.permission,
+        path: UpdateForm.value.path,
         parentId:
           UpdateForm.value.parentId === "null"
             ? null
-            : UpdateForm.value.parentId, //父id
-        permissionId: UpdateForm.value.permissionId, //权限id
-        menuStatus: UpdateForm.value.permissionId === "" ? "0" : "1", // 按钮标识
-        id: UpdateForm.value.id
+            : UpdateForm.value.parentId,
+        icon: UpdateForm.value.icon,
+        visible: visibleswitchvalue.value,
+        sortOrder: UpdateForm.value.sortOrder,
+        keepAlive: keepAliveswitchvalue.value,
+        embedded: UpdateForm.value.embedded,
+        menuType: UpdateForm.value.menuType,
+        menuId: UpdateForm.value.menuId
       });
       if (status == 1) {
         ElMessage({
@@ -204,10 +181,9 @@ export function useUser() {
         });
         dialogUpdateVisible.value = false;
         onSearch();
-        permission();
         Menu();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
@@ -220,54 +196,51 @@ export function useUser() {
       cancelButtonText: "取消",
       type: "warning"
     }).then(async () => {
-      const { status, message } = await deleteMenuList({ id: row.id });
+      const { status, msg } = await deleteMenuList(row.id);
       if (status == 1) {
         ElMessage({
           message: "删除成功",
           type: "success"
         });
         onSearch();
-        permission();
         Menu();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
       }
     });
   }
-  function AddUser(row) {
+  function AddUser() {
     UpdateForm.value = {
-      name: "", // 菜单名
-      path: "", // 组件路径
-      descs: "", // 描述
-      title: "", // 名称
-      icon: "", // 图标
-      parentId: "", //父id
-      permissionId: "", //权限id
-      menuStatus: "1", // 按钮标识
-      version: "" // 是否按钮
+      name: "", //菜单名
+      enName: "", //英文名称
+      permission: "", //权限标识
+      path: "", //路由路径
+      parentId: "", //父菜单ID
+      icon: "", //菜单图标
+      sortOrder: "", //排序值,越小越靠前
+      embedded: "0", //是否内嵌,0否,1是
+      menuType: "0" //菜单类型,0菜单,1按钮
     };
     dialogType.value = 1;
     dialogUpdateVisible.value = true;
   }
   function handleUpdate(row) {
-    console.log(row);
-
     dialogType.value = 2;
     dialogUpdateVisible.value = true;
     UpdateForm.value = {
-      name: row.name, // 菜单名
-      path: row.path, // 组件路径
-      title: row.title, // 菜单名称
-      descs: row.descs, // 描述
-      icon: row.icon, // 图标
-      parentId: row.parentId ? row.parentId : "null", //父id
-      permissionId: row.permissionId === null ? "" : row.permissionId, //权限id
-      menuStatus: row.version === 0 ? "0" : "1", // 按钮标识
-      version: row.version, // 是否按钮
-      id: row.id // 是否按钮
+      menuId: row.id ? row.id : "",
+      name: row.name ? row.name : "", //菜单名称
+      enName: row.meta.enName ? row.meta.enName : "", //英文名称
+      permission: row.permission ? row.permission : "", //权限标识
+      path: row.path ? row.path : "", //路由路径
+      parentId: row.parentId ? row.parentId : "", //父菜单ID
+      icon: row.meta.icon ? row.meta.icon : "", //菜单图标
+      sortOrder: row.sortOrder, //排序值,越小越靠前
+      embedded: row.embedded ? row.embedded : "0", //是否内嵌,0否,1是
+      menuType: row.menuType ? row.menuType : "" //菜单类型,0菜单,1按钮
     };
   }
 
@@ -297,17 +270,13 @@ export function useUser() {
   }
   async function onSearch() {
     loading.value = true;
-    const { data, other } = await getMenuList({
-      pageSize: pagination.pageSize,
-      pageNum: pagination.currentPage
-    });
+    const { data } = await getMenuList({});
     dataList.value = data;
-    pagination.total = other;
+    pagination.total = data.length;
     setTimeout(() => {
       loading.value = false;
     }, 500);
   }
-
   onMounted(() => {
     onSearch();
   });
@@ -319,11 +288,12 @@ export function useUser() {
     pagination,
     buttonClass,
     dialogUpdateVisible,
+    visibleswitchvalue,
+    keepAliveswitchvalue,
     UpdateFormSubmit,
     submit,
     UpdateForm,
     menuList,
-    permissionList,
     dialogType,
     AddUser,
     onSearch,

+ 29 - 26
src/views/admin/menu/index.vue

@@ -1,16 +1,14 @@
 <script lang="ts">
 // 声明额外的选项
 export default {
-  name: "Menu"
+  name: "menu"
 };
 </script>
 <script setup lang="ts">
-import { ref } from "vue";
 import { useUser } from "./hook";
 import { hasAuth } from "@/router/utils";
 import { PureTableBar } from "@/components/RePureTableBar";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
-import IconSelect from '@/components/ReIcon/src/Select.vue';
 
 import Delete from "@iconify-icons/ep/delete";
 import Search from "@iconify-icons/ep/search";
@@ -29,13 +27,14 @@ const {
   submit,
   dialogType,
   menuList,
-  permissionList,
   AddUser,
   handleUpdate,
   handleDelete,
   handleSizeChange,
   handleCurrentChange,
-  handleSelectionChange
+  handleSelectionChange,
+  visibleswitchvalue,
+  keepAliveswitchvalue
 } = useUser();
 defineExpose({
   loading,
@@ -49,13 +48,14 @@ defineExpose({
   onSearch,
   dialogType,
   menuList,
-  permissionList,
   AddUser,
   handleUpdate,
   handleDelete,
   handleSizeChange,
   handleCurrentChange,
-  handleSelectionChange
+  handleSelectionChange,
+  visibleswitchvalue,
+  keepAliveswitchvalue
 });
 </script>
 
@@ -64,7 +64,7 @@ defineExpose({
   //- 表格组件
   PureTableBar.mt12(title="后台菜单管理", @refresh="onSearch" )
     template(#buttons)
-      el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser"  v-if="hasAuth(['menuAdd'])") 新增菜单
+      el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser") 新增菜单
     template(v-slot="{ size, checkList }")
       pure-table(stripe 
         border,
@@ -90,7 +90,6 @@ defineExpose({
             :size="size"
             @click="handleUpdate(row)"
             :icon="useRenderIcon(EditPen)"
-            v-if="hasAuth(['menuEdit'])"
           ) 编辑
           el-button.reset-margin(
             link
@@ -98,27 +97,40 @@ defineExpose({
             :size="size"
             @click="handleDelete(row)"
             :icon="useRenderIcon(Delete)"
-            v-if="hasAuth(['menuDelete'])"
           ) 删除
 
-  el-dialog(v-model='dialogUpdateVisible' width="40%" :title="dialogType == 1 ?'添加菜单' : '修改菜单'" :close-on-click-modal="false")
+  el-dialog(v-model='dialogUpdateVisible' width="40%" :close-on-click-modal="false" :title="dialogType == 1 ?'添加菜单' : '修改菜单'" :close-on-click-modal="false")
     el-form(:model='UpdateForm' 
       label-position="left"
       label-width="100px")
+      el-form-item(label='权限类型')
+        el-select(
+          v-model="UpdateForm.menuType"
+          placeholder="请选择权限类型"
+          class="!w-[300px]")
+          el-option(label="菜单" value="0")
+          el-option(label="按钮" value="1")
       el-form-item(label='菜单标题' prop="name")
         el-input(v-model='UpdateForm.name' autocomplete='off' class="!w-[300px]"
           placeholder="请输入菜单标题")
-      el-form-item(label='菜单名称' prop="title")
+      el-form-item(label='菜单名称' prop="title" v-if="UpdateForm.menuType == '0'")
         el-input(v-model='UpdateForm.title' autocomplete='off' class="!w-[300px]"
           placeholder="请输入菜单名称(英文字母名称)")
-      el-form-item(label='菜单描述' prop="descs")
-        el-input(v-model='UpdateForm.descs' autocomplete='off' class="!w-[300px]"
-          placeholder="请输入菜单描述")
-      el-form-item(label='菜单路径' prop="path")
+      el-form-item(label='权限标识' prop="permission" v-if="UpdateForm.menuType == '1'")
+        el-input(v-model='UpdateForm.permission' autocomplete='off' class="!w-[300px]"
+          placeholder="请输入权限标识")
+      el-form-item(label='菜单路径' prop="path" v-if="UpdateForm.menuType == '0'")
         el-input(v-model='UpdateForm.path' autocomplete='off' class="!w-[300px]"
           placeholder="请输入菜单路径")
-      el-form-item(label='图标' prop="icon")
+      el-form-item(label='图标' prop="icon" v-if="UpdateForm.menuType == '0'")
         IconSelect(v-model="UpdateForm.icon")
+      el-form-item(label='排序' prop="path" v-if="UpdateForm.menuType == '0'")
+        el-input(v-model='UpdateForm.sortOrder' autocomplete='off' type="number" class="!w-[300px]"
+          placeholder="请输入排序值(越小越靠前)")
+      el-form-item(label='是否显示' prop="visibleswitchvalue" v-if="UpdateForm.menuType == '0'")
+        el-switch(v-model="visibleswitchvalue" style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" active-value="1" inactive-value="0")
+      el-form-item(label='是否缓存' prop="keepAliveswitchvalue" v-if="UpdateForm.menuType == '0'")
+        el-switch(v-model="keepAliveswitchvalue" style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" active-value="1" inactive-value="0")
       el-form-item(label='父级菜单')
         el-tree-select(
           v-model="UpdateForm.parentId" 
@@ -128,15 +140,6 @@ defineExpose({
           show-checkbox
           check-on-click-node
           class="!w-[300px]")
-      el-form-item(label="按钮权限:", prop="permissionId")
-        el-select(
-          v-model="UpdateForm.permissionId",
-          placeholder="请选择按钮权限",
-          clearable,
-          filterable
-          class="!w-[300px]"
-        )
-          el-option(:label="item.label", :value="item.Id" v-for="(item,index) in permissionList")
     template(#footer)
       span.dialog-footer
         el-button(@click='dialogUpdateVisible = false') 关闭

+ 223 - 0
src/views/admin/post/hook.tsx

@@ -0,0 +1,223 @@
+import {
+  deletePostList,
+  getPostList,
+  postPostList,
+  putPostList
+} from "@/api/system";
+import { type PaginationProps } from "@pureadmin/table";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { reactive, ref, computed, onMounted } from "vue";
+
+export function useUser() {
+  const form: any = ref({
+    postName: ""
+  });
+  const UpdateForm: any = ref({
+    postCode: "", //岗位编码
+    postName: "", //岗位名称
+    postSort: "", //岗位排序
+    remark: "" //岗位描述
+  });
+  const dialogType = ref(1);
+  const dataList = ref([]);
+  const loading = ref(false);
+  const dialogUpdateVisible = ref(false);
+  const pagination = reactive<PaginationProps>({
+    total: 0,
+    pageSize: 10,
+    currentPage: 1,
+    background: true
+  });
+  const columns: TableColumnList = [
+    {
+      type: "selection",
+      width: 55,
+      align: "left",
+      hide: ({ checkList }) => !checkList.includes("勾选列")
+    },
+    {
+      label: "序号",
+      type: "index",
+      width: 70,
+      hide: ({ checkList }) => !checkList.includes("序号列")
+    },
+    {
+      label: "岗位ID",
+      prop: "postId",
+      minWidth: 130
+    },
+    {
+      label: "岗位名称",
+      prop: "postName",
+      minWidth: 130
+    },
+    {
+      label: "岗位描述",
+      prop: "remark",
+      minWidth: 130
+    },
+    {
+      label: "操作",
+      fixed: "right",
+      width: 200,
+      slot: "operation"
+    }
+  ];
+  const buttonClass = computed(() => {
+    return [
+      "!h-[20px]",
+      "reset-margin",
+      "!text-gray-500",
+      "dark:!text-white",
+      "dark:hover:!text-primary"
+    ];
+  });
+
+  async function UpdateFormSubmit() {
+    if (dialogType.value == 1) {
+      const { status, msg } = await postPostList(UpdateForm.value);
+      if (status == 1) {
+        ElMessage({
+          message: "新增岗位成功",
+          type: "success"
+        });
+        dialogUpdateVisible.value = false;
+        onSearch();
+      } else {
+        ElMessageBox.alert(msg, "提示", {
+          confirmButtonText: "关闭",
+          type: "warning"
+        });
+      }
+    } else {
+      console.log(UpdateForm.value);
+      const { status, msg } = await putPostList(UpdateForm.value);
+      if (status == 1) {
+        ElMessage({
+          message: "岗位修改成功",
+          type: "success"
+        });
+        dialogUpdateVisible.value = false;
+        onSearch();
+      } else {
+        ElMessageBox.alert(msg, "提示", {
+          confirmButtonText: "关闭",
+          type: "warning"
+        });
+      }
+    }
+  }
+  function handleDelete(row) {
+    ElMessageBox.confirm(`是否删除名称为:${row.postName}的岗位? `, "提示", {
+      confirmButtonText: "删除",
+      cancelButtonText: "取消",
+      type: "warning"
+    }).then(async () => {
+      const { status, msg } = await deletePostList(row.postId);
+      if (status == 1) {
+        ElMessage({
+          message: "删除成功",
+          type: "success"
+        });
+        onSearch();
+      } else {
+        ElMessageBox.alert(msg, "提示", {
+          confirmButtonText: "关闭",
+          type: "warning"
+        });
+      }
+    });
+  }
+  function AddUser() {
+    UpdateForm.value = {
+      postCode: "", //岗位编码
+      postName: "", //岗位名称
+      postSort: "", //岗位排序
+      remark: "" //岗位描述
+    };
+    dialogType.value = 1;
+    dialogUpdateVisible.value = true;
+  }
+  function handleUpdate(row) {
+    dialogType.value = 2;
+    dialogUpdateVisible.value = true;
+    UpdateForm.value = {
+      postId: row.postId,
+      postCode: row.postCode, //岗位编码
+      postName: row.postName, //岗位名称
+      postSort: row.postSort, //岗位排序
+      remark: row.remark //岗位描述
+    };
+  }
+
+  function handleSizeChange(val: number) {
+    console.log(`${val} items per page`);
+    onSearch();
+  }
+
+  function handleCurrentChange(val: number) {
+    if (typeof val !== "number") return;
+    console.log(`current page: ${val}`);
+    onSearch();
+  }
+
+  function handleSelectionChange(val) {
+    console.log("handleSelectionChange", val);
+    onSearch();
+  }
+
+  // 搜索函数(请求表格数据列表)
+  function submit(e: { keyCode: number }) {
+    if (e.keyCode == 229) {
+      return;
+    } else {
+      onSearch();
+    }
+  }
+  async function onSearch(type = "") {
+    if (type == "search" && !Object.values(form).some(item => !!item)) {
+      return ElMessage({
+        message: "请输入查询条件",
+        type: "error"
+      });
+    }
+    if (type == "all") {
+      form.value.postName = "";
+    }
+    loading.value = true;
+    const { data } = await getPostList({
+      ...form.value,
+      pageSize: pagination.pageSize,
+      pageNum: pagination.currentPage
+    });
+    dataList.value = data.records;
+    pagination.total = data.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 500);
+  }
+  onMounted(() => {
+    onSearch();
+  });
+
+  return {
+    loading,
+    columns,
+    dataList,
+    pagination,
+    buttonClass,
+    dialogUpdateVisible,
+    UpdateFormSubmit,
+    submit,
+    UpdateForm,
+    dialogType,
+    AddUser,
+    onSearch,
+    handleUpdate,
+    handleDelete,
+    handleSizeChange,
+    handleCurrentChange,
+    handleSelectionChange,
+    form
+  };
+}

+ 189 - 0
src/views/admin/post/index.vue

@@ -0,0 +1,189 @@
+<script lang="ts">
+// 声明额外的选项
+export default {
+  name: "post"
+};
+</script>
+<script setup lang="ts">
+import { useUser } from "./hook";
+import { PureTableBar } from "@/components/RePureTableBar";
+import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+
+import Delete from "@iconify-icons/ep/delete";
+import Search from "@iconify-icons/ep/search";
+import Refresh from "@iconify-icons/ep/refresh";
+import AddFill from "@iconify-icons/ri/add-circle-line";
+
+const {
+  loading,
+  columns,
+  dataList,
+  pagination,
+  dialogUpdateVisible,
+  UpdateFormSubmit,
+  UpdateForm,
+  onSearch,
+  submit,
+  dialogType,
+  AddUser,
+  handleUpdate,
+  handleDelete,
+  handleSizeChange,
+  handleCurrentChange,
+  handleSelectionChange,
+  form
+} = useUser();
+defineExpose({
+  loading,
+  columns,
+  dataList,
+  pagination,
+  dialogUpdateVisible,
+  UpdateFormSubmit,
+  UpdateForm,
+  submit,
+  onSearch,
+  dialogType,
+  AddUser,
+  handleUpdate,
+  handleDelete,
+  handleSizeChange,
+  handleCurrentChange,
+  handleSelectionChange,
+  form
+});
+</script>
+
+<template lang="pug">
+.main 
+  div
+    el-form.bg-bg_color.pl-8.pt-4.pr-8(
+      label-position="left"
+      label-width="100px"
+      ref="formRef",
+      :inline="true",
+      :model="form",
+      :rules="rules",
+      class="w-[99/100]"
+    )
+      el-form-item(label="岗位名称:", prop="postName")
+        el-input(
+          v-model="form.postName",
+          placeholder="请输入岗位名称",
+          clearable,@keydown.enter="submit"
+          class="!w-[230px]"
+        )
+      el-form-item
+        el-button(
+          type="primary",
+          :icon="useRenderIcon(Search)",
+          :loading="loading",
+          @click="onSearch('search')"
+        ) 查询
+      el-form-item
+        el-button(
+          type="primary",
+          :icon="useRenderIcon(Search)",
+          :loading="loading",
+          @click="onSearch('all')"
+        ) 全部
+
+  //- 表格组件
+  PureTableBar.mt12(title="后台岗位管理", @refresh="onSearch" )
+    template(#buttons)
+      el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser") 新增岗位
+    template(v-slot="{ size, checkList }")
+      pure-table(stripe 
+        border,
+        row-key="id",
+        align-whole="center",
+        table-layout="auto",
+        :loading="loading",
+        :size="size",
+        :data="dataList",
+        :columns="columns",
+        :checkList="checkList",
+        :pagination="pagination",
+        :paginationSmall="size === 'default' ? true : false",
+        :header-cell-style="{ background: 'var(--el-table-row-hover-bg-color)', color: 'var(--el-text-color-primary)' }",
+        @selection-change="handleSelectionChange",
+        @size-change="handleSizeChange",
+        @current-change="handleCurrentChange"
+      )          
+        template(#operation="{ row }")
+          el-button.reset-margin(
+            link
+            type="primary"
+            :size="size"
+            @click="handleUpdate(row)"
+            :icon="useRenderIcon(EditPen)"
+          ) 编辑
+          el-button.reset-margin(
+            link
+            type="primary"
+            :size="size"
+            @click="handleDelete(row)"
+            :icon="useRenderIcon(Delete)"
+          ) 删除
+
+  el-dialog(v-model='dialogUpdateVisible' width="40%" :close-on-click-modal="false" :title="dialogType == 1 ?'添加岗位' : '修改岗位'" :close-on-click-modal="false")
+    el-form(:model='UpdateForm' 
+      label-position="left"
+      label-width="100px")
+      el-form-item(label='岗位名称' prop="postName")
+        el-input(v-model='UpdateForm.postName' autocomplete='off' class="!w-[300px]"
+          placeholder="请输入岗位名称")
+      el-form-item(label='岗位编码' prop="postCode")
+        el-input(v-model='UpdateForm.postCode' autocomplete='off' class="!w-[300px]"
+          placeholder="请输入岗位编码")
+      el-form-item(label='岗位描述' prop="remark")
+        el-input(v-model='UpdateForm.remark' autocomplete='off' class="!w-[300px]"
+          placeholder="请输入岗位描述")
+      el-form-item(label='岗位排序' prop="postSort")
+        el-input(v-model='UpdateForm.postSort' autocomplete='off' type="number" class="!w-[300px]"
+          placeholder="请输入排序值(越小越靠前)")
+    template(#footer)
+      span.dialog-footer
+        el-button(@click='dialogUpdateVisible = false') 关闭
+        el-button(type='primary' @click='UpdateFormSubmit') 确认提交
+</template>
+
+<style scoped lang="scss">
+:deep(.el-dropdown-menu__item i) {
+  margin: 0;
+}
+
+:deep(.el-form-item__label) {
+  font-weight: 700;
+}
+
+:deep(.el-pagination) {
+  flex-flow: wrap;
+}
+
+:deep(.is-draggable) {
+  max-height: 80vh;
+  overflow: auto;
+}
+
+:deep(.el-dialog__header) {
+  position: sticky;
+  top: 0;
+  z-index: 2;
+  background: #fff;
+}
+
+.collapsedom {
+  padding: 0 20px;
+  background-color: #fff;
+}
+
+.ovh-x {
+  height: 40vh;
+  overflow-y: auto;
+}
+
+:deep(.el-descriptions__header) {
+  margin: 16px 0 !important;
+}
+</style>

+ 1 - 0
src/views/admin/post/svg/expand.svg

@@ -0,0 +1 @@
+<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M22 4V2H2v2h9v14.17l-5.5-5.5-1.42 1.41L12 22l7.92-7.92-1.42-1.41-5.5 5.5V4h9Z"/></svg>

+ 1 - 0
src/views/admin/post/svg/unexpand.svg

@@ -0,0 +1 @@
+<svg width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M4 2H2v20h2v-9h14.17l-5.5 5.5l1.41 1.42L22 12l-7.92-7.92l-1.41 1.42l5.5 5.5H4V2Z"/></svg>

+ 140 - 99
src/views/admin/role/hook.tsx

@@ -1,21 +1,27 @@
-import { deleteRoleList, getRoleList, getRoleRightList, getRoleTreeList, postRoleList, putRoleList } from "@/api/system";
+import {
+  deleteRoleList,
+  getMenuList,
+  getRoleList,
+  getRoleRightList,
+  postRoleList,
+  putRoleList,
+  putRoleMenuList
+} from "@/api/system";
 import { type PaginationProps } from "@pureadmin/table";
 import { ElMessage, ElMessageBox } from "element-plus";
 import { reactive, ref, computed, onMounted } from "vue";
 
 export function useUser() {
-  let form = reactive({
-    name: ""
+  const form = reactive({
+    roleName: ""
   });
-  let AddForm = ref([]);
-  let AddAllForm = ref([]);
-  let AddFormdata = ref({
-    name: "",
-    sn: "",
-    menus: "",
-    permissions: "",
+  const AddForm = ref([]);
+  const AddFormdata: any = ref({
+    roleName: "",
+    roleDesc: "",
+    roleCode: "roleCode"
   });
-  let dialogType = ref(1);
+  const dialogType = ref(1);
   const AddFormvalueStrictly = ref([]);
   const dataList = ref([]);
   const loading = ref(true);
@@ -41,17 +47,17 @@ export function useUser() {
     },
     {
       label: "角色ID",
-      prop: "id",
+      prop: "roleId",
       minWidth: 130
     },
     {
       label: "角色名称",
-      prop: "name",
+      prop: "roleName",
       minWidth: 130
     },
     {
       label: "角色描述",
-      prop: "sn",
+      prop: "roleDesc",
       minWidth: 130
     },
     {
@@ -72,9 +78,8 @@ export function useUser() {
   });
   async function AddFormSubmit() {
     if (dialogType.value == 1) {
-      AddFormdata.value.menus = ResultFormatter(AddFormvalueStrictly.value, 0);
-      AddFormdata.value.permissions = ResultFormatter(AddFormvalueStrictly.value, 1);
-      const { status, message } = await postRoleList(AddFormdata.value);
+      console.log(AddFormdata.value);
+      const { status, msg } = await postRoleList(AddFormdata.value);
       if (status == 1) {
         ElMessage({
           message: "添加角色成功",
@@ -83,22 +88,19 @@ export function useUser() {
         dialogAddVisible.value = false;
         AddFormvalueStrictly.value = [];
         AddFormdata.value = {
-          name: "",
-          sn: "",
-          menus: "",
-          permissions: "",
+          roleName: "",
+          roleDesc: "",
+          roleCode: ""
         };
         onSearch();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
-      };
+      }
     } else {
-      AddFormdata.value.menus = ResultFormatter(AddFormvalueStrictly.value, 0);
-      AddFormdata.value.permissions = ResultFormatter(AddFormvalueStrictly.value, 1);
-      const { status, message } = await putRoleList(AddFormdata.value);
+      const { status, msg } = await putRoleList(AddFormdata.value);
       if (status == 1) {
         ElMessage({
           message: "编辑角色成功",
@@ -107,26 +109,23 @@ export function useUser() {
         dialogAddVisible.value = false;
         AddFormvalueStrictly.value = [];
         AddFormdata.value = {
-          name: "",
-          sn: "",
-          menus: "",
-          permissions: "",
+          roleName: "",
+          roleDesc: "",
+          roleCode: ""
         };
         onSearch();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
-      };
-
+      }
     }
   }
   // 删除角色
   function handleDelete(row) {
     ElMessageBox.confirm(
-      `是否删除该角色?  角色名称为:${row.name
-      }`,
+      `是否删除该角色?  角色名称为:${row.roleName}`,
       "提示",
       {
         confirmButtonText: "删除",
@@ -134,7 +133,7 @@ export function useUser() {
         type: "warning"
       }
     ).then(async () => {
-      const { status, message } = await deleteRoleList({ id: row.id });
+      const { status, msg } = await deleteRoleList(row.roleId);
       if (status == 1) {
         ElMessage({
           message: "删除成功",
@@ -142,134 +141,172 @@ export function useUser() {
         });
         onSearch();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
-      };
-    })
+      }
+    });
   }
   // 添加角色
   function AddUser() {
     dialogType.value = 1;
     AddFormvalueStrictly.value = [];
     AddFormdata.value = {
-      name: "",
-      sn: "",
-      menus: "",
-      permissions: "",
+      roleName: "",
+      roleDesc: "",
+      roleCode: "roleCode"
     };
     dialogAddVisible.value = true;
   }
   // 编辑角色
   async function handleUpdate(row) {
     dialogType.value = 2;
-
-    const arr = await getrolelisttree(row)
-    AddFormvalueStrictly.value = RoleTreeFormatter(arr);
     loading.value = false;
-    AddFormdata.value.id = row.id;
-    AddFormdata.value.name = row.name;
-    AddFormdata.value.sn = row.sn;
+    AddFormdata.value.roleId = row.roleId; //角色ID
+    AddFormdata.value.roleName = row.roleName; //角色名称
+    AddFormdata.value.roleCode = row.roleCode; //角色编码
+    AddFormdata.value.roleDesc = row.roleDesc; //角色描述
+    AddFormdata.value.createBy = row.createBy; //创建人
+    AddFormdata.value.updateBy = row.updateBy; //修改人
     dialogAddVisible.value = true;
   }
   // 当前页数量切换
   function handleSizeChange(val: number) {
-    onSearch()
+    if (typeof val === "number") {
+      pagination.pageSize = val;
+      onSearch();
+    }
   }
   // 当前页码切换
   function handleCurrentChange(val: number) {
-    onSearch()
+    if (typeof val === "number") {
+      pagination.currentPage = val;
+      onSearch();
+    }
   }
   // 选择表格项
-  function handleSelectionChange(val) {
-    onSearch()
-  }
+  function handleSelectionChange() { }
   // 搜索函数(请求表格数据列表)
   function submit(e: { keyCode: number }) {
     if (e.keyCode == 229) {
       return;
     } else {
-      onSearch('search');
+      onSearch("search");
     }
   }
   // 搜索列表
-  async function onSearch(type = '') {
-
-    if (type == 'search' && !Object.values(form).some(item => !!item)) {
+  async function onSearch(type = "") {
+    if (type == "search" && !Object.values(form).some(item => !!item)) {
       return ElMessage({
         message: "请输入查询条件",
         type: "error"
       });
-    };
-    if (type == 'all') {
-      form.name = "";
+    }
+    if (type == "all") {
+      form.roleName = "";
     }
     loading.value = true;
-    const { data, other } = await getRoleList({ ...form, pageSize: pagination.pageSize, pageNum: pagination.currentPage });
-    dataList.value = data;
-    pagination.total = other;
-    setTimeout(() => {
-      loading.value = false;
-    }, 500);
-  }
-  getroletree();
-  // 获取权限树
-  async function getroletree() {
-    loading.value = true;
-    const { data } = await getRoleTreeList({});
-    AddForm.value = TreeFormatter(data);
+    const { data } = await getRoleList({
+      ...form,
+      pageSize: pagination.pageSize,
+      pageNum: pagination.currentPage
+    });
+    dataList.value = data.records;
+    pagination.total = data.total;
     setTimeout(() => {
       loading.value = false;
     }, 500);
   }
-  // 获取角色权限树
-  async function getrolelisttree(row) {
-    loading.value = true;
-    const { data } = await getRoleRightList({ id: row.id });
-    return data;
-
-  }
   // 树形结构格式化
   function TreeFormatter(data) {
     const result = data.map(item => {
       if (item.children) {
         return {
           label: item.name,
-          value: item.id + "," + item.permissionId,
+          id: item.id,
+          // value: item.id,
           children: TreeFormatter(item.children)
-        }
+        };
       } else {
         return {
           label: item.name,
-          value: item.id + "," + item.permissionId
-        }
+          id: item.id
+          // value: item.id
+        };
       }
-    })
-    return result
+    });
+    return result;
   }
+
   // 个人权限树形结构格式化
   function RoleTreeFormatter(data) {
-    let arr = [];
+    const arr = [];
     data.forEach(item => {
       if (item.children && item.children.length !== 0) {
-        arr.push(item.id + "," + item.permissionId)
-        arr.push(...RoleTreeFormatter(item.children))
+        arr.push(item.id);
+        arr.push(...RoleTreeFormatter(item.children));
       } else {
-        arr.push(item.id + "," + item.permissionId)
-      };
+        arr.push(item.id);
+      }
     });
     return arr;
   }
-  // 传输权限格式化
-  function ResultFormatter(data, type) {
-      return data.map(item => {
-        return item.split(',')[type]
-      })
+
+  // 获取角色权限树
+  async function getrolelisttree(row) {
+    const { data } = await getRoleRightList({ roleId: row.roleId });
+    return data;
   }
 
+  const AuthorizationVisible = ref(false);
+  // 获取权限树
+  async function getroletree() {
+    loading.value = true;
+    const { data } = await getMenuList({});
+    AddForm.value = TreeFormatter(data);
+    console.log(AddForm.value);
+    setTimeout(() => {
+      loading.value = false;
+    }, 500);
+  }
+  getroletree();
+  const roleId = ref("");
+  // 授权
+  async function handleAuthorization(row) {
+    roleId.value = row.roleId;
+    const arr = await getrolelisttree(row);
+    console.log(arr);
+    AddFormvalueStrictly.value = arr;
+    AuthorizationVisible.value = true;
+    menuTree.value.setCheckedKeys(arr);
+  }
+  const menuTree = ref();
+  // 提交授权修改
+  async function AddAuthorization() {
+    const menuIds = [
+      ...menuTree.value.getHalfCheckedKeys(),
+      ...menuTree.value.getCheckedKeys()
+    ].join(",");
+    const { status, msg } = await putRoleMenuList({
+      roleId: roleId.value,
+      menuIds
+    });
+    if (status == 1) {
+      ElMessage({
+        message: "调整授权成功",
+        type: "success"
+      });
+      AuthorizationVisible.value = false;
+    } else {
+      ElMessageBox.alert(msg, "提示", {
+        confirmButtonText: "关闭",
+        type: "warning"
+      });
+    }
+  }
   onMounted(() => {
-    // onSearch();
+    onSearch();
   });
 
   return {
@@ -292,6 +329,10 @@ export function useUser() {
     handleDelete,
     handleSizeChange,
     handleCurrentChange,
-    handleSelectionChange
+    handleSelectionChange,
+    handleAuthorization,
+    AuthorizationVisible,
+    menuTree,
+    AddAuthorization
   };
 }

+ 40 - 15
src/views/admin/role/index.vue

@@ -20,6 +20,10 @@ import Search from "@iconify-icons/ep/search";
 import Refresh from "@iconify-icons/ep/refresh";
 import AddFill from "@iconify-icons/ri/add-circle-line";
 const formRef = ref();
+const defaultProps = {
+  children: "children",
+  label: "label"
+};
 const {
   form,
   loading,
@@ -39,7 +43,11 @@ const {
   handleDelete,
   handleSizeChange,
   handleCurrentChange,
-  handleSelectionChange
+  handleSelectionChange,
+  handleAuthorization,
+  AuthorizationVisible,
+  menuTree,
+  AddAuthorization
 } = useUser();
 defineExpose({
   form,
@@ -60,7 +68,12 @@ defineExpose({
   handleDelete,
   handleSizeChange,
   handleCurrentChange,
-  handleSelectionChange
+  handleSelectionChange,
+  handleAuthorization,
+  AuthorizationVisible,
+  AddAuthorization,
+  menuTree,
+  defaultProps
 });
 </script>
 
@@ -76,9 +89,9 @@ defineExpose({
       :rules="rules",
       class="w-[99/100]"
     )
-      el-form-item(label="角色名称:", prop="AdminName")
+      el-form-item(label="角色名称:", prop="roleName")
         el-input(
-          v-model="form.Name",
+          v-model="form.roleName",
           placeholder="请输入角色名称",
           clearable,@keydown.enter="submit"
           class="!w-[230px]"
@@ -89,7 +102,6 @@ defineExpose({
           :icon="useRenderIcon(Search)",
           :loading="loading",
           @click="onSearch('search')"
-          v-if="hasAuth(['getRoleList'])"
         ) 查询
       el-form-item
         el-button(
@@ -97,13 +109,12 @@ defineExpose({
           :icon="useRenderIcon(Refresh)",
           :loading="loading",
           @click="onSearch('all')"
-          v-if="hasAuth(['getRoleList'])"
         ) 全部
     //- 表格组件
     PureTableBar.mt12(title="后台角色管理", @refresh="onSearch" )
       template(#buttons)
         //- el-button(v-if="hasAuth(['add'])" type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser" 
-        el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser" v-if="hasAuth(['addRole'])" ) 新增角色
+        el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser") 新增角色
       template(v-slot="{ size, checkList }")
         pure-table(
           stripe 
@@ -131,7 +142,6 @@ defineExpose({
                 :size="size"
                 :icon="useRenderIcon(EditPen)"
                 @click="handleUpdate(row)"
-                v-if="hasAuth(['RoleEdit'])"
               ) 编辑
               el-button(
                 class="reset-margin"
@@ -140,20 +150,35 @@ defineExpose({
                 :size="size"
                 :icon="useRenderIcon(Delete)"
                 @click="handleDelete(row)"
-                v-if="hasAuth(['RoleDelete'])"
               ) 删除
+              el-button(
+                class="reset-margin"
+                link
+                type="primary"
+                :size="size"
+                :icon="useRenderIcon(Password)"
+                @click="handleAuthorization(row)"
+              ) 授权
+  el-dialog(v-model='AuthorizationVisible' :close-on-click-modal="false" width="60%" title="角色授权")
+    //- el-form(:model='AddFormdata' label-position="left" label-width="100px")
+      el-form-item(label='权限' required)
+        //- el-tree-select(v-model="AddFormvalueStrictly" :data="AddForm" multiple size="large" collapse-tags collapse-tags-tooltip :max-collapse-tags="3" :render-after-expand="false" show-checkbox check-strictly check-on-click-node class="!w-[230px]")
+    el-scrollbar(height="400px")
+      el-tree(:default-checked-keys="AddFormvalueStrictly" default-expand-all check-on-click-node node-key="id" :expand-on-click-node="false" check-strictly :props="defaultProps" :data="AddForm" class="!w-[230px]" show-checkbox ref="menuTree")
+    template(#footer)
+      span.dialog-footer
+        el-button(@click='AuthorizationVisible = false') 关闭
+        el-button(type='primary' @click='AddAuthorization') 确认提交
   el-dialog(v-model='dialogAddVisible' width="60%" :title="dialogType == 1? '新增角色':'修改角色'")
     el-form(:model='AddFormdata' 
       label-position="left"
       label-width="100px")
-      el-form-item(label='角色名称' prop="name")
-        el-input(v-model='AddFormdata.name' autocomplete='off' class="!w-[230px]"
+      el-form-item(label='角色名称' prop="roleName")
+        el-input(v-model='AddFormdata.roleName' autocomplete='off' class="!w-[230px]"
           placeholder="请输入角色名称")
-      el-form-item(label='角色描述' prop="sn")
-        el-input(v-model='AddFormdata.sn' autocomplete='off' class="!w-[230px]"
+      el-form-item(label='角色描述' prop="roleDesc")
+        el-input(v-model='AddFormdata.roleDesc' autocomplete='off' class="!w-[230px]"
           placeholder="请输入角色描述")
-      el-form-item(label='权限' required)
-        el-tree-select(v-model="AddFormvalueStrictly" :data="AddForm" multiple size="large" collapse-tags collapse-tags-tooltip :max-collapse-tags="3" :render-after-expand="false" show-checkbox check-strictly check-on-click-node class="!w-[230px]")
     template(#footer)
       span.dialog-footer
         el-button(@click='dialogAddVisible = false') 关闭

+ 145 - 98
src/views/admin/user/hook.tsx

@@ -1,16 +1,15 @@
 import {
   deleteUserList,
   editUserList,
-  getRoleList,
+  getAllRoleList,
   getUserList,
-  postUserList
+  AddUserList,
+  lockUserList,
+  getAllDeptList,
+  getAllPostList
 } from "@/api/system";
-import { ListDate } from "@/utils/formateDate";
-import {
-  UseFormatDatePickerHook,
-  UseValidTimeRangeHook
-} from "@/utils/hooks/format";
 import { type PaginationProps } from "@pureadmin/table";
+import { log } from "console";
 import { ElMessage, ElMessageBox } from "element-plus";
 import { reactive, ref, computed, onMounted } from "vue";
 
@@ -20,18 +19,23 @@ export function useUser() {
     phone: "",
     deptId: ""
   });
-  const UpdateForm = ref({
-    account: "",
-    username: "",
-    password: "",
-    roleIds: [],
-    phone: "",
-    adminType: "1",
-    id: ""
+  const UpdateForm: any = ref({
+    username: "", //用户名
+    password: "", //密码
+    phone: "", //电话号码
+    nickname: "", //昵称
+    name: "", //姓名
+    email: "", //邮箱地址
+    role: "", //角色id集合
+    post: "", //岗位集合
+    deptId: "", //所属部门ID
+    avatar: "" //头像
   });
   const dialogType = ref(1);
   const dataList = ref([]);
   const optionList = ref([]);
+  const optionDeptList = ref([]);
+  const optionPostList = ref([]);
   const loading = ref(false);
   const dialogUpdateVisible = ref(false);
   const pagination = reactive<PaginationProps>({
@@ -54,34 +58,27 @@ export function useUser() {
       hide: ({ checkList }) => !checkList.includes("序号列")
     },
     {
-      label: "用户ID",
-      prop: "id",
+      label: "用户",
+      prop: "username",
       minWidth: 130
     },
     {
-      label: "角色名称",
-      prop: "roles",
+      label: "电话号码",
+      prop: "phone",
+      minWidth: 130
+    },
+    {
+      label: "角色",
+      prop: "roleList",
       minWidth: 130,
-      formatter: ({ roles }) => {
+      formatter: ({ roleList }) => {
         let RoleName = "";
-        optionList.value.forEach(item => {
-          if (item.Id === roles[0].id) {
-            RoleName = item.label;
-          }
+        roleList.forEach(item => {
+          RoleName = RoleName + "\n" + item.roleName;
         });
         return RoleName;
       }
     },
-    {
-      label: "用户名",
-      prop: "account",
-      minWidth: 130
-    },
-    {
-      label: "名称",
-      prop: "username",
-      minWidth: 130
-    },
     {
       label: "操作",
       fixed: "right",
@@ -101,14 +98,8 @@ export function useUser() {
 
   async function UpdateFormSubmit() {
     if (dialogType.value == 1) {
-      const { status, message } = await postUserList({
-        account: UpdateForm.value.account,
-        username: UpdateForm.value.username,
-        password: UpdateForm.value.password,
-        roleIds: [UpdateForm.value.roleIds],
-        phone: UpdateForm.value.phone,
-        adminType: "1"
-      });
+      console.log(UpdateForm.value);
+      const { status, msg } = await AddUserList(UpdateForm.value);
       if (status == 1) {
         ElMessage({
           message: "新增账号成功",
@@ -125,39 +116,23 @@ export function useUser() {
         };
         onSearch();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
       }
     } else {
-      const { status, message } = await editUserList({
-        account: UpdateForm.value.account,
-        username: UpdateForm.value.username,
-        password: UpdateForm.value.password,
-        roleIds: [UpdateForm.value.roleIds],
-        phone: UpdateForm.value.phone,
-        adminType: "1",
-        id: UpdateForm.value.id
-      });
+      console.log(UpdateForm.value);
+      const { status, msg } = await editUserList(UpdateForm.value);
       if (status == 1) {
         ElMessage({
           message: "修改账号成功",
           type: "success"
         });
         dialogUpdateVisible.value = false;
-        UpdateForm.value = {
-          account: "",
-          username: "",
-          password: "",
-          roleIds: [],
-          phone: "",
-          adminType: "1",
-          id: ""
-        };
         onSearch();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
@@ -166,16 +141,40 @@ export function useUser() {
   }
   // 获取角色列表
   async function RoleList() {
-    const { data } = await getRoleList({ name: "", pageSize: 100, pageNum: 1 });
+    const { data } = await getAllRoleList({});
     const option = data.map(item => {
       return {
-        label: item.name,
-        Id: item.id
+        label: item.roleName,
+        Id: item.roleId
       };
     });
     optionList.value = option;
   }
   RoleList();
+  // 获取部门列表
+  async function DeptList() {
+    const { data } = await getAllDeptList({});
+    const option = data.map(item => {
+      return {
+        label: item.name,
+        Id: item.deptId
+      };
+    });
+    optionDeptList.value = option;
+  }
+  DeptList();
+  // 获取部门列表
+  async function PostList() {
+    const { data } = await getAllPostList({});
+    const option = data.map(item => {
+      return {
+        label: item.postName,
+        Id: item.postId
+      };
+    });
+    optionPostList.value = option;
+  }
+  PostList();
   function handleDelete(row) {
     ElMessageBox.confirm(
       `是否删除该用户?  用户名称为:${row.username}`,
@@ -186,7 +185,7 @@ export function useUser() {
         type: "warning"
       }
     ).then(async () => {
-      const { status, message } = await deleteUserList({ id: row.id });
+      const { status, msg } = await deleteUserList(row.userId);
       if (status == 1) {
         ElMessage({
           message: "删除成功",
@@ -194,22 +193,24 @@ export function useUser() {
         });
         onSearch();
       } else {
-        ElMessageBox.alert(message, "提示", {
+        ElMessageBox.alert(msg, "提示", {
           confirmButtonText: "关闭",
           type: "warning"
         });
       }
     });
   }
-  function AddUser(row) {
+  function AddUser() {
     UpdateForm.value = {
-      account: "",
-      username: "",
-      password: "",
-      roleIds: [],
-      phone: "",
-      adminType: "1",
-      id: ""
+      username: "", //用户名
+      password: "", //密码
+      phone: "", //电话号码
+      nickname: "", //昵称
+      name: "", //姓名
+      email: "", //邮箱地址
+      role: "", //角色id集合
+      deptId: "", //所属部门ID
+      avatar: "" //头像
     };
     dialogUpdateVisible.value = true;
     dialogType.value = 1;
@@ -218,30 +219,42 @@ export function useUser() {
     dialogType.value = 2;
     dialogUpdateVisible.value = true;
     UpdateForm.value = {
-      account: row.account,
-      username: row.username,
-      password: "",
-      roleIds: row.roles[0].id,
-      phone: row.phone,
-      adminType: "1",
-      id: row.id
+      userId: row.userId ? row.userId : "", //用户ID
+      username: row.username ? row.username : "", //用户名
+      phone: row.phone ? row.phone : "", //电话号码
+      avatar: row.avatar ? row.avatar : "", //头像
+      nickname: row.nickname ? row.nickname : "", //昵称
+      name: row.name ? row.name : "", //姓名
+      email: row.email ? row.email : "", //邮箱地址
+      deptId: row.deptId ? row.deptId : "", //所属部门ID
+      role: row.roleList
+        ? row.roleList.map(item => {
+          return item.roleId;
+        })
+        : [], //角色id集合
+      post: row.postList
+        ? row.postList.map(item => {
+          return item.postId;
+        })
+        : [] //岗位id集合
     };
   }
 
   function handleSizeChange(val: number) {
-    console.log(`${val} items per page`);
-    onSearch();
+    if (typeof val === "number") {
+      pagination.pageSize = val;
+      onSearch();
+    }
   }
 
   function handleCurrentChange(val: number) {
-    console.log(`current page: ${val}`);
-    onSearch();
+    if (typeof val === "number") {
+      pagination.currentPage = val;
+      onSearch();
+    }
   }
 
-  function handleSelectionChange(val) {
-    console.log("handleSelectionChange", val);
-    onSearch();
-  }
+  function handleSelectionChange(val) { }
 
   // 搜索函数(请求表格数据列表)
   function submit(e: { keyCode: number }) {
@@ -259,24 +272,55 @@ export function useUser() {
       });
     }
     if (type == "all") {
-      form.account = "";
-      form.username = "";
+      (form.username = ""), (form.phone = ""), (form.deptId = "");
     }
     loading.value = true;
-    const { data, other } = await getUserList({
+    const { data } = await getUserList({
       ...form,
       pageSize: pagination.pageSize,
       pageNum: pagination.currentPage
     });
-    dataList.value = data;
-    pagination.total = other;
+    dataList.value = data.records;
+    pagination.total = data.total;
     setTimeout(() => {
       loading.value = false;
     }, 500);
   }
-
+  // 锁定用户
+  const handleLock = row => {
+    ElMessageBox.confirm(
+      `是否锁定该用户?  用户名称为:${row.username}`,
+      "提示",
+      {
+        confirmButtonText: "锁定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }
+    ).then(async () => {
+      console.log("[  ] >", {
+        userId: row.userId,
+        username: row.username
+      });
+      const { status, msg } = await lockUserList({
+        userId: row.userId,
+        username: row.username
+      });
+      if (status == 1) {
+        ElMessage({
+          message: "锁定用户成功",
+          type: "success"
+        });
+        onSearch();
+      } else {
+        ElMessageBox.alert(msg, "提示", {
+          confirmButtonText: "关闭",
+          type: "warning"
+        });
+      }
+    });
+  };
   onMounted(() => {
-    // onSearch();
+    onSearch();
   });
 
   return {
@@ -291,6 +335,8 @@ export function useUser() {
     submit,
     UpdateForm,
     optionList,
+    optionDeptList,
+    optionPostList,
     dialogType,
     AddUser,
     onSearch,
@@ -298,6 +344,7 @@ export function useUser() {
     handleDelete,
     handleSizeChange,
     handleCurrentChange,
-    handleSelectionChange
+    handleSelectionChange,
+    handleLock
   };
 }

+ 53 - 16
src/views/admin/user/index.vue

@@ -39,7 +39,10 @@ const {
   handleDelete,
   handleSizeChange,
   handleCurrentChange,
-  handleSelectionChange
+  handleSelectionChange,
+  handleLock,
+  optionDeptList,
+  optionPostList
 } = useUser();
 defineExpose({
   form,
@@ -59,7 +62,10 @@ defineExpose({
   handleDelete,
   handleSizeChange,
   handleCurrentChange,
-  handleSelectionChange
+  handleSelectionChange,
+  handleLock,
+  optionDeptList,
+  optionPostList
 });
 </script>
 
@@ -121,7 +127,6 @@ defineExpose({
     //- 表格组件
     PureTableBar.mt12(title="后台用户管理", @refresh="onSearch" )
       template(#buttons)
-        //- el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser" v-if="hasAuth(['add'])") 新增用户
         el-button(type="primary" :icon="useRenderIcon(AddFill)" @click="AddUser") 新增用户
       template(v-slot="{ size, checkList }")
         pure-table(stripe 
@@ -148,7 +153,13 @@ defineExpose({
               @click="handleUpdate(row)"
               :icon="useRenderIcon(EditPen)"
             ) 编辑
-              //- v-if="hasAuth(['edit'])"
+            //- el-button.reset-margin(
+            //-   link
+            //-   type="primary"
+            //-   :size="size"
+            //-   @click="handleLock(row)"
+            //-   :icon="useRenderIcon(EditPen)"
+            //- ) 锁定
             el-button.reset-margin(
               link
               type="primary"
@@ -156,32 +167,58 @@ defineExpose({
               @click="handleDelete(row)"
               :icon="useRenderIcon(Delete)"
             ) 删除
-              //- v-if="hasAuth(['delete'])"
 
-  el-dialog(v-model='dialogUpdateVisible' width="40%" :title="dialogType == 1 ?'添加系统用户' : '修改系统用户信息'")
+  el-dialog(v-model='dialogUpdateVisible' width="40%" :close-on-click-modal="false" :title="dialogType == 1 ?'添加系统用户' : '修改系统用户信息'")
     el-form(:model='UpdateForm' 
       label-position="left"
       label-width="100px")
-      el-form-item(label='管理员账号' prop="account")
-        el-input(v-model='UpdateForm.account' autocomplete='off' class="!w-[230px]"
-          placeholder="请输入管理员账号")
-      el-form-item(label='管理员密码' prop="password")
-        el-input(v-model='UpdateForm.password' autocomplete='off' class="!w-[230px]"
-          placeholder="请输入管理员密码")
       el-form-item(label='用户名' prop="username")
         el-input(v-model='UpdateForm.username' autocomplete='off' class="!w-[230px]"
           placeholder="请输入用户名")
-      el-form-item(label='管理员电话' prop="phone")
+      el-form-item(label='用户密码' prop="password")
+        el-input(v-model='UpdateForm.password' autocomplete='off' class="!w-[230px]"
+          :placeholder="dialogType == 1 ? '请输入用户密码' : '若不修改用户密码,可不填此项'")
+      el-form-item(label='邮箱' prop="email")
+        el-input(v-model='UpdateForm.email' autocomplete='off' class="!w-[230px]"
+          placeholder="请输入邮箱")
+      el-form-item(label='昵称' prop="nickname")
+        el-input(v-model='UpdateForm.nickname' autocomplete='off' class="!w-[230px]"
+          placeholder="请输入昵称")
+      el-form-item(label='用户姓名' prop="name")
+        el-input(v-model='UpdateForm.name' autocomplete='off' class="!w-[230px]"
+          placeholder="请输入用户姓名")
+      el-form-item(label='用户电话' prop="phone")
         el-input(v-model='UpdateForm.phone' autocomplete='off' class="!w-[230px]"
-          placeholder="请输入管理员电话")
-      el-form-item(label="角色:", prop="roleIds")
+          placeholder="请输入用户电话")
+      el-form-item(label="角色:", prop="role")
         el-select(
-          v-model="UpdateForm.roleIds",
+          v-model="UpdateForm.role",
+          filterable,
+          multiple,
           placeholder="请选择用户角色",
           clearable,
           class="!w-[230px]"
         )
           el-option(:label="item.label", :value="item.Id" v-for="(item,index) in optionList")
+      el-form-item(label="岗位:", prop="post")
+        el-select(
+          v-model="UpdateForm.post",
+          filterable,
+          multiple,
+          placeholder="请选择用户岗位",
+          clearable,
+          class="!w-[230px]"
+        )
+          el-option(:label="item.label", :value="item.Id" v-for="(item,index) in optionPostList")
+      el-form-item(label="部门:", prop="deptId")
+        el-select(
+          v-model="UpdateForm.deptId",
+          filterable,
+          placeholder="请选择用户部门",
+          clearable,
+          class="!w-[230px]"
+        )
+          el-option(:label="item.label", :value="item.Id" v-for="(item,index) in optionDeptList")
     template(#footer)
       span.dialog-footer
         el-button(@click='dialogUpdateVisible = false') 关闭

+ 48 - 22
src/views/login/index.vue

@@ -1,7 +1,6 @@
 <script setup lang="ts">
 import {
   ref,
-  toRaw,
   reactive,
   watch,
   computed,
@@ -77,12 +76,12 @@ const onLogin = async (formEl: FormInstance | undefined) => {
   };
   checked.value
     ? Cookies.set("isRememberPassword", "true") &&
-    Cookies.set("RememberAccount", ShakeDownEncrypt(ruleForm))
+      Cookies.set("RememberAccount", ShakeDownEncrypt(ruleForm))
     : Cookies.set("isRememberPassword", "") &&
-    Cookies.set(
-      "RememberAccount",
-      ShakeDownEncrypt({ username: ruleForm.username })
-    );
+      Cookies.set(
+        "RememberAccount",
+        ShakeDownEncrypt({ username: ruleForm.username })
+      );
   if (!formEl) return;
   await formEl.validate((valid, fields) => {
     if (valid) {
@@ -196,31 +195,53 @@ watch(imgCode, value => {
             </h2>
           </Motion>
 
-          <el-form v-if="currentPage === 0" ref="ruleFormRef" :model="ruleForm" :rules="loginRules" size="large">
+          <el-form
+            v-if="currentPage === 0"
+            ref="ruleFormRef"
+            :model="ruleForm"
+            :rules="loginRules"
+            size="large"
+          >
             <Motion :delay="100">
-              <el-form-item :rules="[
-          {
-            required: true,
-            message: transformI18n($t('login.usernameReg')),
-            trigger: 'blur'
-          }
-        ]" prop="username">
-                <el-input clearable v-model="ruleForm.username" :placeholder="t('login.username')"
-                  :prefix-icon="useRenderIcon(User)" />
+              <el-form-item
+                :rules="[
+                  {
+                    required: true,
+                    message: transformI18n($t('login.usernameReg')),
+                    trigger: 'blur'
+                  }
+                ]"
+                prop="username"
+              >
+                <el-input
+                  clearable
+                  v-model="ruleForm.username"
+                  :placeholder="t('login.username')"
+                  :prefix-icon="useRenderIcon(User)"
+                />
               </el-form-item>
             </Motion>
 
             <Motion :delay="150">
               <el-form-item prop="password">
-                <el-input clearable show-password v-model="ruleForm.password" :placeholder="t('login.password')"
-                  :prefix-icon="useRenderIcon(Lock)" />
+                <el-input
+                  clearable
+                  show-password
+                  v-model="ruleForm.password"
+                  :placeholder="t('login.password')"
+                  :prefix-icon="useRenderIcon(Lock)"
+                />
               </el-form-item>
             </Motion>
 
             <Motion :delay="200">
               <el-form-item prop="verifyCode">
-                <el-input clearable v-model="ruleForm.verifyCode" :placeholder="t('login.verifyCode')"
-                  :prefix-icon="useRenderIcon('ri:shield-keyhole-line')">
+                <el-input
+                  clearable
+                  v-model="ruleForm.verifyCode"
+                  :placeholder="t('login.verifyCode')"
+                  :prefix-icon="useRenderIcon('ri:shield-keyhole-line')"
+                >
                   <template v-slot:append>
                     <ReImageVerify v-model:code="imgCode" />
                   </template>
@@ -242,8 +263,13 @@ watch(imgCode, value => {
                     {{ t("login.forget") }}
                   </el-button> -->
                 </div>
-                <el-button class="w-full mt-4" size="default" type="primary" :loading="loading"
-                  @click="onLogin(ruleFormRef)">
+                <el-button
+                  class="w-full mt-4"
+                  size="default"
+                  type="primary"
+                  :loading="loading"
+                  @click="onLogin(ruleFormRef)"
+                >
                   {{ t("login.login") }}
                 </el-button>
               </el-form-item>