Просмотр исходного кода

Merge branch 'system-assemble' into 'master'

角色管理+用户管理

See merge request tian-group/skyeye-admin-fe!11
孙宏耀 2 лет назад
Родитель
Сommit
a06554d7b0
32 измененных файлов с 1668 добавлено и 193 удалено
  1. BIN
      public/upload-user-templete/templete.xlsx
  2. 56 10
      src/api/system/role.ts
  3. 108 0
      src/api/system/user-operate.ts
  4. 37 0
      src/api/system/user-query.ts
  5. 1 1
      src/api/system/user.ts
  6. 8 8
      src/router/modules/dashboard.ts
  7. 0 4
      src/views/auth/dept/columns.ts
  8. 7 0
      src/views/auth/dept/dept.vue
  9. 1 1
      src/views/login/LoginForm2.vue
  10. 1 1
      src/views/dashboard/monitor/CompanyDrawer.vue
  11. 1 1
      src/views/dashboard/monitor/monitor.vue
  12. 1 1
      src/views/dashboard/monitor/WorkshopDrawer.vue
  13. 1 1
      src/views/dashboard/monitor/WorkspaceDrawer.vue
  14. 0 0
      src/views/system-config/scene-manage/actionColomns.vue
  15. 0 0
      src/views/system-config/scene-manage/constant.ts
  16. 0 0
      src/views/system-config/scene-manage/use-method.ts
  17. 0 0
      src/views/system-config/scene-manage/use-scene.ts
  18. 0 0
      src/views/system-config/scene-manage/use-sence-templete.ts
  19. 5 5
      src/views/system/role/CreateDrawer.vue
  20. 423 0
      src/views/system/role/CreateUserDrawer.vue
  21. 31 5
      src/views/system/role/role.vue
  22. 10 0
      src/views/system/role/types/index.ts
  23. 87 89
      src/views/system/user/CreateDrawer.vue
  24. 58 1
      src/views/system/user/columns.ts
  25. 32 0
      src/views/system/user/component/ActionColomns.vue
  26. 223 0
      src/views/system/user/component/AddUser.vue
  27. 95 0
      src/views/system/user/component/UserQuery.vue
  28. 35 0
      src/views/system/user/constant.ts
  29. 26 0
      src/views/system/user/hooks/use-user-para.ts
  30. 151 0
      src/views/system/user/hooks/use-user.ts
  31. 161 0
      src/views/system/user/user-copy.vue
  32. 109 65
      src/views/system/user/user.vue

BIN
public/upload-user-templete/templete.xlsx


+ 56 - 10
src/api/system/role.ts

@@ -1,9 +1,33 @@
 import { http } from '@/utils/http/axios';
 import { http } from '@/utils/http/axios';
 
 
 /**
 /**
- * @description: 添加角色
+ * @description: 添加管理角色
  */
  */
