mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	feat: 添加用户管理demo
This commit is contained in:
		
							parent
							
								
									9271997a30
								
							
						
					
					
						commit
						42b7e36e0d
					
				@ -12,15 +12,6 @@ const systemRouter = {
 | 
			
		||||
    rank: 11
 | 
			
		||||
  },
 | 
			
		||||
  children: [
 | 
			
		||||
    // {
 | 
			
		||||
    //   path: "/system/dict/index",
 | 
			
		||||
    //   name: "dict",
 | 
			
		||||
    //   meta: {
 | 
			
		||||
    //     title: "menus.hsDict",
 | 
			
		||||
    //     i18n: true,
 | 
			
		||||
    //     keepAlive: true
 | 
			
		||||
    //   }
 | 
			
		||||
    // },
 | 
			
		||||
    {
 | 
			
		||||
      path: "/system/user/index",
 | 
			
		||||
      name: "user",
 | 
			
		||||
@ -34,7 +25,7 @@ const systemRouter = {
 | 
			
		||||
      path: "/system/role/index",
 | 
			
		||||
      name: "role",
 | 
			
		||||
      meta: {
 | 
			
		||||
        icon: "peoples",
 | 
			
		||||
        icon: "role",
 | 
			
		||||
        title: "menus.hsRole",
 | 
			
		||||
        i18n: true
 | 
			
		||||
      }
 | 
			
		||||
@ -43,10 +34,20 @@ const systemRouter = {
 | 
			
		||||
      path: "/system/dept/index",
 | 
			
		||||
      name: "dept",
 | 
			
		||||
      meta: {
 | 
			
		||||
        icon: "office-building",
 | 
			
		||||
        icon: "dept",
 | 
			
		||||
        title: "menus.hsDept",
 | 
			
		||||
        i18n: true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      path: "/system/dict/index",
 | 
			
		||||
      name: "dict",
 | 
			
		||||
      meta: {
 | 
			
		||||
        icon: "dict",
 | 
			
		||||
        title: "menus.hsDict",
 | 
			
		||||
        i18n: true,
 | 
			
		||||
        keepAlive: true
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -448,8 +448,7 @@ export default [
 | 
			
		||||
                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
        },
 | 
			
		||||
        msg: ""
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -62,8 +62,7 @@ export default [
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          total: 3
 | 
			
		||||
        },
 | 
			
		||||
        msg: ""
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
@ -76,6 +75,7 @@ export default [
 | 
			
		||||
        data: [
 | 
			
		||||
          {
 | 
			
		||||
            name: "杭州总公司",
 | 
			
		||||
            type: 1, // 1 公司 2 分公司 3 部门
 | 
			
		||||
            parentId: 0,
 | 
			
		||||
            sort: 0,
 | 
			
		||||
            leaderUserId: 1,
 | 
			
		||||
@ -88,6 +88,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "郑州分公司",
 | 
			
		||||
            type: 2,
 | 
			
		||||
            parentId: 100,
 | 
			
		||||
            sort: 1,
 | 
			
		||||
            leaderUserId: 104,
 | 
			
		||||
@ -100,6 +101,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "研发部门",
 | 
			
		||||
            type: 3,
 | 
			
		||||
            parentId: 101,
 | 
			
		||||
            sort: 1,
 | 
			
		||||
            leaderUserId: 104,
 | 
			
		||||
@ -112,6 +114,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "市场部门",
 | 
			
		||||
            type: 3,
 | 
			
		||||
            parentId: 102,
 | 
			
		||||
            sort: 1,
 | 
			
		||||
            leaderUserId: null,
 | 
			
		||||
@ -124,6 +127,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "深圳分公司",
 | 
			
		||||
            type: 2,
 | 
			
		||||
            parentId: 100,
 | 
			
		||||
            sort: 2,
 | 
			
		||||
            leaderUserId: null,
 | 
			
		||||
@ -136,6 +140,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "市场部门",
 | 
			
		||||
            type: 3,
 | 
			
		||||
            parentId: 101,
 | 
			
		||||
            sort: 2,
 | 
			
		||||
            leaderUserId: null,
 | 
			
		||||
@ -148,6 +153,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "财务部门",
 | 
			
		||||
            type: 3,
 | 
			
		||||
            parentId: 102,
 | 
			
		||||
            sort: 2,
 | 
			
		||||
            leaderUserId: null,
 | 
			
		||||
@ -160,6 +166,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "测试部门",
 | 
			
		||||
            type: 3,
 | 
			
		||||
            parentId: 101,
 | 
			
		||||
            sort: 3,
 | 
			
		||||
            leaderUserId: null,
 | 
			
		||||
@ -172,6 +179,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "财务部门",
 | 
			
		||||
            type: 3,
 | 
			
		||||
            parentId: 101,
 | 
			
		||||
            sort: 4,
 | 
			
		||||
            leaderUserId: 103,
 | 
			
		||||
@ -184,6 +192,7 @@ export default [
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "运维部门",
 | 
			
		||||
            type: 3,
 | 
			
		||||
            parentId: 101,
 | 
			
		||||
            sort: 5,
 | 
			
		||||
            leaderUserId: null,
 | 
			
		||||
@ -194,8 +203,85 @@ export default [
 | 
			
		||||
            createTime: 1609837427000,
 | 
			
		||||
            remark: "备注、备注、备注、备注、备注、备注、备注"
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    url: "/user",
 | 
			
		||||
    method: "post",
 | 
			
		||||
    response: () => {
 | 
			
		||||
      return {
 | 
			
		||||
        code: 0,
 | 
			
		||||
        data: {
 | 
			
		||||
          list: [
 | 
			
		||||
            {
 | 
			
		||||
              username: "admin",
 | 
			
		||||
              nickname: "admin",
 | 
			
		||||
              remark: "管理员",
 | 
			
		||||
              deptId: 103,
 | 
			
		||||
              postIds: [1],
 | 
			
		||||
              mobile: "15888888888",
 | 
			
		||||
              sex: 0,
 | 
			
		||||
              id: 1,
 | 
			
		||||
              status: 0,
 | 
			
		||||
              createTime: 1609837427000,
 | 
			
		||||
              dept: {
 | 
			
		||||
                id: 103,
 | 
			
		||||
                name: "研发部门"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              username: "pure",
 | 
			
		||||
              nickname: "pure",
 | 
			
		||||
              remark: "不要吓我",
 | 
			
		||||
              deptId: 104,
 | 
			
		||||
              postIds: [1],
 | 
			
		||||
              mobile: "15888888888",
 | 
			
		||||
              sex: 0,
 | 
			
		||||
              id: 100,
 | 
			
		||||
              status: 1,
 | 
			
		||||
              createTime: 1609981637000,
 | 
			
		||||
              dept: {
 | 
			
		||||
                id: 104,
 | 
			
		||||
                name: "市场部门"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              username: "小姐姐",
 | 
			
		||||
              nickname: "girl",
 | 
			
		||||
              remark: null,
 | 
			
		||||
              deptId: 106,
 | 
			
		||||
              postIds: null,
 | 
			
		||||
              mobile: "15888888888",
 | 
			
		||||
              sex: 1,
 | 
			
		||||
              id: 103,
 | 
			
		||||
              status: 1,
 | 
			
		||||
              createTime: 1610553035000,
 | 
			
		||||
              dept: {
 | 
			
		||||
                id: 106,
 | 
			
		||||
                name: "财务部门"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              username: "小哥哥",
 | 
			
		||||
              nickname: "boy",
 | 
			
		||||
              remark: null,
 | 
			
		||||
              deptId: 107,
 | 
			
		||||
              postIds: [],
 | 
			
		||||
              mobile: "15888888888",
 | 
			
		||||
              sex: 0,
 | 
			
		||||
              id: 104,
 | 
			
		||||
              status: 0,
 | 
			
		||||
              createTime: 1611166433000,
 | 
			
		||||
              dept: {
 | 
			
		||||
                id: 107,
 | 
			
		||||
                name: "运维部门"
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
        msg: ""
 | 
			
		||||
          total: 4
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -71,6 +71,7 @@
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@commitlint/cli": "13.1.0",
 | 
			
		||||
    "@commitlint/config-conventional": "13.1.0",
 | 
			
		||||
    "@iconify-icons/carbon": "^1.2.4",
 | 
			
		||||
    "@iconify-icons/ep": "^1.2.4",
 | 
			
		||||
    "@iconify-icons/fa": "^1.2.2",
 | 
			
		||||
    "@iconify-icons/fa-solid": "^1.2.2",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@ -5,6 +5,7 @@ specifiers:
 | 
			
		||||
  "@commitlint/cli": 13.1.0
 | 
			
		||||
  "@commitlint/config-conventional": 13.1.0
 | 
			
		||||
  "@ctrl/tinycolor": ^3.4.0
 | 
			
		||||
  "@iconify-icons/carbon": ^1.2.4
 | 
			
		||||
  "@iconify-icons/ep": ^1.2.4
 | 
			
		||||
  "@iconify-icons/fa": ^1.2.2
 | 
			
		||||
  "@iconify-icons/fa-solid": ^1.2.2
 | 
			
		||||
@ -151,6 +152,7 @@ dependencies:
 | 
			
		||||
devDependencies:
 | 
			
		||||
  "@commitlint/cli": 13.1.0
 | 
			
		||||
  "@commitlint/config-conventional": 13.1.0
 | 
			
		||||
  "@iconify-icons/carbon": 1.2.4
 | 
			
		||||
  "@iconify-icons/ep": 1.2.4
 | 
			
		||||
  "@iconify-icons/fa": 1.2.2
 | 
			
		||||
  "@iconify-icons/fa-solid": 1.2.2
 | 
			
		||||
@ -963,6 +965,15 @@ packages:
 | 
			
		||||
      }
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@iconify-icons/carbon/1.2.4:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-RhLB8EwYz32oSSQZjafhWbyAqOoPIcj59VQmsrY/+8MR083c8XwOjepIwKVzZNMjWSL966ykqZxNrXwEjk7jrg==
 | 
			
		||||
      }
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@iconify/types": 1.1.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@iconify-icons/ep/1.2.4:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,11 @@ interface ResponseType extends Promise<any> {
 | 
			
		||||
  msg?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取用户管理列表
 | 
			
		||||
export const getUserList = (data?: object): ResponseType => {
 | 
			
		||||
  return http.request("post", "/user", { data });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 获取角色管理列表
 | 
			
		||||
export const getRoleList = (data?: object): ResponseType => {
 | 
			
		||||
  return http.request("post", "/role", { data });
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,7 @@ const cardLogoClass = computed(() => [
 | 
			
		||||
            :disabled="!product.isSetup"
 | 
			
		||||
            max-height="2"
 | 
			
		||||
          >
 | 
			
		||||
            <IconifyIconOffline icon="more-2-fill" class="icon-more" />
 | 
			
		||||
            <IconifyIconOffline icon="more-vertical" class="icon-more" />
 | 
			
		||||
            <template #dropdown>
 | 
			
		||||
              <el-dropdown-menu :disabled="!product.isSetup">
 | 
			
		||||
                <el-dropdown-item @click="handleClickManage(product)"
 | 
			
		||||
 | 
			
		||||
@ -80,6 +80,11 @@ import AddFill from "@iconify-icons/ri/add-circle-line";
 | 
			
		||||
import ListCheck from "@iconify-icons/ri/list-check";
 | 
			
		||||
import More2Fill from "@iconify-icons/ri/more-2-fill";
 | 
			
		||||
import Database from "@iconify-icons/ri/database-2-line";
 | 
			
		||||
import Dict from "@iconify-icons/ri/git-repository-line";
 | 
			
		||||
import Card from "@iconify-icons/ri/bank-card-line";
 | 
			
		||||
import Reset from "@iconify-icons/ri/restart-line";
 | 
			
		||||
import Dept from "@iconify-icons/ri/git-branch-line";
 | 
			
		||||
import Password from "@iconify-icons/ri/lock-password-line";
 | 
			
		||||
addIcon("arrow-right-s-line", ArrowRightSLine);
 | 
			
		||||
addIcon("arrow-left-s-line", ArrowLeftSLine);
 | 
			
		||||
addIcon("logout-circle-r-line", LogoutCircleRLine);
 | 
			
		||||
@ -94,8 +99,13 @@ addIcon("arrow-down-line", ArrowDownLine);
 | 
			
		||||
addIcon("bookmark-2-line", Bookmark2Line);
 | 
			
		||||
addIcon("add", AddFill);
 | 
			
		||||
addIcon("list-check", ListCheck);
 | 
			
		||||
addIcon("more-2-fill", More2Fill);
 | 
			
		||||
addIcon("more-vertical", More2Fill);
 | 
			
		||||
addIcon("database", Database);
 | 
			
		||||
addIcon("dict", Dict);
 | 
			
		||||
addIcon("card", Card);
 | 
			
		||||
addIcon("reset", Reset);
 | 
			
		||||
addIcon("dept", Dept);
 | 
			
		||||
addIcon("password", Password);
 | 
			
		||||
 | 
			
		||||
// Font Awesome 4
 | 
			
		||||
import FaUser from "@iconify-icons/fa/user";
 | 
			
		||||
@ -114,9 +124,9 @@ addIcon("export", Export);
 | 
			
		||||
addIcon("density", ArrowsShrinkV);
 | 
			
		||||
 | 
			
		||||
// fluent
 | 
			
		||||
import Peoples from "@iconify-icons/fluent/people-swap-28-filled";
 | 
			
		||||
import Role from "@iconify-icons/fluent/people-swap-28-filled";
 | 
			
		||||
import FlUser from "@iconify-icons/fluent/person-12-filled";
 | 
			
		||||
addIcon("peoples", Peoples);
 | 
			
		||||
addIcon("role", Role);
 | 
			
		||||
addIcon("flUser", FlUser);
 | 
			
		||||
 | 
			
		||||
// Material Design Icons
 | 
			
		||||
@ -125,6 +135,10 @@ import UnExpand from "@iconify-icons/mdi/arrow-expand-right";
 | 
			
		||||
addIcon("expand", Expand);
 | 
			
		||||
addIcon("unExpand", UnExpand);
 | 
			
		||||
 | 
			
		||||
// carbon
 | 
			
		||||
import LocationCompany from "@iconify-icons/carbon/location-company";
 | 
			
		||||
addIcon("location-company", LocationCompany);
 | 
			
		||||
 | 
			
		||||
// Iconify Icon在Vue里离线使用(用于内网环境)https://docs.iconify.design/icon-components/vue/offline.html
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: "IconifyIcon",
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,7 @@ export default defineComponent({
 | 
			
		||||
  name: "epTableProBar",
 | 
			
		||||
  props,
 | 
			
		||||
  emits: ["refresh"],
 | 
			
		||||
  setup(props, { emit, slots }) {
 | 
			
		||||
  setup(props, { emit, slots, attrs }) {
 | 
			
		||||
    const buttonRef = ref();
 | 
			
		||||
    const checkList = ref([]);
 | 
			
		||||
    const currentWidth = ref(0);
 | 
			
		||||
@ -125,6 +125,7 @@ export default defineComponent({
 | 
			
		||||
      <>
 | 
			
		||||
        <div
 | 
			
		||||
          v-resize
 | 
			
		||||
          {...attrs}
 | 
			
		||||
          class="w-99/100 mt-6 p-2 bg-white"
 | 
			
		||||
          v-loading={props.loading}
 | 
			
		||||
          element-loading-svg={loadingSvg}
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ const ableRouter = {
 | 
			
		||||
      name: "listCard",
 | 
			
		||||
      component: () => import("/@/views/list/card/index.vue"),
 | 
			
		||||
      meta: {
 | 
			
		||||
        icon: "card",
 | 
			
		||||
        title: $t("menus.listCard"),
 | 
			
		||||
        i18n: true,
 | 
			
		||||
        showParent: true
 | 
			
		||||
 | 
			
		||||
@ -64,10 +64,10 @@ onMounted(() => {
 | 
			
		||||
      class="bg-white w-99/100 pl-8 pt-4"
 | 
			
		||||
    >
 | 
			
		||||
      <el-form-item label="部门名称:" prop="user">
 | 
			
		||||
        <el-input v-model="form.user" placeholder="请输入" clearable />
 | 
			
		||||
        <el-input v-model="form.user" placeholder="请输入部门名称" clearable />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="状态:" prop="status">
 | 
			
		||||
        <el-select v-model="form.status" placeholder="请选择" clearable>
 | 
			
		||||
        <el-select v-model="form.status" placeholder="请选择状态" clearable>
 | 
			
		||||
          <el-option label="开启" value="1" />
 | 
			
		||||
          <el-option label="关闭" value="0" />
 | 
			
		||||
        </el-select>
 | 
			
		||||
 | 
			
		||||
@ -117,13 +117,13 @@ onMounted(() => {
 | 
			
		||||
      class="bg-white w-99/100 pl-8 pt-4"
 | 
			
		||||
    >
 | 
			
		||||
      <el-form-item label="角色名称:" prop="name">
 | 
			
		||||
        <el-input v-model="form.name" placeholder="请输入" clearable />
 | 
			
		||||
        <el-input v-model="form.name" placeholder="请输入角色名称" clearable />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="角色标识:" prop="code">
 | 
			
		||||
        <el-input v-model="form.code" placeholder="请输入" clearable />
 | 
			
		||||
        <el-input v-model="form.code" placeholder="请输入角色标识" clearable />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="状态:" prop="status">
 | 
			
		||||
        <el-select v-model="form.status" placeholder="请选择" clearable>
 | 
			
		||||
        <el-select v-model="form.status" placeholder="请选择状态" clearable>
 | 
			
		||||
          <el-option label="已开启" value="1" />
 | 
			
		||||
          <el-option label="已关闭" value="0" />
 | 
			
		||||
        </el-select>
 | 
			
		||||
 | 
			
		||||
@ -5,218 +5,330 @@ export default {
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { reactive } from "vue";
 | 
			
		||||
import { $t } from "/@/plugins/i18n";
 | 
			
		||||
import { VxeGridProps } from "vxe-table";
 | 
			
		||||
import dayjs from "dayjs";
 | 
			
		||||
import tree from "./tree.vue";
 | 
			
		||||
import { getUserList } from "/@/api/system";
 | 
			
		||||
import { FormInstance } from "element-plus";
 | 
			
		||||
import { ElMessageBox } from "element-plus";
 | 
			
		||||
import { reactive, ref, onMounted } from "vue";
 | 
			
		||||
import { EpTableProBar } from "/@/components/ReTable";
 | 
			
		||||
import { Switch, message } from "@pureadmin/components";
 | 
			
		||||
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
 | 
			
		||||
 | 
			
		||||
const gridOptions = reactive({
 | 
			
		||||
  border: true,
 | 
			
		||||
  resizable: true,
 | 
			
		||||
  keepSource: true,
 | 
			
		||||
  height: 578,
 | 
			
		||||
  printConfig: {},
 | 
			
		||||
  importConfig: {},
 | 
			
		||||
  exportConfig: {},
 | 
			
		||||
  pagerConfig: {
 | 
			
		||||
    perfect: true,
 | 
			
		||||
    pageSize: 15
 | 
			
		||||
  },
 | 
			
		||||
  editConfig: {
 | 
			
		||||
    trigger: "click",
 | 
			
		||||
    mode: "row",
 | 
			
		||||
    showStatus: true
 | 
			
		||||
  },
 | 
			
		||||
  toolbarConfig: {
 | 
			
		||||
    buttons: [
 | 
			
		||||
const form = reactive({
 | 
			
		||||
  username: "",
 | 
			
		||||
  mobile: "",
 | 
			
		||||
  status: ""
 | 
			
		||||
});
 | 
			
		||||
let dataList = ref([]);
 | 
			
		||||
let pageSize = ref(10);
 | 
			
		||||
let totalPage = ref(0);
 | 
			
		||||
let loading = ref(true);
 | 
			
		||||
let switchLoadMap = ref({});
 | 
			
		||||
 | 
			
		||||
const formRef = ref<FormInstance>();
 | 
			
		||||
 | 
			
		||||
function handleUpdate(row) {
 | 
			
		||||
  console.log(row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleDelete(row) {
 | 
			
		||||
  console.log(row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleCurrentChange(val: number) {
 | 
			
		||||
  console.log(`current page: ${val}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleSizeChange(val: number) {
 | 
			
		||||
  console.log(`${val} items per page`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleSelectionChange(val) {
 | 
			
		||||
  console.log("handleSelectionChange", val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onChange(checked, { $index, row }) {
 | 
			
		||||
  ElMessageBox.confirm(
 | 
			
		||||
    `确认要<strong>${
 | 
			
		||||
      row.status === 0 ? "停用" : "启用"
 | 
			
		||||
    }</strong><strong style='color:var(--el-color-primary)'>${
 | 
			
		||||
      row.username
 | 
			
		||||
    }</strong>用户吗?`,
 | 
			
		||||
    "系统提示",
 | 
			
		||||
    {
 | 
			
		||||
        code: "insert_actived",
 | 
			
		||||
        name: $t("buttons.hsadd"),
 | 
			
		||||
        status: "perfect",
 | 
			
		||||
        icon: "fa fa-plus"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        code: "mark_cancel",
 | 
			
		||||
        name: $t("buttons.hsmark"),
 | 
			
		||||
        status: "perfect",
 | 
			
		||||
        icon: "fa fa-trash-o"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        code: "save",
 | 
			
		||||
        name: $t("buttons.hssave"),
 | 
			
		||||
        status: "perfect",
 | 
			
		||||
        icon: "fa fa-save"
 | 
			
		||||
      confirmButtonText: "确定",
 | 
			
		||||
      cancelButtonText: "取消",
 | 
			
		||||
      type: "warning",
 | 
			
		||||
      dangerouslyUseHTMLString: true,
 | 
			
		||||
      draggable: true
 | 
			
		||||
    }
 | 
			
		||||
    ],
 | 
			
		||||
    perfect: true,
 | 
			
		||||
    refresh: {
 | 
			
		||||
      icon: "fa fa-refresh",
 | 
			
		||||
      iconLoading: "fa fa-spinner fa-spin"
 | 
			
		||||
    },
 | 
			
		||||
    import: {
 | 
			
		||||
      icon: "fa fa-upload"
 | 
			
		||||
    },
 | 
			
		||||
    export: {
 | 
			
		||||
      icon: "fa fa-download"
 | 
			
		||||
    },
 | 
			
		||||
    print: {
 | 
			
		||||
      icon: "fa fa-print"
 | 
			
		||||
    },
 | 
			
		||||
    zoom: {
 | 
			
		||||
      iconIn: "fa fa-arrows-alt",
 | 
			
		||||
      iconOut: "fa fa-expand"
 | 
			
		||||
    },
 | 
			
		||||
    custom: {
 | 
			
		||||
      icon: "fa fa-cog"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  proxyConfig: {
 | 
			
		||||
    props: {
 | 
			
		||||
      result: "result",
 | 
			
		||||
      total: "page.total"
 | 
			
		||||
    },
 | 
			
		||||
    ajax: {
 | 
			
		||||
      // 接收 Promise
 | 
			
		||||
      query: ({ page }) => {
 | 
			
		||||
        return new Promise(resolve => {
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            const list = [
 | 
			
		||||
              {
 | 
			
		||||
                id: 10001,
 | 
			
		||||
                name: "Test1",
 | 
			
		||||
                nickname: "T1",
 | 
			
		||||
                role: "Develop",
 | 
			
		||||
                sex: "Man",
 | 
			
		||||
                age: 28,
 | 
			
		||||
                address: "Shenzhen"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10002,
 | 
			
		||||
                name: "Test2",
 | 
			
		||||
                nickname: "T2",
 | 
			
		||||
                role: "Test",
 | 
			
		||||
                sex: "Women",
 | 
			
		||||
                age: 22,
 | 
			
		||||
                address: "Guangzhou"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10003,
 | 
			
		||||
                name: "Test3",
 | 
			
		||||
                nickname: "T3",
 | 
			
		||||
                role: "PM",
 | 
			
		||||
                sex: "Man",
 | 
			
		||||
                age: 32,
 | 
			
		||||
                address: "Shanghai"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10004,
 | 
			
		||||
                name: "Test4",
 | 
			
		||||
                nickname: "T4",
 | 
			
		||||
                role: "Designer",
 | 
			
		||||
                sex: "Women ",
 | 
			
		||||
                age: 23,
 | 
			
		||||
                address: "Shenzhen"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10005,
 | 
			
		||||
                name: "Test5",
 | 
			
		||||
                nickname: "T5",
 | 
			
		||||
                role: "Develop",
 | 
			
		||||
                sex: "Women ",
 | 
			
		||||
                age: 30,
 | 
			
		||||
                address: "Shanghai"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10006,
 | 
			
		||||
                name: "Test6",
 | 
			
		||||
                nickname: "T6",
 | 
			
		||||
                role: "Designer",
 | 
			
		||||
                sex: "Women ",
 | 
			
		||||
                age: 21,
 | 
			
		||||
                address: "Shenzhen"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10007,
 | 
			
		||||
                name: "Test7",
 | 
			
		||||
                nickname: "T7",
 | 
			
		||||
                role: "Test",
 | 
			
		||||
                sex: "Man ",
 | 
			
		||||
                age: 29,
 | 
			
		||||
                address: "vxe-table 从入门到放弃"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10008,
 | 
			
		||||
                name: "Test8",
 | 
			
		||||
                nickname: "T8",
 | 
			
		||||
                role: "Develop",
 | 
			
		||||
                sex: "Man ",
 | 
			
		||||
                age: 35,
 | 
			
		||||
                address: "Shenzhen"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 10009,
 | 
			
		||||
                name: "Test9",
 | 
			
		||||
                nickname: "T9",
 | 
			
		||||
                role: "Develop",
 | 
			
		||||
                sex: "Man ",
 | 
			
		||||
                age: 35,
 | 
			
		||||
                address: "Shenzhen"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 100010,
 | 
			
		||||
                name: "Test10",
 | 
			
		||||
                nickname: "T10",
 | 
			
		||||
                role: "Develop",
 | 
			
		||||
                sex: "Man ",
 | 
			
		||||
                age: 35,
 | 
			
		||||
                address: "Guangzhou"
 | 
			
		||||
              }
 | 
			
		||||
            ];
 | 
			
		||||
            resolve({
 | 
			
		||||
              page: {
 | 
			
		||||
                total: list.length
 | 
			
		||||
              },
 | 
			
		||||
              result: list.slice(
 | 
			
		||||
                (page.currentPage - 1) * page.pageSize,
 | 
			
		||||
                page.currentPage * page.pageSize
 | 
			
		||||
  )
 | 
			
		||||
            });
 | 
			
		||||
          }, 100);
 | 
			
		||||
        });
 | 
			
		||||
      },
 | 
			
		||||
      // body 对象: { removeRecords }
 | 
			
		||||
      delete: () => {
 | 
			
		||||
        return new Promise(resolve => {
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            resolve({});
 | 
			
		||||
          }, 100);
 | 
			
		||||
        });
 | 
			
		||||
      },
 | 
			
		||||
      // body 对象: { insertRecords, updateRecords, removeRecords, pendingRecords }
 | 
			
		||||
      save: () => {
 | 
			
		||||
        return new Promise(resolve => {
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            resolve({});
 | 
			
		||||
          }, 100);
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  columns: [
 | 
			
		||||
    { type: "checkbox", width: 50 },
 | 
			
		||||
    { type: "seq", width: 60 },
 | 
			
		||||
    { field: "name", title: "Name", editRender: { name: "input" } },
 | 
			
		||||
    { field: "nickname", title: "Nickname", editRender: { name: "input" } },
 | 
			
		||||
    { field: "role", title: "Role", editRender: { name: "input" } },
 | 
			
		||||
    .then(() => {
 | 
			
		||||
      switchLoadMap.value[$index] = Object.assign(
 | 
			
		||||
        {},
 | 
			
		||||
        switchLoadMap.value[$index],
 | 
			
		||||
        {
 | 
			
		||||
      field: "address",
 | 
			
		||||
      title: "Address",
 | 
			
		||||
      showOverflow: true,
 | 
			
		||||
      editRender: { name: "input" }
 | 
			
		||||
          loading: true
 | 
			
		||||
        }
 | 
			
		||||
  ]
 | 
			
		||||
} as VxeGridProps);
 | 
			
		||||
      );
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        switchLoadMap.value[$index] = Object.assign(
 | 
			
		||||
          {},
 | 
			
		||||
          switchLoadMap.value[$index],
 | 
			
		||||
          {
 | 
			
		||||
            loading: false
 | 
			
		||||
          }
 | 
			
		||||
        );
 | 
			
		||||
        message.success("已成功修改用户状态");
 | 
			
		||||
      }, 300);
 | 
			
		||||
    })
 | 
			
		||||
    .catch(() => {
 | 
			
		||||
      row.status === 0 ? (row.status = 1) : (row.status = 0);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function onSearch() {
 | 
			
		||||
  loading.value = true;
 | 
			
		||||
  let { data } = await getUserList();
 | 
			
		||||
  dataList.value = data.list;
 | 
			
		||||
  totalPage.value = data.total;
 | 
			
		||||
  setTimeout(() => {
 | 
			
		||||
    loading.value = false;
 | 
			
		||||
  }, 500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const resetForm = (formEl: FormInstance | undefined) => {
 | 
			
		||||
  if (!formEl) return;
 | 
			
		||||
  formEl.resetFields();
 | 
			
		||||
  onSearch();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  onSearch();
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <vxe-grid v-bind="gridOptions" />
 | 
			
		||||
  <div class="main flex">
 | 
			
		||||
    <tree />
 | 
			
		||||
    <div class="flex-1 ml-4">
 | 
			
		||||
      <el-form
 | 
			
		||||
        ref="formRef"
 | 
			
		||||
        :inline="true"
 | 
			
		||||
        :model="form"
 | 
			
		||||
        class="bg-white w-99/100 pl-8 pt-4"
 | 
			
		||||
      >
 | 
			
		||||
        <el-form-item label="用户名称:" prop="username">
 | 
			
		||||
          <el-input
 | 
			
		||||
            v-model="form.username"
 | 
			
		||||
            placeholder="请输入用户名称"
 | 
			
		||||
            clearable
 | 
			
		||||
          />
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="手机号码:" prop="mobile">
 | 
			
		||||
          <el-input
 | 
			
		||||
            v-model="form.mobile"
 | 
			
		||||
            placeholder="请输入手机号码"
 | 
			
		||||
            clearable
 | 
			
		||||
          />
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="状态:" prop="status">
 | 
			
		||||
          <el-select v-model="form.status" placeholder="请选择" clearable>
 | 
			
		||||
            <el-option label="已开启" value="1" />
 | 
			
		||||
            <el-option label="已关闭" value="0" />
 | 
			
		||||
          </el-select>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item>
 | 
			
		||||
          <el-button
 | 
			
		||||
            type="primary"
 | 
			
		||||
            :icon="useRenderIcon('search')"
 | 
			
		||||
            :loading="loading"
 | 
			
		||||
            @click="onSearch"
 | 
			
		||||
          >
 | 
			
		||||
            搜索
 | 
			
		||||
          </el-button>
 | 
			
		||||
          <el-button
 | 
			
		||||
            :icon="useRenderIcon('refresh')"
 | 
			
		||||
            @click="resetForm(formRef)"
 | 
			
		||||
          >
 | 
			
		||||
            重置
 | 
			
		||||
          </el-button>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
      </el-form>
 | 
			
		||||
 | 
			
		||||
      <EpTableProBar
 | 
			
		||||
        title="用户管理"
 | 
			
		||||
        :loading="loading"
 | 
			
		||||
        :dataList="dataList"
 | 
			
		||||
        @refresh="onSearch"
 | 
			
		||||
      >
 | 
			
		||||
        <template #buttons>
 | 
			
		||||
          <el-button type="primary" :icon="useRenderIcon('add')">
 | 
			
		||||
            新增用户
 | 
			
		||||
          </el-button>
 | 
			
		||||
        </template>
 | 
			
		||||
        <template v-slot="{ size, checkList }">
 | 
			
		||||
          <el-table
 | 
			
		||||
            border
 | 
			
		||||
            table-layout="auto"
 | 
			
		||||
            :size="size"
 | 
			
		||||
            :data="dataList"
 | 
			
		||||
            :header-cell-style="{ background: '#fafafa', color: '#606266' }"
 | 
			
		||||
            @selection-change="handleSelectionChange"
 | 
			
		||||
          >
 | 
			
		||||
            <el-table-column
 | 
			
		||||
              v-if="checkList.includes('勾选列')"
 | 
			
		||||
              type="selection"
 | 
			
		||||
              align="center"
 | 
			
		||||
              width="55"
 | 
			
		||||
            />
 | 
			
		||||
            <el-table-column
 | 
			
		||||
              v-if="checkList.includes('序号列')"
 | 
			
		||||
              type="index"
 | 
			
		||||
              label="序号"
 | 
			
		||||
              align="center"
 | 
			
		||||
              width="70"
 | 
			
		||||
            />
 | 
			
		||||
            <el-table-column label="用户编号" align="center" prop="id" />
 | 
			
		||||
            <el-table-column label="用户名称" align="center" prop="username" />
 | 
			
		||||
            <el-table-column label="用户昵称" align="center" prop="nickname" />
 | 
			
		||||
            <el-table-column label="性别" align="center" prop="sex">
 | 
			
		||||
              <template #default="scope">
 | 
			
		||||
                <el-tag
 | 
			
		||||
                  :size="size"
 | 
			
		||||
                  :type="scope.row.sex === 1 ? 'danger' : ''"
 | 
			
		||||
                  effect="plain"
 | 
			
		||||
                >
 | 
			
		||||
                  {{ scope.row.sex === 1 ? "女" : "男" }}
 | 
			
		||||
                </el-tag>
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-table-column>
 | 
			
		||||
            <el-table-column
 | 
			
		||||
              label="部门"
 | 
			
		||||
              align="center"
 | 
			
		||||
              prop="dept"
 | 
			
		||||
              :formatter="
 | 
			
		||||
                ({ dept }) => {
 | 
			
		||||
                  return dept.name;
 | 
			
		||||
                }
 | 
			
		||||
              "
 | 
			
		||||
            />
 | 
			
		||||
            <el-table-column label="手机号码" align="center" prop="mobile" />
 | 
			
		||||
            <el-table-column
 | 
			
		||||
              label="状态"
 | 
			
		||||
              align="center"
 | 
			
		||||
              width="130"
 | 
			
		||||
              prop="status"
 | 
			
		||||
            >
 | 
			
		||||
              <template #default="scope">
 | 
			
		||||
                <Switch
 | 
			
		||||
                  :size="size === 'small' ? 'small' : 'default'"
 | 
			
		||||
                  :loading="switchLoadMap[scope.$index]?.loading"
 | 
			
		||||
                  v-model:checked="scope.row.status"
 | 
			
		||||
                  :checkedValue="1"
 | 
			
		||||
                  :unCheckedValue="0"
 | 
			
		||||
                  checked-children="已开启"
 | 
			
		||||
                  un-checked-children="已关闭"
 | 
			
		||||
                  @change="checked => onChange(checked, scope)"
 | 
			
		||||
                />
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-table-column>
 | 
			
		||||
            <el-table-column
 | 
			
		||||
              label="创建时间"
 | 
			
		||||
              align="center"
 | 
			
		||||
              width="180"
 | 
			
		||||
              prop="createTime"
 | 
			
		||||
              :formatter="
 | 
			
		||||
                ({ createTime }) => {
 | 
			
		||||
                  return dayjs(createTime).format('YYYY-MM-DD HH:mm:ss');
 | 
			
		||||
                }
 | 
			
		||||
              "
 | 
			
		||||
            />
 | 
			
		||||
            <el-table-column
 | 
			
		||||
              fixed="right"
 | 
			
		||||
              label="操作"
 | 
			
		||||
              width="180"
 | 
			
		||||
              align="center"
 | 
			
		||||
            >
 | 
			
		||||
              <template #default="scope">
 | 
			
		||||
                <el-button
 | 
			
		||||
                  class="reset-margin"
 | 
			
		||||
                  type="text"
 | 
			
		||||
                  :size="size"
 | 
			
		||||
                  @click="handleUpdate(scope.row)"
 | 
			
		||||
                  :icon="useRenderIcon('edits')"
 | 
			
		||||
                >
 | 
			
		||||
                  修改
 | 
			
		||||
                </el-button>
 | 
			
		||||
                <el-popconfirm title="是否确认删除?">
 | 
			
		||||
                  <template #reference>
 | 
			
		||||
                    <el-button
 | 
			
		||||
                      class="reset-margin"
 | 
			
		||||
                      type="text"
 | 
			
		||||
                      :size="size"
 | 
			
		||||
                      :icon="useRenderIcon('delete')"
 | 
			
		||||
                      @click="handleDelete(scope.row)"
 | 
			
		||||
                    >
 | 
			
		||||
                      删除
 | 
			
		||||
                    </el-button>
 | 
			
		||||
                  </template>
 | 
			
		||||
                </el-popconfirm>
 | 
			
		||||
                <el-dropdown>
 | 
			
		||||
                  <el-button
 | 
			
		||||
                    class="ml-3"
 | 
			
		||||
                    type="text"
 | 
			
		||||
                    :size="size"
 | 
			
		||||
                    @click="handleUpdate(scope.row)"
 | 
			
		||||
                    :icon="useRenderIcon('more')"
 | 
			
		||||
                  />
 | 
			
		||||
                  <template #dropdown>
 | 
			
		||||
                    <el-dropdown-menu>
 | 
			
		||||
                      <el-dropdown-item>
 | 
			
		||||
                        <el-button
 | 
			
		||||
                          class="reset-margin !h-20px !text-gray-500"
 | 
			
		||||
                          type="text"
 | 
			
		||||
                          :size="size"
 | 
			
		||||
                          :icon="useRenderIcon('password')"
 | 
			
		||||
                        >
 | 
			
		||||
                          重置密码
 | 
			
		||||
                        </el-button>
 | 
			
		||||
                      </el-dropdown-item>
 | 
			
		||||
                      <el-dropdown-item>
 | 
			
		||||
                        <el-button
 | 
			
		||||
                          class="reset-margin !h-20px !text-gray-500"
 | 
			
		||||
                          type="text"
 | 
			
		||||
                          :size="size"
 | 
			
		||||
                          :icon="useRenderIcon('role')"
 | 
			
		||||
                        >
 | 
			
		||||
                          分配角色
 | 
			
		||||
                        </el-button>
 | 
			
		||||
                      </el-dropdown-item>
 | 
			
		||||
                    </el-dropdown-menu>
 | 
			
		||||
                  </template>
 | 
			
		||||
                </el-dropdown>
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-table-column>
 | 
			
		||||
          </el-table>
 | 
			
		||||
          <el-pagination
 | 
			
		||||
            class="flex justify-end mt-4"
 | 
			
		||||
            :small="size === 'small' ? true : false"
 | 
			
		||||
            v-model:page-size="pageSize"
 | 
			
		||||
            :page-sizes="[10, 20, 30, 50]"
 | 
			
		||||
            :background="true"
 | 
			
		||||
            layout="total, sizes, prev, pager, next, jumper"
 | 
			
		||||
            :total="totalPage"
 | 
			
		||||
            @size-change="handleSizeChange"
 | 
			
		||||
            @current-change="handleCurrentChange"
 | 
			
		||||
          />
 | 
			
		||||
        </template>
 | 
			
		||||
      </EpTableProBar>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
:deep(.el-dropdown-menu__item i) {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										187
									
								
								src/views/system/user/tree.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								src/views/system/user/tree.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,187 @@
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import type { ElTree } from "element-plus";
 | 
			
		||||
import { handleTree } from "/@/utils/tree";
 | 
			
		||||
import { getDeptList } from "/@/api/system";
 | 
			
		||||
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
 | 
			
		||||
import { ref, watch, onMounted, getCurrentInstance } from "vue";
 | 
			
		||||
 | 
			
		||||
interface Tree {
 | 
			
		||||
  id: number;
 | 
			
		||||
  name: string;
 | 
			
		||||
  highlight?: boolean;
 | 
			
		||||
  children?: Tree[];
 | 
			
		||||
}
 | 
			
		||||
const defaultProps = {
 | 
			
		||||
  children: "children",
 | 
			
		||||
  label: "name"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const treeData = ref([]);
 | 
			
		||||
const searchValue = ref("");
 | 
			
		||||
const { proxy } = getCurrentInstance();
 | 
			
		||||
const treeRef = ref<InstanceType<typeof ElTree>>();
 | 
			
		||||
 | 
			
		||||
let highlightMap = ref({});
 | 
			
		||||
 | 
			
		||||
const filterNode = (value: string, data: Tree) => {
 | 
			
		||||
  if (!value) return true;
 | 
			
		||||
  return data.name.includes(value);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function nodeClick(value) {
 | 
			
		||||
  const nodeId = value.$treeNodeId;
 | 
			
		||||
  highlightMap.value[nodeId] = highlightMap.value[nodeId]?.highlight
 | 
			
		||||
    ? Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
 | 
			
		||||
        highlight: false
 | 
			
		||||
      })
 | 
			
		||||
    : Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
 | 
			
		||||
        highlight: true
 | 
			
		||||
      });
 | 
			
		||||
  Object.values(highlightMap.value).forEach((v: Tree) => {
 | 
			
		||||
    if (v.id !== nodeId) {
 | 
			
		||||
      v.highlight = false;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function toggleRowExpansionAll(status) {
 | 
			
		||||
  // @ts-expect-error
 | 
			
		||||
  let nodes = proxy.$refs["treeRef"].store._getAllNodes();
 | 
			
		||||
  for (var i = 0; i < nodes.length; i++) {
 | 
			
		||||
    nodes[i].expanded = status;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 重置状态(选中状态、搜索框值、树初始化)
 | 
			
		||||
function onReset() {
 | 
			
		||||
  highlightMap.value = {};
 | 
			
		||||
  searchValue.value = "";
 | 
			
		||||
  toggleRowExpansionAll(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
watch(searchValue, val => {
 | 
			
		||||
  treeRef.value!.filter(val);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onMounted(async () => {
 | 
			
		||||
  let { data } = await getDeptList();
 | 
			
		||||
  treeData.value = handleTree(data);
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="max-w-260px h-full min-h-780px bg-white">
 | 
			
		||||
    <div class="flex items-center h-34px">
 | 
			
		||||
      <p class="flex-1 ml-2 font-bold text-base truncate" title="部门列表">
 | 
			
		||||
        部门列表
 | 
			
		||||
      </p>
 | 
			
		||||
      <el-input
 | 
			
		||||
        style="flex: 2"
 | 
			
		||||
        size="small"
 | 
			
		||||
        v-model="searchValue"
 | 
			
		||||
        placeholder="请输入部门名称"
 | 
			
		||||
        clearable
 | 
			
		||||
      >
 | 
			
		||||
        <template #suffix>
 | 
			
		||||
          <el-icon class="el-input__icon">
 | 
			
		||||
            <IconifyIconOffline
 | 
			
		||||
              v-show="searchValue.length === 0"
 | 
			
		||||
              icon="search"
 | 
			
		||||
            />
 | 
			
		||||
          </el-icon>
 | 
			
		||||
        </template>
 | 
			
		||||
      </el-input>
 | 
			
		||||
      <el-dropdown>
 | 
			
		||||
        <IconifyIconOffline
 | 
			
		||||
          class="w-28px cursor-pointer"
 | 
			
		||||
          width="18px"
 | 
			
		||||
          icon="more-vertical"
 | 
			
		||||
        />
 | 
			
		||||
        <template #dropdown>
 | 
			
		||||
          <el-dropdown-menu>
 | 
			
		||||
            <el-dropdown-item>
 | 
			
		||||
              <el-button
 | 
			
		||||
                class="reset-margin !h-20px !text-gray-500"
 | 
			
		||||
                type="text"
 | 
			
		||||
                :icon="useRenderIcon('expand')"
 | 
			
		||||
                @click="toggleRowExpansionAll(true)"
 | 
			
		||||
              >
 | 
			
		||||
                展开全部
 | 
			
		||||
              </el-button>
 | 
			
		||||
            </el-dropdown-item>
 | 
			
		||||
            <el-dropdown-item>
 | 
			
		||||
              <el-button
 | 
			
		||||
                class="reset-margin !h-20px !text-gray-500"
 | 
			
		||||
                type="text"
 | 
			
		||||
                :icon="useRenderIcon('unExpand')"
 | 
			
		||||
                @click="toggleRowExpansionAll(false)"
 | 
			
		||||
              >
 | 
			
		||||
                折叠全部
 | 
			
		||||
              </el-button>
 | 
			
		||||
            </el-dropdown-item>
 | 
			
		||||
            <el-dropdown-item>
 | 
			
		||||
              <el-button
 | 
			
		||||
                class="reset-margin !h-20px !text-gray-500"
 | 
			
		||||
                type="text"
 | 
			
		||||
                :icon="useRenderIcon('reset')"
 | 
			
		||||
                @click="onReset"
 | 
			
		||||
              >
 | 
			
		||||
                重置状态
 | 
			
		||||
              </el-button>
 | 
			
		||||
            </el-dropdown-item>
 | 
			
		||||
          </el-dropdown-menu>
 | 
			
		||||
        </template>
 | 
			
		||||
      </el-dropdown>
 | 
			
		||||
    </div>
 | 
			
		||||
    <el-divider />
 | 
			
		||||
    <el-tree
 | 
			
		||||
      ref="treeRef"
 | 
			
		||||
      :data="treeData"
 | 
			
		||||
      node-key="id"
 | 
			
		||||
      size="small"
 | 
			
		||||
      :props="defaultProps"
 | 
			
		||||
      default-expand-all
 | 
			
		||||
      :expand-on-click-node="false"
 | 
			
		||||
      :filter-node-method="filterNode"
 | 
			
		||||
      @node-click="nodeClick"
 | 
			
		||||
    >
 | 
			
		||||
      <template #default="{ node, data }">
 | 
			
		||||
        <span
 | 
			
		||||
          :class="[
 | 
			
		||||
            'pl-1',
 | 
			
		||||
            'pr-1',
 | 
			
		||||
            'rounded',
 | 
			
		||||
            'flex',
 | 
			
		||||
            'items-center',
 | 
			
		||||
            'select-none',
 | 
			
		||||
            searchValue.trim().length > 0 &&
 | 
			
		||||
              node.label.includes(searchValue) &&
 | 
			
		||||
              'text-red-500'
 | 
			
		||||
          ]"
 | 
			
		||||
          :style="{
 | 
			
		||||
            background: highlightMap[node.id]?.highlight
 | 
			
		||||
              ? 'var(--el-color-primary-light-7)'
 | 
			
		||||
              : 'transparent'
 | 
			
		||||
          }"
 | 
			
		||||
        >
 | 
			
		||||
          <IconifyIconOffline
 | 
			
		||||
            :icon="
 | 
			
		||||
              data.type === 1
 | 
			
		||||
                ? 'office-building'
 | 
			
		||||
                : data.type === 2
 | 
			
		||||
                ? 'location-company'
 | 
			
		||||
                : 'dept'
 | 
			
		||||
            "
 | 
			
		||||
          />
 | 
			
		||||
          {{ node.label }}
 | 
			
		||||
        </span>
 | 
			
		||||
      </template>
 | 
			
		||||
    </el-tree>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
:deep(.el-divider) {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user