-export function addRole(params) {
+export function addAdminRole(params) {
+  return http.request({
+    url: '/role/addAdmin',
+    method: 'POST',
+    params,
+  });
+}
+
+export interface RoleType<T> {
+  permissionList?: T[];
+  remark?: string;
+  roleName?: string;
+  roleCode?: string;
+  roleId?: number;
+}
+
+export interface PermissionType {
+  workshopCode: string;
+  permissionId: string;
+}
+
+/**
+ * @description: 添加用户角色
+ */
+export function addRole(params: RoleType<PermissionType>) {
   return http.request({
   return http.request({
     url: '/role/add',
     url: '/role/add',
     method: 'POST',
     method: 'POST',
@@ -12,9 +36,31 @@ export function addRole(params) {
 }
 }
 
 
 /**
 /**
- * @description: 查询角色信息
+ * @description: 修改用户角色
+ */
+export function updateRole(params: RoleType<PermissionType>) {
+  return http.request({
+    url: '/role/update',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 查询管理角色信息
  */
  */
-export function roleInfo(params) {
+export function roleAdminInfo(params) {
+  return http.request({
+    url: '/role/infoAdmin',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 查询用户角色信息
+ */
+export function roleUserInfo(params) {
   return http.request({
   return http.request({
     url: '/role/info',
     url: '/role/info',
     method: 'GET',
     method: 'GET',
@@ -23,22 +69,22 @@ export function roleInfo(params) {
 }
 }
 
 
 /**
 /**
- * @description: 编辑角色
+ * @description: 编辑管理角色
  */
  */
-export function editRole(params) {
+export function editAdminRole(params) {
   return http.request({
   return http.request({
-    url: '/role/update',
+    url: '/role/updateAdmin',
     method: 'POST',
     method: 'POST',
     params,
     params,
   });
   });
 }
 }
 
 
 /**
 /**
- * @description: 删除角色
+ * @description: 删除管理角色
  */
  */
-export function delRole(params) {
+export function delAdminRole(params) {
   return http.request({
   return http.request({
-    url: '/role/delete',
+    url: '/role/deleteAdmin',
     method: 'POST',
     method: 'POST',
     params,
     params,
   });
   });

+ 108 - 0
src/api/system/user-operate.ts

@@ -0,0 +1,108 @@
+import { http } from '@/utils/http/axios';
+
+export interface UserType {
+  userId?: number;
+  password?: string;
+  deptId?: number | null;
+  username?: string;
+  staffNo?: string;
+  mobile?: string;
+  isEnable?: boolean;
+  nickname?: string;
+  roleIds?: number[];
+  passwordRe?: string;
+}
+
+//添加用户
+export function addSingleUser(params: UserType) {
+  return http.request({
+    url: '/user/add',
+    method: 'POST',
+    params,
+  });
+}
+
+//添加批量用户
+export function addMultipleUser(params: File) {
+  return http.request({
+    url: '/user/import',
+    method: 'POST',
+    params,
+  });
+}
+
+export interface UserTypeDel {
+  deleteStatus?: string;
+  deptId?: number;
+  email?: string;
+  isEnable?: boolean;
+  mobile?: string;
+  nickname?: string;
+  opertor?: string;
+  password?: string;
+  postId?: string;
+  remark?: string;
+  roleIds?: string[];
+  sex?: string;
+  staffNo?: string;
+  userId?: number;
+  username?: string;
+  updateTime?: string;
+  createTime?: string;
+}
+
+//删除用户
+export function delUser(params: UserTypeDel) {
+  return http.request({
+    url: '/user/delete',
+    method: 'POST',
+    params,
+  });
+}
+
+//修改用户
+export function updateUser(params: UserType) {
+  return http.request({
+    url: '/user/update',
+    method: 'POST',
+    params,
+  });
+}
+
+//获取单个用户信息
+// export function getUser(params: string): Promise<UserType> {
+//   return http.request({
+//     url: '/user/info',
+//     method: 'get',
+//     params,
+//   });
+// }
+
+export interface UserList {
+  pageNumber: number;
+  totalPage: number;
+  pageSize: number;
+  page: number;
+  list: UserTypeDel[];
+  totalCount: number;
+  pageNum: number;
+}
+
+export interface QueryUser {
+  staffNo?: string; //工号
+  nickname?: string; //姓名
+  mobile?: string; //手机号
+  roleName?: string; //角色
+  deptName?: string; //组织
+  page?: number; //当前页数
+  pageRow?: number; //每页个数
+}
+
+//获取单个用户信息
+export function getUserList(params: QueryUser | null): Promise<UserList> {
+  return http.request({
+    url: '/user/list',
+    method: 'get',
+    params,
+  });
+}

+ 37 - 0
src/api/system/user-query.ts

@@ -0,0 +1,37 @@
+import { http } from '@/utils/http/axios';
+
+export interface Role {
+  roleId: number;
+  roleName: string;
+}
+
+export interface RoleList {
+  list?: Role[];
+}
+
+//获取所有角色
+export function getAllRoles(): Promise<RoleList> {
+  return http.request({
+    url: '/role/getAllRoles',
+    method: 'get',
+  });
+}
+
+export interface Department {
+  deptId: number;
+  createDate: string;
+  modifyDate: string;
+  deptName: string;
+  treePath: string;
+  grade: number;
+  parent: number;
+  orderNum: number | null;
+  isEnable: boolean;
+}
+//获取所有组织
+export function getAllDepartments(): Promise<Department[]> {
+  return http.request({
+    url: '/dept/getAllDept',
+    method: 'get',
+  });
+}

+ 1 - 1
src/api/system/user.ts

@@ -15,7 +15,7 @@ export interface BasicPageParams {
 /**
 /**
  * @description: 获取用户信息
  * @description: 获取用户信息
  */
  */
-export function getUserInfo(params?) {
+export function getUserInfo(params) {
   return http.request({
   return http.request({
     url: '/login/info',
     url: '/login/info',
     method: 'POST',
     method: 'POST',

+ 8 - 8
src/router/modules/dashboard.ts

@@ -42,14 +42,14 @@ const routes: Array<RouteRecordRaw> = [
         },
         },
         component: () => import('@/views/dashboard/console/console.vue'),
         component: () => import('@/views/dashboard/console/console.vue'),
       },
       },
-      {
-        path: 'monitor',
-        name: `${routeName}_monitor`,
-        meta: {
-          title: '监控页',
-        },
-        component: () => import('@/views/dashboard/monitor/monitor.vue'),
-      },
+      // {
+      //   path: 'monitor',
+      //   name: `${routeName}_monitor`,
+      //   meta: {
+      //     title: '监控页',
+      //   },
+      //   component: () => import('@/views/dashboard/monitor/monitor.vue'),
+      // },
       {
       {
         path: 'workplace',
         path: 'workplace',
         name: `${routeName}_workplace`,
         name: `${routeName}_workplace`,

+ 0 - 4
src/views/auth/dept/columns.ts

@@ -21,8 +21,4 @@ export const columns: BasicColumn[] = [
     label: '上级组织名称',
     label: '上级组织名称',
     prop: 'parentName',
     prop: 'parentName',
   },
   },
-  {
-    label: '组织代码',
-    prop: 'code',
-  },
 ];
 ];

+ 7 - 0
src/views/auth/dept/dept.vue

@@ -26,6 +26,13 @@
         :columns="columns"
         :columns="columns"
         :request="loadDataTable"
         :request="loadDataTable"
         row-key="deptId"
         row-key="deptId"
+        :tableSetting="{
+          size: false,
+          redo: false,
+          fullscreen: false,
+          striped: false,
+          setting: false,
+        }"
         ref="basicTableRef"
         ref="basicTableRef"
         :actionColumn="actionColumn"
         :actionColumn="actionColumn"
         @update:checked-row-keys="onCheckedRow"
         @update:checked-row-keys="onCheckedRow"

+ 1 - 1
src/views/login/LoginForm2.vue

@@ -138,7 +138,7 @@
   import { ResultEnum } from '@/enums/httpEnum';
   import { ResultEnum } from '@/enums/httpEnum';
   import { initData, captchaBase64, tentantList } from '@/api/common/index';
   import { initData, captchaBase64, tentantList } from '@/api/common/index';
   import { CodeOutlined } from '@vicons/antd';
   import { CodeOutlined } from '@vicons/antd';
-  import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5';//LogoGithub, LogoFacebook 
+  import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5'; //LogoGithub, LogoFacebook
   import { PageEnum } from '@/enums/pageEnum';
   import { PageEnum } from '@/enums/pageEnum';
 
 
   interface FormState {
   interface FormState {

+ 1 - 1
src/views/dashboard/monitor/CompanyDrawer.vue

@@ -82,7 +82,7 @@
         </el-form-item>
         </el-form-item>
       </el-form>
       </el-form>
       <div style="position: absolute; left: 108px; bottom: 67px">
       <div style="position: absolute; left: 108px; bottom: 67px">
-        <el-button v-if="!props.comEdit" type="warning" @click="resetDrawCom">重置</el-button>
+        <el-button v-if="!props.comEdit" @click="resetDrawCom">重置</el-button>
         <el-button type="primary" v-if="!props.comEdit" @click="newCompanyAdd"> 提交 </el-button>
         <el-button type="primary" v-if="!props.comEdit" @click="newCompanyAdd"> 提交 </el-button>
         <el-button type="primary" v-if="props.comEdit" @click="editedSub"> 提交 </el-button>
         <el-button type="primary" v-if="props.comEdit" @click="editedSub"> 提交 </el-button>
       </div>
       </div>

+ 1 - 1
src/views/dashboard/monitor/monitor.vue

@@ -34,7 +34,7 @@
         <template #empty>
         <template #empty>
           <div class="empty-content flex flex-col items-center">
           <div class="empty-content flex flex-col items-center">
             <img src="@/assets/icons/no-content.png" class="empty-img" />
             <img src="@/assets/icons/no-content.png" class="empty-img" />
-            <span class="empty-text">目前无内容,请先添加相机</span>
+            <span class="empty-text">目前无内容,请先添加场景</span>
           </div>
           </div>
         </template>
         </template>
       </BasicTable>
       </BasicTable>

+ 1 - 1
src/views/dashboard/monitor/WorkshopDrawer.vue

@@ -69,7 +69,7 @@
         </el-form-item>
         </el-form-item>
       </el-form>
       </el-form>
       <div style="position: absolute; left: 108px; bottom: 67px">
       <div style="position: absolute; left: 108px; bottom: 67px">
-        <el-button v-if="!props.detail.companyId" type="warning" @click="resetDraw">重置</el-button>
+        <el-button v-if="!props.detail.companyId" @click="resetDraw">重置</el-button>
         <el-button v-if="!props.detail.companyId" type="primary" @click="addNewType">
         <el-button v-if="!props.detail.companyId" type="primary" @click="addNewType">
           提交
           提交
         </el-button>
         </el-button>

+ 1 - 1
src/views/dashboard/monitor/WorkspaceDrawer.vue

@@ -41,7 +41,7 @@
         </el-form-item>
         </el-form-item>
       </el-form>
       </el-form>
       <div style="position: absolute; left: 108px; bottom: 67px">
       <div style="position: absolute; left: 108px; bottom: 67px">
-        <el-button v-if="!props.detail.principal" type="warning" @click="resetDraw">重置</el-button>
+        <el-button v-if="!props.detail.principal" @click="resetDraw">重置</el-button>
         <el-button v-if="!props.detail.principal" type="primary" @click="addNewType">
         <el-button v-if="!props.detail.principal" type="primary" @click="addNewType">
           提交
           提交
         </el-button>
         </el-button>

src/views/dashboard/monitor/actionColomns.vue → src/views/system-config/scene-manage/actionColomns.vue


src/views/dashboard/monitor/constant.ts → src/views/system-config/scene-manage/constant.ts


src/views/dashboard/monitor/use-method.ts → src/views/system-config/scene-manage/use-method.ts


src/views/dashboard/monitor/use-scene.ts → src/views/system-config/scene-manage/use-scene.ts


src/views/dashboard/monitor/use-sence-templete.ts → src/views/system-config/scene-manage/use-sence-templete.ts


+ 5 - 5
src/views/system/role/CreateDrawer.vue

@@ -28,7 +28,7 @@
         <el-card shadow="hover">
         <el-card shadow="hover">
           <el-space>
           <el-space>
             <el-checkbox v-model:checked="isSpread" @change="packHandle">展开/收起</el-checkbox>
             <el-checkbox v-model:checked="isSpread" @change="packHandle">展开/收起</el-checkbox>
-            <el-checkbox v-model:checked="isAll" @change="handleCheckAll">全选/全不选</el-checkbox>
+            <el-checkbox v-model="isAll" @change="handleCheckAll">全选/全不选</el-checkbox>
           </el-space>
           </el-space>
           <el-divider />
           <el-divider />
           <el-tree
           <el-tree
@@ -59,7 +59,7 @@
   import { ElMessage } from 'element-plus';
   import { ElMessage } from 'element-plus';
   import type { formParamsType } from './types';
   import type { formParamsType } from './types';
 
 
-  import { addRole, editRole, roleInfo } from '@/api/system/role';
+  import { addAdminRole, editAdminRole, roleAdminInfo } from '@/api/system/role';
   import { getTreeValues } from '@/utils/helper/treeHelper';
   import { getTreeValues } from '@/utils/helper/treeHelper';
 
 
   const rules = {
   const rules = {
@@ -176,14 +176,14 @@
         return message.error('请填写完整信息');
         return message.error('请填写完整信息');
       }
       }
       if (formParams.value.roleId) {
       if (formParams.value.roleId) {
-        editRole(formParams.value).then((_) => {
+        editAdminRole(formParams.value).then((_) => {
           message.success('编辑成功');
           message.success('编辑成功');
           emit('change');
           emit('change');
           handleReset();
           handleReset();
           closeDrawer();
           closeDrawer();
         });
         });
       } else {
       } else {
-        addRole(formParams.value).then((_) => {
+        addAdminRole(formParams.value).then((_) => {
           message.success('添加成功');
           message.success('添加成功');
           emit('change');
           emit('change');
           handleReset();
           handleReset();
@@ -200,7 +200,7 @@
   }
   }
 
 
   function getInfo() {
   function getInfo() {
-    roleInfo({ roleId: formParams.value.roleId }).then((res) => {
+    roleAdminInfo({ roleId: formParams.value.roleId }).then((res) => {
       const info = {
       const info = {
         roleId: res.id,
         roleId: res.id,
         roleName: res.roleName,
         roleName: res.roleName,

+ 423 - 0
src/views/system/role/CreateUserDrawer.vue

@@ -0,0 +1,423 @@
+<template>
+  <el-drawer
+    v-model="isDrawer"
+    :width="width"
+    placement="right"
+    :title="title"
+    @close="handleReset"
+  >
+    <el-form
+      :model="formParams"
+      :rules="rules"
+      ref="formRef"
+      label-placement="left"
+      :label-width="80"
+    >
+      <el-form-item label="角色编码" prop="roleCode">
+        <el-input
+          placeholder="请输入角色编码"
+          v-model="formParams.roleCode"
+          :disabled="formParams.roleId ? true : false"
+        />
+      </el-form-item>
+
+      <el-form-item label="角色名称" prop="roleName">
+        <el-input placeholder="请输入角色名称" v-model="formParams.roleName" />
+      </el-form-item>
+      <el-form-item label="角色权限" prop="permissionIds">
+        <div class="mark-left"></div>
+        <el-card shadow="hover" class="permission-card">
+          <div class="permission-name">场景权限</div>
+          <el-space>
+            <el-checkbox v-model:checked="isSpread" @change="packHandle">展开/收起</el-checkbox>
+            <el-checkbox v-model="isAll" @change="handleCheckAll">全选/全不选</el-checkbox>
+          </el-space>
+          <el-divider />
+          <div style="height: 25vh">
+            <el-scrollbar>
+              <el-tree
+                ref="treeRef"
+                show-checkbox
+                node-key="code"
+                :data="treeData"
+                :props="treeProps"
+                @check="checkedTree"
+                @node-click="clickNode"
+              />
+            </el-scrollbar>
+          </div>
+        </el-card>
+        <div style="position: relative; margin-top: 10px; width: 100%">
+          <div class="mark-left"></div>
+          <el-card shadow="hover" class="permission-card">
+            <div class="permission-name">功能权限</div>
+            <el-divider />
+            <div style="height: 10vh">
+              <el-scrollbar>
+                <el-tree
+                  ref="modeTreeRef"
+                  show-checkbox
+                  node-key="key"
+                  :data="modeTreeData"
+                  @check="checkedModeTree"
+                />
+              </el-scrollbar>
+            </div>
+          </el-card>
+        </div>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input type="textarea" placeholder="请输入备注" v-model="formParams.remark" />
+      </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <el-space>
+        <el-button @click="handleReset">重置</el-button>
+        <el-button type="primary" :loading="subLoading" @click="formSubmit">提交</el-button>
+      </el-space>
+    </template>
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+  import { ref, onMounted, nextTick, computed } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import type { userFormParamsType } from './types';
+
+  import { addRole, roleAdminInfo, roleUserInfo, updateRole } from '@/api/system/role';
+  import useScene from '@/views/system-config/scene-manage/use-scene';
+
+  const sceneInfos = useScene();
+  const { tableData, getSceneDetail } = sceneInfos;
+
+  const rules = {
+    roleCode: {
+      required: true,
+      message: '角色编码不能为空',
+      trigger: 'blur',
+    },
+    roleName: {
+      required: true,
+      message: '角色名称不能为空',
+      trigger: 'blur',
+    },
+  };
+
+  const treeProps = { label: 'name' };
+
+  const treeData = computed(() => {
+    const newList: any[] = [];
+    if (tableData.value && tableData.value.length) {
+      for (let i = 0; i < tableData.value.length; i++) {
+        const data = tableData.value[i];
+        if (data.children && data.children.length) {
+          const treeItem = {
+            id: data.id,
+            code: data.id,
+            name: data.name,
+            children: data
+              .labelList!.map((item) => {
+                return {
+                  id: item.id,
+                  code: item.code,
+                  name: item.name,
+                  children: data
+                    .children!.filter((children) => children.sceneLabelId === item.id)
+                    .map((children) => {
+                      return {
+                        id: children.id,
+                        code: children.code,
+                        name: children.name,
+                        isShop: true,
+                      };
+                    }),
+                };
+              })
+              .filter((label) => label.children.length),
+          };
+          newList.push(treeItem);
+        }
+      }
+    }
+    return newList;
+  });
+
+  const modeList = [
+    {
+      key: 10,
+      id: 1,
+      label: 10,
+    },
+    {
+      key: 11,
+      id: 2,
+      label: 11,
+    },
+    {
+      key: 12,
+      id: 3,
+      label: 12,
+    },
+  ];
+
+  const emit = defineEmits(['change']);
+
+  const props = defineProps({
+    title: {
+      type: String,
+      default: '添加角色',
+    },
+    width: {
+      type: Number,
+      default: 450,
+    },
+    permissionList: {
+      type: Array,
+    },
+  });
+
+  const defaultValueRef = () => ({
+    roleId: null,
+    roleName: '',
+    roleCode: '',
+    remark: '',
+    permissions: [],
+    permissionKeys: [],
+  });
+
+  const defaultTreeValueRef = () => ({
+    roleId: null,
+    roleName: '',
+    roleCode: '',
+    remark: '',
+    permissionList: [],
+    permissionKeys: [],
+  });
+
+  const message = ElMessage;
+  const formRef: any = ref(null);
+  const isDrawer = ref(false);
+  const subLoading = ref(false);
+  const isSpread = ref(false);
+  const isAll = ref(false);
+  const treeRef = ref();
+  const expandedKeys = ref();
+  const selectedNodeKey = ref<string>('');
+  const modeTreeData = computed(() => (selectedNodeKey.value ? modeList : []));
+
+  const formParams = ref<userFormParamsType>(defaultTreeValueRef());
+
+  function clickNode(tree, nodeInfo, _, __) {
+    console.log('tree', tree);
+    console.log('nodeInfo', nodeInfo.isShop);
+
+    if (nodeInfo.isShop) {
+      selectedNodeKey.value = tree.code;
+    } else {
+      selectedNodeKey.value = '';
+    }
+  }
+
+  function treeNodeExpand(status) {
+    for (var i = 0; i < treeRef.value.store._getAllNodes().length; i++) {
+      treeRef.value.store._getAllNodes()[i].expanded = status;
+    }
+  }
+
+  function packHandle(value) {
+    if (value) {
+      treeNodeExpand(true);
+      expandedKeys.value = props?.permissionList?.map((item: any) => item.key as string) as [];
+    } else {
+      expandedKeys.value = [];
+      treeNodeExpand(false);
+    }
+  }
+
+  function handleCheckAll(value) {
+    if (!value) {
+      formParams.value.permissions = [];
+      treeRef.value!.setCheckedKeys([]);
+    } else {
+      const allTreeNodes = treeRef.value.store._getAllNodes().map((item) => item.data.code);
+      console.log('allTreeNodes', allTreeNodes.length);
+
+      treeRef.value!.setCheckedKeys(allTreeNodes);
+    }
+  }
+
+  // function getAllIds(list: { key: number; children: [] }[] = [], ids: number[] = []) {
+  //   for (let item of list) {
+  //     !ids.includes(item.key) && ids.push(item.key);
+  //     if (item.children && item.children.length) getAllIds(item.children, ids);
+  //   }
+  //   return ids;
+  // }
+
+  function checkedTree(tree, checkedInfo) {
+    console.log(tree);
+    console.log(checkedInfo);
+
+    const nodes = checkedInfo.checkedNodes;
+    console.log('nodes', nodes);
+    // const selectNodes =
+
+    const halfKeys = checkedInfo.halfCheckedKeys;
+    formParams.value.permissionList = checkedInfo.halfCheckedKeys;
+    formParams.value.permissionList = nodes
+      .filter((item) => item.isShop)
+      .map((node) => {
+        return {
+          workshopCode: node.code,
+          permissionId: '0',
+        };
+      });
+    formParams.value.permissionKeys = halfKeys;
+    const allTreeNodes = treeRef.value.store._getAllNodes().map((item) => item.data.code);
+    if (nodes.length < allTreeNodes.length) {
+      isAll.value = false;
+    } else {
+      isAll.value = true;
+    }
+  }
+
+  function checkedModeTree() {}
+
+  function openDrawer(roleId?, roleType?) {
+    isAll.value = false;
+    if (roleId) {
+      formParams.value.roleId = roleId;
+      getInfo(roleType);
+      return;
+    }
+    isDrawer.value = true;
+  }
+
+  function closeDrawer() {
+    isDrawer.value = false;
+  }
+
+  function formSubmit() {
+    formRef.value.validate((valid) => {
+      if (!valid) {
+        return message.error('请填写完整信息');
+      }
+      if (formParams.value.roleId) {
+        console.log('bianji');
+
+        const updateData = {
+          permissionList: formParams.value.permissionList,
+          remark: formParams.value.remark,
+          roleName: formParams.value.roleName,
+          roleCode: formParams.value.roleCode,
+          roleType: 3,
+          roleId: formParams.value.roleId,
+        };
+        updateRole(updateData).then((_) => {
+          message.success('编辑成功');
+          emit('change');
+          handleReset();
+          closeDrawer();
+        });
+      } else {
+        const addData = {
+          permissionList: formParams.value.permissionList,
+          remark: formParams.value.remark,
+          roleName: formParams.value.roleName,
+          roleCode: formParams.value.roleCode,
+          roleType: 3,
+        };
+        addRole(addData).then((_) => {
+          message.success('添加成功');
+          emit('change');
+          handleReset();
+          closeDrawer();
+        });
+      }
+    });
+  }
+
+  function handleReset() {
+    formRef.value.resetFields();
+    formParams.value = Object.assign(formParams.value, defaultValueRef());
+    treeRef.value!.setCheckedKeys([]);
+    // isAll.value = false;
+  }
+  const selectNodes = ref<string[]>([]);
+  function getInfo(roleType) {
+    if (roleType === 3) {
+      roleUserInfo({ roleId: formParams.value.roleId }).then((res) => {
+        const info = {
+          roleId: res.id,
+          roleName: res.roleName,
+          roleCode: res.roleCode,
+          remark: res.remark,
+          permissionList: res.permissionIds || [],
+          permissionKeys: res.permissionKeys || [],
+        };
+        formParams.value = info;
+        isDrawer.value = true;
+        nextTick(() => {
+          selectNodes.value = res.permissionMap.map((item) => item.workshopCode);
+          // 将匹配到的节点的键值数组传递给 setCheckedKeys 方法
+          treeRef.value.setCheckedKeys(selectNodes.value);
+        });
+      });
+    } else {
+      roleAdminInfo({ roleId: formParams.value.roleId }).then((res) => {
+        const info = {
+          roleId: res.id,
+          roleName: res.roleName,
+          roleCode: res.roleCode,
+          remark: res.remark,
+          permissionList: res.permissionIds || [],
+          permissionKeys: res.permissionKeys || [],
+        };
+        formParams.value = info;
+        isDrawer.value = true;
+        nextTick(() => {
+          treeRef.value?.setCheckedKeys(res.permissionIds);
+        });
+      });
+    }
+  }
+
+  onMounted(() => {
+    getSceneDetail();
+  });
+
+  defineExpose({
+    openDrawer,
+    closeDrawer,
+  });
+</script>
+
+<style scoped>
+  .mark-left {
+    position: absolute;
+    width: 4px;
+    height: 28px;
+    top: 0;
+    background-color: #1890ff;
+  }
+
+  .permission-name {
+    height: 28px;
+    font-weight: 500;
+    display: flex;
+    align-items: center;
+  }
+
+  :deep(.el-divider--horizontal) {
+    margin: 12px 0;
+  }
+
+  .permission-card {
+    width: 100%;
+  }
+
+  :deep(.permission-card .el-card__body) {
+    padding-top: 0;
+  }
+</style>

+ 31 - 5
src/views/system/role/role.vue

@@ -24,18 +24,33 @@
         :columns="columns"
         :columns="columns"
         :request="loadDataTable"
         :request="loadDataTable"
         :row-key="(row) => row.id"
         :row-key="(row) => row.id"
+        :tableSetting="{
+          size: false,
+          redo: false,
+          fullscreen: false,
+          striped: false,
+          setting: false,
+        }"
         ref="tableRef"
         ref="tableRef"
         :actionColumn="actionColumn"
         :actionColumn="actionColumn"
         @update:checked-row-keys="onCheckedRow"
         @update:checked-row-keys="onCheckedRow"
       >
       >
         <template #tableTitle>
         <template #tableTitle>
+          <el-button type="primary" @click="openCreateUserDrawer">
+            <template #icon>
+              <el-icon>
+                <FileAddOutlined />
+              </el-icon>
+            </template>
+            添加用户角色
+          </el-button>
           <el-button type="primary" @click="openCreateDrawer">
           <el-button type="primary" @click="openCreateDrawer">
             <template #icon>
             <template #icon>
               <el-icon>
               <el-icon>
                 <FileAddOutlined />
                 <FileAddOutlined />
               </el-icon>
               </el-icon>
             </template>
             </template>
-            添加角色
+            添加管理员角色
           </el-button>
           </el-button>
         </template>
         </template>
 
 
@@ -51,6 +66,8 @@
       :permissionList="treeData"
       :permissionList="treeData"
       @change="reloadTable"
       @change="reloadTable"
     />
     />
+
+    <CreateUserDrawer ref="createUserDrawerRef" :title="drawerTitle" @change="reloadTable" />
   </page-wrapper>
   </page-wrapper>
 </template>
 </template>
 
 
@@ -58,15 +75,17 @@
   import { reactive, ref, unref, h, onMounted } from 'vue';
   import { reactive, ref, unref, h, onMounted } from 'vue';
   import { ElMessage } from 'element-plus';
   import { ElMessage } from 'element-plus';
   import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
   import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
-  import { roleList, permissionList, delRole } from '@/api/system/role';
+  import { roleList, permissionList, delAdminRole } from '@/api/system/role';
   import { columns } from './columns';
   import { columns } from './columns';
   import { FileAddOutlined, SearchOutlined } from '@vicons/antd';
   import { FileAddOutlined, SearchOutlined } from '@vicons/antd';
   import CreateDrawer from './CreateDrawer.vue';
   import CreateDrawer from './CreateDrawer.vue';
+  import CreateUserDrawer from './CreateUserDrawer.vue';
   import { useUserStore } from '@/store/modules/user';
   import { useUserStore } from '@/store/modules/user';
 
 
   const message = ElMessage;
   const message = ElMessage;
   const tableRef = ref();
   const tableRef = ref();
   const createDrawerRef = ref();
   const createDrawerRef = ref();
+  const createUserDrawerRef = ref();
   const drawerTitle = ref('添加角色');
   const drawerTitle = ref('添加角色');
   const treeData = ref([]);
   const treeData = ref([]);
   const userStore = useUserStore();
   const userStore = useUserStore();
@@ -117,6 +136,12 @@
     openDrawer();
     openDrawer();
   }
   }
 
 
+  function openCreateUserDrawer() {
+    drawerTitle.value = '添加角色';
+    const { openDrawer } = createUserDrawerRef.value;
+    openDrawer();
+  }
+
   function onCheckedRow(rowKeys: any[]) {
   function onCheckedRow(rowKeys: any[]) {
     console.log(rowKeys);
     console.log(rowKeys);
   }
   }
@@ -127,9 +152,10 @@
 
 
   function handleEdit(record: Recordable) {
   function handleEdit(record: Recordable) {
     console.log('点击了编辑', record);
     console.log('点击了编辑', record);
+    console.log('record.roleType', record.role_type);
     drawerTitle.value = '编辑角色';
     drawerTitle.value = '编辑角色';
-    const { openDrawer } = createDrawerRef.value;
-    openDrawer(record.roleId);
+    const { openDrawer } = createUserDrawerRef.value;
+    openDrawer(record.roleId, record.role_type);
   }
   }
 
 
   function handleDelete(record: Recordable) {
   function handleDelete(record: Recordable) {
@@ -137,7 +163,7 @@
       message.error('不能删除自己的角色');
       message.error('不能删除自己的角色');
       return;
       return;
     }
     }
-    delRole({ roleId: record.roleId }).then(() => {
+    delAdminRole({ roleId: record.roleId }).then(() => {
       message.success('删除成功');
       message.success('删除成功');
       reloadTable();
       reloadTable();
     });
     });

+ 10 - 0
src/views/system/role/types/index.ts

@@ -6,3 +6,13 @@ export interface formParamsType {
   permissions: number[];
   permissions: number[];
   permissionKeys: number[];
   permissionKeys: number[];
 }
 }
+
+export interface userFormParamsType {
+  roleId?: number | null;
+  roleName: string;
+  roleCode: string;
+  remark: string;
+  permissions?: number[];
+  permissionList: { workshopCode: string; permissionId: any }[];
+  permissionKeys?: number[];
+}

+ 87 - 89
src/views/system/user/CreateDrawer.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-  <el-drawer v-model="isDrawer" :size="width" :title="title" @close="handleReset">
+  <el-drawer v-model="isDrawer" :size="width" :title="props.title" @close="handleReset">
     <el-form
     <el-form
       :model="formParams"
       :model="formParams"
       :rules="rules"
       :rules="rules"
@@ -8,22 +8,19 @@
       :label-width="80"
       :label-width="80"
     >
     >
       <el-form-item label="登录账号" prop="username">
       <el-form-item label="登录账号" prop="username">
-        <el-input
-          placeholder="请输入登录账号"
-          v-model="formParams.username"
-          :disabled="formParams.userId ? true : false"
-        />
+        <el-input placeholder="请输入登录账号" v-model="formParams.username" />
       </el-form-item>
       </el-form-item>
       <el-form-item label="所属部门" prop="deptId">
       <el-form-item label="所属部门" prop="deptId">
-        <el-tree-select
-          :data="deptList"
-          clearable
-          check-strictly
-          v-model="formParams.deptId"
-          placeholder="请选择部门"
-        />
+        <el-select v-model="formParams.deptId" placeholder="请选择组织" class="protocal-select">
+          <el-option
+            v-for="item in departmentList"
+            :key="item.deptId"
+            :label="item.deptName"
+            :value="item.deptId"
+          />
+        </el-select>
       </el-form-item>
       </el-form-item>
-      <el-form-item label="密码" :prop="!formParams.userId ? 'password' : ''">
+      <el-form-item label="密码" prop="password">
         <el-input
         <el-input
           type="password"
           type="password"
           show-password-on="mousedown"
           show-password-on="mousedown"
@@ -31,7 +28,7 @@
           v-model="formParams.password"
           v-model="formParams.password"
         />
         />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="确认密码" :prop="!formParams.userId ? 'passwordRe' : ''">
+      <el-form-item label="确认密码" :prop="!formParams.username ? 'passwordRe' : ''">
         <el-input
         <el-input
           type="password"
           type="password"
           show-password-on="mousedown"
           show-password-on="mousedown"
@@ -43,10 +40,10 @@
       <el-form-item label="角色" prop="roleIds">
       <el-form-item label="角色" prop="roleIds">
         <el-select clearable v-model="formParams.roleIds" multiple>
         <el-select clearable v-model="formParams.roleIds" multiple>
           <el-option
           <el-option
-            v-for="(item, index) in getRoleList"
-            :key="index"
-            :label="item.label"
-            :value="item.value"
+            v-for="item in roleList!"
+            :key="item.roleId"
+            :label="item.roleName"
+            :value="item.roleId"
           />
           />
         </el-select>
         </el-select>
       </el-form-item>
       </el-form-item>
@@ -56,28 +53,8 @@
       <el-form-item label="手机" prop="mobile">
       <el-form-item label="手机" prop="mobile">
         <el-input placeholder="请输入手机" v-model="formParams.mobile" />
         <el-input placeholder="请输入手机" v-model="formParams.mobile" />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="邮箱" prop="email">
-        <el-input placeholder="请输入邮箱" v-model="formParams.email" />
-      </el-form-item>
-      <el-form-item label="性别" prop="sex">
-        <el-radio-group v-model="formParams.sex" name="sexGroup">
-          <el-radio v-for="item in sexList" :key="item.dictValue" :label="item.dictLabel">
-            {{ item.dictLabel }}
-          </el-radio>
-        </el-radio-group>
-      </el-form-item>
-      <el-form-item label="所在岗位" prop="postId">
-        <el-select clearable multiple v-model="formParams.postId" placeholder="请选择所在岗位">
-          <el-option
-            v-for="(item, index) in postDataList"
-            :key="index"
-            :label="item.postName"
-            :value="item.postId"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="个人介绍" prop="remark">
-        <el-input type="textarea" placeholder="请输入个人介绍" v-model="formParams.remark" />
+      <el-form-item label="工号" prop="staffNo">
+        <el-input placeholder="请输入工号" v-model="formParams.staffNo" />
       </el-form-item>
       </el-form-item>
       <el-form-item label="是否启用" prop="isEnable">
       <el-form-item label="是否启用" prop="isEnable">
         <el-switch v-model="formParams.isEnable" />
         <el-switch v-model="formParams.isEnable" />
@@ -94,16 +71,17 @@
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-  import { ref, onMounted, computed } from 'vue';
+  import { ref, onMounted } from 'vue';
   import { FormRules, ElMessage } from 'element-plus';
   import { FormRules, ElMessage } from 'element-plus';
-  import type { formParamsType } from './types';
   import { useDictionary } from '@/hooks/web/useDictionary';
   import { useDictionary } from '@/hooks/web/useDictionary';
-
-  import { addUsur, editUsur, userInfo } from '@/api/system/user';
+  import { userInfo } from '@/api/system/user';
   import { postList } from '@/api/common/index';
   import { postList } from '@/api/common/index';
-  import { deptTreeList } from '@/api/auth/dept';
   import { cloneDeep } from 'lodash-es';
   import { cloneDeep } from 'lodash-es';
-  import { replaceParams } from '@/utils/helper/treeHelper';
+  import { UserType, addSingleUser, updateUser } from '@/api/system/user-operate';
+  import useSelectContent from './hooks/use-user-para';
+
+  const selectContent = useSelectContent();
+  const { roleList, departmentList } = selectContent;
 
 
   const rules: FormRules = {
   const rules: FormRules = {
     username: {
     username: {
@@ -133,6 +111,21 @@
       message: '密码不能为空',
       message: '密码不能为空',
       trigger: 'blur',
       trigger: 'blur',
     },
     },
+    nickname: {
+      required: true,
+      message: '用户名不能为空',
+      trigger: 'blur',
+    },
+    mobile: {
+      required: true,
+      message: '手机不能为空',
+      trigger: 'blur',
+    },
+    staffNo: {
+      required: true,
+      message: '工号不能为空',
+      trigger: 'blur',
+    },
   };
   };
 
 
   interface PostOption {
   interface PostOption {
@@ -146,38 +139,27 @@
   const props = defineProps({
   const props = defineProps({
     title: {
     title: {
       type: String,
       type: String,
-      default: '添加会员',
+      default: '添加用户',
     },
     },
     width: {
     width: {
       type: Number,
       type: Number,
       default: 450,
       default: 450,
     },
     },
-    roleList: {
-      type: Array,
-    },
   });
   });
 
 
   const sexList = ref<any[]>();
   const sexList = ref<any[]>();
-  const deptList = ref<any[]>();
+  // const deptList = ref<any[]>();
   const postDataList = ref<PostOption[]>([]);
   const postDataList = ref<PostOption[]>([]);
   const defaultValueRef = () => ({
   const defaultValueRef = () => ({
-    userId: null,
-    roleIds: [],
-    isEnable: true,
-    deptId: null,
-    email: '',
-    mobile: '',
-    nickname: '',
     password: '',
     password: '',
     passwordRe: '',
     passwordRe: '',
-    remark: '',
-    sex: '',
+    deptId: null,
     username: '',
     username: '',
-    postId: [],
-  });
-
-  const getRoleList = computed(() => {
-    return props.roleList as SelectOption[];
+    staffNo: '',
+    mobile: '',
+    isEnable: true,
+    nickname: '',
+    roleIds: [],
   });
   });
 
 
   const message = ElMessage;
   const message = ElMessage;
@@ -185,15 +167,13 @@
   const isDrawer = ref(false);
   const isDrawer = ref(false);
   const subLoading = ref(false);
   const subLoading = ref(false);
 
 
-  const formParams = ref<formParamsType>(defaultValueRef());
+  const formParams = ref<UserType>(defaultValueRef());
 
 
-  async function openDrawer(userId?) {
-    const deptResList = await deptTreeList();
-    deptList.value = replaceParams(deptResList, 'deptName', 'deptId');
+  async function openDrawer(username?) {
     const postListRes = await postList();
     const postListRes = await postList();
     postDataList.value = postListRes;
     postDataList.value = postListRes;
-    if (userId) {
-      formParams.value.userId = userId;
+    if (username) {
+      formParams.value.username = username;
       getInfo();
       getInfo();
       return;
       return;
     }
     }
@@ -211,30 +191,47 @@
       }
       }
       // 克隆
       // 克隆
       const params = cloneDeep(formParams.value);
       const params = cloneDeep(formParams.value);
-      // 处理岗位
-      if (params.postId && params.postId.length) {
-        params.postId = params.postId.join(',');
-      } else {
-        params.postId = '';
-      }
+
       // 处理部门
       // 处理部门
+      console.log('params', params);
+
       if (params.deptId) {
       if (params.deptId) {
-        params.deptId = params.deptId + '';
+        params.deptId = params.deptId;
       }
       }
       if (params.password != params.passwordRe) {
       if (params.password != params.passwordRe) {
         return message.error('两次密码不一致');
         return message.error('两次密码不一致');
       }
       }
-      const msg = params.userId ? '编辑成功' : '添加成功';
-      if (params.userId) {
-        editUsur(params).then((_) => {
-          message.success(msg);
+      // const msg = params.username ? '编辑成功' : '添加成功';
+      if (props.title === '添加用户') {
+        const addData = {
+          password: formParams.value.password,
+          deptId: formParams.value.deptId,
+          username: formParams.value.username,
+          staffNo: formParams.value.staffNo,
+          mobile: formParams.value.mobile,
+          isEnable: formParams.value.isEnable,
+          nickname: formParams.value.nickname,
+          roleIds: formParams.value.roleIds,
+        };
+        addSingleUser(addData).then(() => {
           emit('change');
           emit('change');
           handleReset();
           handleReset();
           closeDrawer();
           closeDrawer();
         });
         });
       } else {
       } else {
-        addUsur(params).then((_) => {
-          message.success(msg);
+        const updateData = {
+          userId: params.userId,
+          password: formParams.value.password,
+          deptId: formParams.value.deptId,
+          username: formParams.value.username,
+          staffNo: formParams.value.staffNo,
+          mobile: formParams.value.mobile,
+          isEnable: formParams.value.isEnable,
+          nickname: formParams.value.nickname,
+          roleIds: formParams.value.roleIds,
+          deleteStatus: '1',
+        };
+        updateUser(updateData).then(() => {
           emit('change');
           emit('change');
           handleReset();
           handleReset();
           closeDrawer();
           closeDrawer();
@@ -249,21 +246,22 @@
   }
   }
 
 
   function getInfo() {
   function getInfo() {
-    userInfo({ userId: formParams.value.userId }).then((res) => {
+    userInfo({ userId: formParams.value.username }).then((res) => {
       const params = {
       const params = {
-        userId: formParams.value.userId,
+        userId: formParams.value.username,
         deleteStatus: parseInt(res.deleteStatus),
         deleteStatus: parseInt(res.deleteStatus),
         email: res.email,
         email: res.email,
         mobile: res.mobile,
         mobile: res.mobile,
         nickname: res.nickname,
         nickname: res.nickname,
-        password: '',
-        passwordRe: '',
+        password: res.password,
+        passwordRe: res.password,
         remark: res.remark,
         remark: res.remark,
         sex: res.sex,
         sex: res.sex,
         username: res.username,
         username: res.username,
         roleIds: res.roleIds,
         roleIds: res.roleIds,
         postId: res.postId ? res.postId.split(',').map(Number) : null,
         postId: res.postId ? res.postId.split(',').map(Number) : null,
         deptId: res.deptId || null,
         deptId: res.deptId || null,
+        staffNo: res.staffNo,
       };
       };
       formParams.value = Object.assign(formParams.value, params);
       formParams.value = Object.assign(formParams.value, params);
       isDrawer.value = true;
       isDrawer.value = true;

+ 58 - 1
src/views/system/user/columns.ts

@@ -2,6 +2,63 @@ import { h } from 'vue';
 import { ElTag } from 'element-plus';
 import { ElTag } from 'element-plus';
 import { BasicColumn } from '@/components/Table';
 import { BasicColumn } from '@/components/Table';
 
 
+// export const columns: BasicColumn[] = [
+//   // {
+//   //   type: 'selection',
+//   // },
+//   {
+//     label: '账号',
+//     prop: 'username',
+//   },
+//   {
+//     label: '用户名',
+//     prop: 'nickname',
+//   },
+//   {
+//     label: '手机',
+//     prop: 'mobile',
+//   },
+//   {
+//     label: '状态',
+//     prop: 'isEnable',
+//     render(record) {
+//       return h(
+//         ElTag,
+//         {
+//           type: record.row.isEnable ? 'success' : 'danger',
+//         },
+//         {
+//           default: () => (record.row.isEnable ? '启用' : '禁用'),
+//         },
+//       );
+//     },
+//   },
+//   {
+//     label: '角色',
+//     prop: 'roleName',
+//   },
+//   {
+//     label: '租户',
+//     prop: 'tenantName',
+//   },
+//   {
+//     label: '部门',
+//     prop: 'deptName',
+//   },
+//   {
+//     label: '岗位',
+//     prop: 'postName',
+//   },
+//   // {
+//   //   label: '描述',
+//   //   prop: 'remark',
+//   // },
+//   {
+//     label: '创建时间',
+//     prop: 'createTime',
+//   },
+// ];
+
 export const columns: BasicColumn[] = [
 export const columns: BasicColumn[] = [
   {
   {
     type: 'selection',
     type: 'selection',
@@ -36,7 +93,7 @@ export const columns: BasicColumn[] = [
           type: record.row.isEnable ? 'success' : 'danger',
           type: record.row.isEnable ? 'success' : 'danger',
         },
         },
         {
         {
-          default: () => (record.row.isEnable ? '启用' : '禁用'),
+          default: () => (record.row.isEnable ? '正常' : '锁定'),
         },
         },
       );
       );
     },
     },

+ 32 - 0
src/views/system/user/component/ActionColomns.vue

@@ -0,0 +1,32 @@
+<template>
+  <div class="flex items-center justify-center">
+    <el-space :size="space">
+      <div v-for="item in props.actionIcons" :key="item.label" @click="item.onClick">
+        <el-tooltip :content="item.label" effect="light">
+          <el-icon v-if="props.style === 'icon'" :color="props.color" :size="props.size">
+            <component :is="item.icon" />
+          </el-icon>
+          <img
+            v-if="props.style === 'img'"
+            :src="item.icon"
+            :style="{ width: `${props.size}px` }"
+          />
+        </el-tooltip>
+      </div>
+    </el-space>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { ActionItem } from '@/components/Table';
+
+  const props = defineProps<{
+    space: number;
+    size: number;
+    color: string;
+    style: 'img' | 'icon';
+    actionIcons: ActionItem[];
+  }>();
+</script>
+
+<style scoped></style>

+ 223 - 0
src/views/system/user/component/AddUser.vue

@@ -0,0 +1,223 @@
+<template>
+  <div v-if="props.modelValue">
+    <el-card v-if="cardVisible" class="pop-card">
+      <template #header>
+        <div class="flex justify-between items-center pop-head">
+          <div style="font-size: 16px">批量导入</div>
+          <el-icon :size="16" class="mr-3" @click="updateValue(false)"><Close /></el-icon
+        ></div>
+      </template>
+      <div class="upload-content">
+        <el-upload
+          ref="upload"
+          class="upload-demo"
+          drag
+          action="http://localhost:8092/api/user/import"
+          :headers="headers"
+          :with-credentials="true"
+          :auto-upload="false"
+          :before-upload="beforeUpload"
+          :on-success="handleUploadSuccess"
+          style="width: 384px; height: 192px; border-radius: 8px"
+        >
+          <el-icon class="el-icon--upload" style="width: 33px; height: 42px"><Document /></el-icon>
+          <div class="el-upload__text">
+            <div style="font-size: 16px">点击或将文件拖拽到这里上传</div>
+            <div style="font-size: 14px; color: rgba(0, 0, 0, 0.45)"
+              >文件只支持:.xlsx .xls .仅支持上传一个文件</div
+            ></div
+          >
+        </el-upload>
+        <div style="margin-top: 52px; margin-left: 288px; display: flex">
+          <el-button @click="handleDownload" style="margin-right: 10px">下载模板</el-button>
+          <el-button type="primary" @click="handleImport">导入</el-button></div
+        ></div
+      >
+    </el-card>
+    <!-- //上传成功 -->
+    <el-dialog
+      v-model="DialogVisibleSuc"
+      title="Warning"
+      width="30%"
+      @close="
+        () => {
+          emits('update:modelValue', false);
+        }
+      "
+      align-center
+    >
+      <template #header="{ titleId, titleClass }">
+        <div class="my-header">
+          <h4 :id="titleId" :class="titleClass" style="display: flex">
+            <el-icon style="margin-top: 2px" color="#52C41A"><CircleCheck /></el-icon
+            ><div style="margin-left: 14px">导入成功</div></h4
+          >
+        </div>
+      </template>
+      <span style="margin-left: 30px"> 已成功添加{{ sucCount }}条用户信息</span>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="handleRightComfirm"> 确定 </el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 上传失败 -->
+    <el-dialog
+      v-model="DialogVisibleErr"
+      title="Warning"
+      width="30%"
+      @close="
+        () => {
+          emits('update:modelValue', false);
+        }
+      "
+      align-center
+    >
+      <template #header="{ titleId, titleClass }">
+        <div class="my-header">
+          <h4 :id="titleId" :class="titleClass" style="display: flex">
+            <el-icon style="margin-top: 2px" color="#FF4D4F "><Warning /></el-icon>
+            <div style="margin-left: 14px">导入失败</div></h4
+          >
+        </div>
+      </template>
+      <ul v-for="(item, index) in errDetail" :key="index">
+        <li v-if="index < 3">{{ item }} </li>
+        <li v-else v-show="showMore">{{ item }}</li>
+      </ul>
+      <div v-if="errDetail.length > 3 && !showMore" @click="showMore = true" class="more-link"
+        >更多</div
+      >
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="handleErrComfirm"> 确定 </el-button>
+        </span>
+      </template>
+    </el-dialog></div
+  >
+</template>
+
+<script setup lang="ts">
+  import { Close, Document, CircleCheck, Warning } from '@element-plus/icons-vue';
+  import { ref } from 'vue';
+  import type { UploadInstance } from 'element-plus';
+  import { downloadByUrl } from '@/utils/file/download';
+  import { useUserStore } from '@/store/modules/user';
+  import { onMounted } from 'vue';
+
+  const userStore = useUserStore();
+
+  onMounted(() => {
+    console.log('111');
+
+    console.log('props.modelValue', props.modelValue);
+
+    cardVisible.value = props.modelValue;
+  });
+
+  const headers = {
+    Satoken: userStore.getToken,
+    Tenantid: userStore.getTenantId,
+  };
+
+  const cardVisible = ref<boolean>(true);
+
+  //对话框
+  const DialogVisibleSuc = ref<boolean>(false);
+  const DialogVisibleErr = ref<boolean>(false);
+
+  //更多
+  const showMore = ref(false);
+
+  const isSuc = ref<boolean>(true);
+  const errDetail = ref<string[]>([]);
+  const sucCount = ref<number>(0);
+
+  const props = defineProps<{ modelValue: boolean }>();
+  const emits = defineEmits(['update:modelValue', 'change']);
+
+  const updateValue = (value) => {
+    emits('update:modelValue', value);
+  };
+  const upload = ref<UploadInstance>();
+
+  const handleDownload = () => {
+    downloadByUrl({
+      url: 'http://localhost:3000/dist/upload-user-templete/templete.xlsx',
+      target: '_self',
+    });
+  };
+  const handleImport = async () => {
+    upload.value!.submit();
+  };
+
+  const beforeUpload = (file) => {
+    const isExcel = /\.(xlsx|xls)$/.test(file.name.toLowerCase());
+    if (!isExcel) {
+      // 提示用户选择正确的文件类型
+      return false; // 阻止上传
+    }
+    return true; // 允许上传
+  };
+
+  const handleUploadSuccess = (response, _file, _fileList) => {
+    // const res = JSON.parse(response);
+    console.log('response', response);
+    isSuc.value = response.data.isSuc;
+    errDetail.value = response.data.failedInfo;
+    sucCount.value = response.data.sucCount || 0;
+    console.log('errDetail', errDetail.value);
+
+    if (isSuc.value) {
+      DialogVisibleSuc.value = true;
+      DialogVisibleErr.value = false;
+    } else {
+      DialogVisibleSuc.value = false;
+      DialogVisibleErr.value = true;
+    }
+    cardVisible.value = false;
+  };
+
+  const handleRightComfirm = () => {
+    DialogVisibleSuc.value = false;
+    emits('update:modelValue', false);
+    emits('change');
+  };
+  const handleErrComfirm = () => {
+    DialogVisibleErr.value = false;
+    emits('update:modelValue', false);
+    emits('change');
+  };
+
+  //对话框
+</script>
+
+<style scoped>
+  .upload-content {
+    margin-left: 96px;
+    margin-top: 36px;
+  }
+
+  .more-link {
+    color: #1890ff;
+    margin-left: 30px;
+  }
+
+  li:before {
+    content: '';
+    width: 6px;
+    height: 6px;
+    display: inline-block;
+    border-radius: 50%;
+    background: #ff4d4f;
+    vertical-align: middle;
+    margin-left: 30px;
+    margin-right: 8px;
+  }
+
+  li {
+    font-size: 14px;
+    margin-bottom: 2px;
+  }
+</style>

+ 95 - 0
src/views/system/user/component/UserQuery.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="flex items-center query-head">
+    <el-space alignment="center" :size="50">
+      <div>
+        <el-select v-model="queryType" placeholder="选择类型" class="type-select">
+          <el-option
+            v-for="item in queryTypeSelect"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+        <el-input
+          :style="{ width: '180px' }"
+          v-model="queryTypeContent"
+          clearable
+          placeholder="请输入查找内容"
+        />
+      </div>
+      <div>
+        <span>请选择角色:</span>
+        <el-select v-model="queryRoleName" placeholder="请选择角色" class="protocal-select">
+          <el-option
+            v-for="item in roleList!"
+            :key="item.roleId"
+            :label="item.roleName"
+            :value="item.roleName"
+          />
+        </el-select>
+      </div>
+      <div>
+        <span>请选择组织:</span>
+        <el-select v-model="queryDeptName" placeholder="请选择组织" class="protocal-select">
+          <el-option
+            v-for="item in departmentList"
+            :key="item.deptId"
+            :label="item.deptName"
+            :value="item.deptName"
+          />
+        </el-select>
+      </div>
+    </el-space>
+    <div class="flex-1 flex justify-end">
+      <el-button type="primary" @click="conditionSearch"> 查询 </el-button>
+      <el-button @click="resetSearch"> 重置 </el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { queryTypeSelect } from '../constant';
+  import useSelectContent from '../hooks/use-user-para';
+  import useUser from '../hooks/use-user';
+  import { storeToRefs } from 'pinia';
+
+  const selectContent = useSelectContent();
+  const { roleList, departmentList } = selectContent;
+
+  const useUserDetail = useUser();
+  const {
+    queryType,
+    queryTypeContent,
+    queryStaffNo,
+    queryNickname,
+    queryMobile,
+    queryRoleName,
+    queryDeptName,
+  } = storeToRefs(useUserDetail);
+  const { conditionSearch } = useUserDetail;
+
+  // 重置查询条件
+  const resetSearch = () => {
+    queryType.value = '';
+    queryTypeContent.value = '';
+    queryRoleName.value = '';
+    queryDeptName.value = '';
+    queryStaffNo.value = '';
+    queryNickname.value = '';
+    queryMobile.value = '';
+  };
+</script>
+
+<style scoped>
+  .type-select {
+    width: 100px;
+  }
+
+  .protocal-select {
+    width: 160px;
+  }
+
+  .query-head {
+    padding: 24px 57px 18px 21px;
+  }
+</style>

+ 35 - 0
src/views/system/user/constant.ts

@@ -0,0 +1,35 @@
+export const queryTypeSelect = [
+  {
+    value: 'staffNo',
+    label: '工号',
+  },
+  {
+    value: 'nickname',
+    label: '姓名',
+  },
+  {
+    value: 'mobile',
+    label: '手机号',
+  },
+];
+
+export enum QuerySelect {
+  'staffNo' = 'staffNo',
+  'nickname' = 'nickname',
+  'mobile' = 'mobile',
+}
+
+// export const roleTypeSelect = [
+//   {
+//     value: 'roleCode',
+//     label: '工号',
+//   },
+//   {
+//     value: 'roleName',
+//     label: '姓名',
+//   },
+//   {
+//     value: 'rolePhone',
+//     label: '手机号',
+//   },
+// ];

+ 26 - 0
src/views/system/user/hooks/use-user-para.ts

@@ -0,0 +1,26 @@
+import { getAllRoles, Department, getAllDepartments, Role } from '@/api/system/user-query';
+import { onMounted, ref } from 'vue';
+
+export const getSelectList = () => {
+  const roleList = ref<Role[]>([]);
+  const getRoleList = () => {
+    getAllRoles().then((res) => {
+      roleList.value = res.list!;
+    });
+  };
+
+  const departmentList = ref<Department[]>([]);
+  const getDepartmentList = () => {
+    getAllDepartments().then((res) => {
+      departmentList.value = res;
+    });
+  };
+
+  onMounted(() => {
+    getRoleList();
+    getDepartmentList();
+  });
+
+  return { roleList, getRoleList, departmentList, getDepartmentList };
+};
+export default getSelectList;

+ 151 - 0
src/views/system/user/hooks/use-user.ts

@@ -0,0 +1,151 @@
+import {
+  UserType,
+  addSingleUser,
+  addMultipleUser,
+  UserTypeDel,
+  delUser,
+  updateUser,
+  QueryUser,
+  getUserList,
+} from '@/api/system/user-operate';
+import { onMounted, ref } from 'vue';
+import { QuerySelect } from '../constant';
+import { defineStore } from 'pinia';
+
+export const useUser = defineStore('user-list', () => {
+  //查询的类型
+  const queryType = ref<string>('');
+  //查询输入的内容
+  const queryTypeContent = ref<string>('');
+  //查询的工号
+  const queryStaffNo = ref<string>('');
+  //查询的姓名
+  const queryNickname = ref<string>('');
+  //查询的手机号
+  const queryMobile = ref<string>('');
+  //查询的角色
+  const queryRoleName = ref<string>('');
+  //查询的组织
+  const queryDeptName = ref<string>('');
+  //user数据
+  const userList = ref<UserTypeDel[]>([]);
+
+  //编辑时的单个数据
+  //   const userData = ref<UserType>();
+
+  //当前的页数
+  const page = ref<number>(1);
+  //总页数
+  //   const totalPage = ref<number>(1);
+  //每页的数量
+  const pageSize = ref<number>(10);
+  //总数量
+  const totalCount = ref<number>(1);
+
+  //条件查询
+  const conditionSearch = () => {
+    const params: QueryUser = {
+      page: page.value,
+      pageRow: pageSize.value,
+    };
+    if (queryType.value === QuerySelect.staffNo) {
+      queryStaffNo.value = queryTypeContent.value;
+    } else if (queryType.value === QuerySelect.nickname) {
+      queryNickname.value = queryTypeContent.value;
+    } else if (queryType.value === QuerySelect.mobile) {
+      queryMobile.value = queryTypeContent.value;
+    }
+    if (queryStaffNo.value) {
+      params.staffNo = queryStaffNo.value;
+    }
+    if (queryNickname.value) {
+      params.nickname = queryNickname.value;
+    }
+    if (queryMobile.value) {
+      params.mobile = queryMobile.value;
+    }
+    if (queryRoleName.value) {
+      params.roleName = queryRoleName.value;
+    }
+    if (queryDeptName.value) {
+      params.deptName = queryDeptName.value;
+    }
+    getUserList(params).then((res) => {
+      userList.value = res.list;
+      totalCount.value = res.totalCount;
+    });
+  };
+
+  //获取列表
+  const getList = () => {
+    getUserList(null).then((res) => {
+      userList.value = res.list;
+      console.log('userList.value', userList.value);
+
+      totalCount.value = res.totalCount;
+    });
+  };
+
+  //添加单个数据
+  const singleUserAdd = (data: UserType) => {
+    addSingleUser(data).then(() => {
+      () => {
+        conditionSearch();
+      };
+    });
+  };
+
+  //添加多个数据
+  const multipleUserAdd = (data: File) => {
+    addMultipleUser(data).then(() => {
+      () => {
+        conditionSearch();
+      };
+    });
+  };
+
+  //删除用户
+  const userDel = (data: UserTypeDel) => {
+    delUser(data).then(() => {
+      conditionSearch();
+    });
+  };
+
+  //修改用户
+  const userUpdate = (data: UserType) => {
+    updateUser(data).then(() => {
+      conditionSearch();
+    });
+  };
+
+  onMounted(() => {
+    getList();
+    console.log('userList', userList.value);
+  });
+
+  return {
+    queryType,
+    queryTypeContent,
+    queryStaffNo,
+    queryNickname,
+    queryMobile,
+    queryRoleName,
+    queryDeptName,
+    userList,
+    page,
+    pageSize,
+    totalCount,
+    conditionSearch,
+    getList,
+    singleUserAdd,
+    multipleUserAdd,
+    userDel,
+    userUpdate,
+  };
+});
+
+//获取单个数据
+
+//修改用户
+
+export default useUser;

+ 161 - 0
src/views/system/user/user-copy.vue

@@ -0,0 +1,161 @@
+<template>
+  <PageWrapper>
+    <el-card :bordered="false" class="mb-3 proCard">
+      <el-space align="center">
+        <el-input
+          :style="{ width: '320px' }"
+          v-model="params.username"
+          clearable
+          placeholder="请输入账号"
+          @keyup.enter="reloadTable"
+        />
+        <el-button type="primary" @click="reloadTable" :icon="Search"> 查询 </el-button>
+      </el-space>
+    </el-card>
+    <el-card :bordered="false" class="proCard">
+      <BasicTable
+        :columns="columns"
+        :request="loadDataTable"
+        :row-key="(row) => row.userId"
+        ref="basicTableRef"
+        :actionColumn="actionColumn"
+        @update:checked-row-keys="onCheckedRow"
+        virtual-scroll
+      >
+        <template #tableTitle>
+          <el-space align="center">
+            <el-button type="primary" @click="openCreateDrawer">
+              <template #icon>
+                <el-icon>
+                  <FileAddOutlined />
+                </el-icon>
+              </template>
+              添加
+            </el-button>
+
+            <!-- <el-button type="error" @click="openRemoveModal" :disabled="!rowKeys.length">
+                <template #icon>
+                  <el-icon>
+                    <DeleteOutlined />
+                  </el-icon>
+                </template>
+                删除
+              </el-button> -->
+          </el-space>
+        </template>
+      </BasicTable>
+    </el-card>
+
+    <CreateDrawer
+      ref="createDrawerRef"
+      :title="drawerTitle"
+      :roleList="roleData"
+      @change="reloadTable"
+    />
+  </PageWrapper>
+</template>
+
+<script lang="ts" setup>
+  import { h, reactive, ref, onMounted } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
+  import { getUserList } from '@/api/system/user';
+  import { FileAddOutlined } from '@vicons/antd';
+  import { roleAllList } from '@/api/system/role';
+  import { delUser } from '@/api/system/user';
+  import CreateDrawer from './CreateDrawer.vue';
+  import { columns } from './columns';
+  import { Search } from '@element-plus/icons-vue';
+
+  const message = ElMessage;
+  const basicTableRef = ref();
+  const rowKeys = ref([]);
+  const rowKeysName = ref([]);
+  const tableData = ref();
+  const createDrawerRef = ref();
+  const drawerTitle = ref('添加用户');
+  const roleData = ref([]);
+
+  const params = reactive({
+    username: '',
+  });
+
+  const actionColumn: BasicColumn = reactive({
+    width: 150,
+    title: '操作',
+    prop: 'action',
+    fixed: 'right',
+    align: 'center',
+    render(record) {
+      return h(TableAction as any, {
+        actions: [
+          {
+            label: '删除',
+            isConfirm: true,
+            popConfirm: {
+              onConfirm: handleDelete.bind(null, record.row),
+              title: '您确定要删除吗?',
+              confirmButtonText: '确定',
+              cancelButtonText: '取消',
+            },
+          },
+          {
+            label: '编辑',
+            onClick: handleEdit.bind(null, record.row),
+          },
+        ],
+      });
+    },
+  });
+
+  const loadDataTable = async (res) => {
+    const result = await getUserList({ ...params, ...res });
+    tableData.value = result.list;
+    return result;
+  };
+
+  function onCheckedRow(keys) {
+    rowKeys.value = keys;
+    rowKeysName.value = tableData.value
+      .filter((item) => {
+        return keys.includes(item.id);
+      })
+      .map((item) => {
+        return item.username;
+      })
+      .join(',');
+  }
+
+  function reloadTable() {
+    basicTableRef.value.reload();
+  }
+
+  function openCreateDrawer() {
+    const { openDrawer } = createDrawerRef.value;
+    openDrawer();
+  }
+
+  function handleEdit(record: Recordable) {
+    console.log('点击了编辑', record);
+    drawerTitle.value = '编辑用户';
+    const { openDrawer } = createDrawerRef.value;
+    openDrawer(record.userId);
+  }
+
+  function handleDelete(record: Recordable) {
+    delUser({ userId: record.userId }).then(() => {
+      message.success('删除成功');
+      reloadTable();
+    });
+  }
+
+  onMounted(async () => {
+    const res = await roleAllList();
+    roleData.value = res.list.map((item: any) => {
+      return {
+        value: item.roleId,
+        label: item.roleName,
+      };
+    });
+  });
+</script>

+ 109 - 65
src/views/system/user/user.vue

@@ -1,73 +1,83 @@
 <template>
 <template>
-  <PageWrapper>
-    <el-card :bordered="false" class="mb-3 proCard">
-      <el-space align="center">
-        <el-input
-          :style="{ width: '320px' }"
-          v-model="params.username"
-          clearable
-          placeholder="请输入账号"
-          @keyup.enter="reloadTable"
-        />
-        <el-button type="primary" @click="reloadTable" :icon="Search"> 查询 </el-button>
-      </el-space>
-    </el-card>
-    <el-card :bordered="false" class="proCard">
+  <div class="user-page">
+    <UserQuery />
+    <div class="user-list">
       <BasicTable
       <BasicTable
         :columns="columns"
         :columns="columns"
-        :request="loadDataTable"
+        :data-source="userList"
         :row-key="(row) => row.userId"
         :row-key="(row) => row.userId"
         ref="basicTableRef"
         ref="basicTableRef"
+        :pagination="{ total: totalCount, pageSize: pageSize, hideOnSinglePage: false }"
         :actionColumn="actionColumn"
         :actionColumn="actionColumn"
+        :tableSetting="{
+          size: false,
+          redo: false,
+          fullscreen: false,
+          striped: false,
+          setting: false,
+        }"
         @update:checked-row-keys="onCheckedRow"
         @update:checked-row-keys="onCheckedRow"
         virtual-scroll
         virtual-scroll
+        @page-num-change="handlePageNumChange"
+        @page-size-change="handlePageSizeChange"
       >
       >
         <template #tableTitle>
         <template #tableTitle>
           <el-space align="center">
           <el-space align="center">
-            <el-button type="primary" @click="openCreateDrawer">
+            <el-button type="primary" @click="openAddSingleDrawer">
               <template #icon>
               <template #icon>
                 <el-icon>
                 <el-icon>
-                  <FileAddOutlined />
+                  <Plus />
                 </el-icon>
                 </el-icon>
               </template>
               </template>
               添加
               添加
             </el-button>
             </el-button>
-
-            <!-- <el-button type="error" @click="openRemoveModal" :disabled="!rowKeys.length">
+            <el-button
+              color="#1890FF"
+              @click="openAddMultipleDrawer"
+              style="margin-left: 18px"
+              plain
+            >
               <template #icon>
               <template #icon>
                 <el-icon>
                 <el-icon>
-                  <DeleteOutlined />
+                  <DocumentAdd />
                 </el-icon>
                 </el-icon>
               </template>
               </template>
-              删除
-            </el-button> -->
+              批量导入
+            </el-button>
           </el-space>
           </el-space>
         </template>
         </template>
       </BasicTable>
       </BasicTable>
-    </el-card>
-
-    <CreateDrawer
-      ref="createDrawerRef"
-      :title="drawerTitle"
-      :roleList="roleData"
+    </div>
+    <CreateDrawer ref="createDrawerRef" :title="drawerTitle" @change="reloadTable" />
+    <AddUser
+      v-if="showAddPopover"
+      v-model="showAddPopover"
+      class="add-popover"
       @change="reloadTable"
       @change="reloadTable"
     />
     />
-  </PageWrapper>
+  </div>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
   import { h, reactive, ref, onMounted } from 'vue';
   import { h, reactive, ref, onMounted } from 'vue';
-  import { ElMessage } from 'element-plus';
-  import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
-  import { getUserList } from '@/api/system/user';
-  import { FileAddOutlined } from '@vicons/antd';
+  import { BasicTable, BasicColumn } from '@/components/Table';
+  import { Plus, DocumentAdd } from '@element-plus/icons-vue';
   import { roleAllList } from '@/api/system/role';
   import { roleAllList } from '@/api/system/role';
-  import { delUser } from '@/api/system/user';
+  import editIcon from '@/assets/images/table/table-edit.png';
+  import deleteIcon from '@/assets/images/table/table-delete.png';
   import CreateDrawer from './CreateDrawer.vue';
   import CreateDrawer from './CreateDrawer.vue';
   import { columns } from './columns';
   import { columns } from './columns';
-  import { Search } from '@element-plus/icons-vue';
+  import ActionColomns from './component/ActionColomns.vue';
+  import AddUser from './component/AddUser.vue';
+  // import { Search } from '@element-plus/icons-vue';
+  import UserQuery from './component/UserQuery.vue';
+  import useUser from './hooks/use-user';
+  import { storeToRefs } from 'pinia';
+
+  const useUserDetail = useUser();
+  const { userList, page, pageSize, totalCount } = storeToRefs(useUserDetail);
+  const { conditionSearch, userDel } = useUserDetail;
 
 
-  const message = ElMessage;
   const basicTableRef = ref();
   const basicTableRef = ref();
   const rowKeys = ref([]);
   const rowKeys = ref([]);
   const rowKeysName = ref([]);
   const rowKeysName = ref([]);
@@ -76,44 +86,46 @@
   const drawerTitle = ref('添加用户');
   const drawerTitle = ref('添加用户');
   const roleData = ref([]);
   const roleData = ref([]);
 
 
-  const params = reactive({
-    username: '',
-  });
+  const handlePageNumChange = (pageNum) => {
+    console.log('pageNum', pageNum);
+
+    page.value = pageNum;
+    conditionSearch();
+  };
+  const handlePageSizeChange = (size) => {
+    page.value = 1;
+    pageSize.value = size;
+    conditionSearch();
+  };
 
 
   const actionColumn: BasicColumn = reactive({
   const actionColumn: BasicColumn = reactive({
     width: 150,
     width: 150,
     title: '操作',
     title: '操作',
     prop: 'action',
     prop: 'action',
+    key: 'action',
     fixed: 'right',
     fixed: 'right',
-    align: 'center',
     render(record) {
     render(record) {
-      return h(TableAction as any, {
-        actions: [
-          {
-            label: '删除',
-            isConfirm: true,
-            popConfirm: {
-              onConfirm: handleDelete.bind(null, record.row),
-              title: '您确定要删除吗?',
-              confirmButtonText: '确定',
-              cancelButtonText: '取消',
-            },
-          },
+      return h(ActionColomns as any, {
+        space: 20,
+        color: '#629bf9',
+        style: 'img',
+        size: 16,
+        actionIcons: [
           {
           {
             label: '编辑',
             label: '编辑',
+            icon: editIcon,
             onClick: handleEdit.bind(null, record.row),
             onClick: handleEdit.bind(null, record.row),
           },
           },
+          {
+            label: '删除',
+            icon: deleteIcon,
+            onClick: handleDelete.bind(null, record.row),
+          },
         ],
         ],
       });
       });
     },
     },
   });
   });
 
 
-  const loadDataTable = async (res) => {
-    const result = await getUserList({ ...params, ...res });
-    tableData.value = result.list;
-    return result;
-  };
-
   function onCheckedRow(keys) {
   function onCheckedRow(keys) {
     rowKeys.value = keys;
     rowKeys.value = keys;
     rowKeysName.value = tableData.value
     rowKeysName.value = tableData.value
@@ -127,13 +139,21 @@
   }
   }
 
 
   function reloadTable() {
   function reloadTable() {
-    basicTableRef.value.reload();
+    conditionSearch();
   }
   }
 
 
-  function openCreateDrawer() {
+  const openAddSingleDrawer = () => {
+    drawerTitle.value = '添加用户';
     const { openDrawer } = createDrawerRef.value;
     const { openDrawer } = createDrawerRef.value;
     openDrawer();
     openDrawer();
-  }
+  };
+
+  const showAddPopover = ref<boolean>(false);
+
+  const openAddMultipleDrawer = () => {
+    showAddPopover.value = true;
+    console.log('showAddPopover', showAddPopover.value);
+  };
 
 
   function handleEdit(record: Recordable) {
   function handleEdit(record: Recordable) {
     console.log('点击了编辑', record);
     console.log('点击了编辑', record);
@@ -143,10 +163,12 @@
   }
   }
 
 
   function handleDelete(record: Recordable) {
   function handleDelete(record: Recordable) {
-    delUser({ userId: record.userId }).then(() => {
-      message.success('删除成功');
-      reloadTable();
-    });
+    const delDetail = {
+      userId: record.userId,
+      nickname: record.nickname,
+      username: record.username,
+    };
+    userDel(delDetail);
   }
   }
 
 
   onMounted(async () => {
   onMounted(async () => {
@@ -159,3 +181,25 @@
     });
     });
   });
   });
 </script>
 </script>
+<style scoped>
+  .user-page {
+    position: relative;
+    height: calc(100vh - 64px - 12px);
+    background-color: #ffffff;
+  }
+
+  .user-list {
+    padding: 0 21px;
+  }
+
+  .add-popover {
+    position: absolute;
+    width: 593px;
+    height: 435px;
+    left: 50%;
+    top: 50%;
+    margin-top: -218px;
+    margin-left: -297px;
+    z-index: 99;
+  }
+</style>