mirror of
				https://github.com/soybeanjs/soybean-admin.git
				synced 2025-11-04 07:43:42 +08:00 
			
		
		
		
	feat(projects): 实现用户管理页面
This commit is contained in:
		@@ -1,3 +1,4 @@
 | 
			
		||||
import { mock } from 'mockjs';
 | 
			
		||||
import type { MockMethod } from 'vite-plugin-mock';
 | 
			
		||||
 | 
			
		||||
const apis: MockMethod[] = [
 | 
			
		||||
@@ -5,44 +6,26 @@ const apis: MockMethod[] = [
 | 
			
		||||
    url: '/mock/getUserManagementList',
 | 
			
		||||
    method: 'post',
 | 
			
		||||
    response: (): Service.MockServiceResult<ApiUserManagement.UserTable[]> => {
 | 
			
		||||
      const data: ApiUserManagement.UserTable[] = [
 | 
			
		||||
        {
 | 
			
		||||
          id: '1',
 | 
			
		||||
          name: '张三',
 | 
			
		||||
          age: 24,
 | 
			
		||||
          gender: null,
 | 
			
		||||
          createTime: '2022-04-13',
 | 
			
		||||
          updateTime: '2022-07-29'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '2',
 | 
			
		||||
          name: '李四',
 | 
			
		||||
          age: 22,
 | 
			
		||||
          gender: '1',
 | 
			
		||||
          createTime: '2022-05-13',
 | 
			
		||||
          updateTime: '2022-06-29'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '3',
 | 
			
		||||
          name: '王五',
 | 
			
		||||
          gender: '1',
 | 
			
		||||
          createTime: '2022-04-18',
 | 
			
		||||
          updateTime: '2022-07-30'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '4',
 | 
			
		||||
          name: '王小梅',
 | 
			
		||||
          age: 20,
 | 
			
		||||
          gender: '0',
 | 
			
		||||
          createTime: '2022-05-18',
 | 
			
		||||
          updateTime: '2022-07-30'
 | 
			
		||||
        }
 | 
			
		||||
      ];
 | 
			
		||||
      const data = mock({
 | 
			
		||||
        'list|1000': [
 | 
			
		||||
          {
 | 
			
		||||
            id: '@id',
 | 
			
		||||
            name: '@cname',
 | 
			
		||||
            'age|20-36': 36,
 | 
			
		||||
            'gender|1': ['0', '1', null],
 | 
			
		||||
            phone:
 | 
			
		||||
              /^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/,
 | 
			
		||||
            email: '@email("qq.com")',
 | 
			
		||||
            'role|1': ['super', 'admin', 'user'],
 | 
			
		||||
            'disabled|1': true
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        code: 200,
 | 
			
		||||
        message: 'ok',
 | 
			
		||||
        data
 | 
			
		||||
        data: data.list
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/** 手机号码正则 */
 | 
			
		||||
export const REGEXP_PHONE =
 | 
			
		||||
  /^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$/;
 | 
			
		||||
  /^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/;
 | 
			
		||||
 | 
			
		||||
/** 邮箱正则 */
 | 
			
		||||
export const REGEXP_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <hover-container class="w-64px h-full" tooltip-content="重新加载" placement="bottom-end" @click="handleRefresh">
 | 
			
		||||
    <icon-mdi-refresh class="text-18px" :class="{ 'animate-spin': loading }" />
 | 
			
		||||
    <icon-mdi-refresh class="text-22px" :class="{ 'animate-spin': loading }" />
 | 
			
		||||
  </hover-container>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
  <n-button
 | 
			
		||||
    type="primary"
 | 
			
		||||
    :class="[{ '!right-330px': app.settingDrawerVisible }, app.settingDrawerVisible ? 'ease-out' : 'ease-in']"
 | 
			
		||||
    class="fixed top-240px right-14px z-10000 w-42px h-42px !p-0 transition-all duration-300"
 | 
			
		||||
    class="fixed top-360px right-14px z-10000 w-42px h-42px !p-0 transition-all duration-300"
 | 
			
		||||
    @click="app.toggleSettingDrawerVisible"
 | 
			
		||||
  >
 | 
			
		||||
    <icon-ant-design-close-outlined v-if="app.settingDrawerVisible" class="text-24px" />
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,7 @@ import { EnumGender } from '@/enum';
 | 
			
		||||
import { isUndefined } from '@/utils';
 | 
			
		||||
 | 
			
		||||
export function adapterOfFetchUserManagementList(
 | 
			
		||||
  requestData: ApiUserManagement.UserTable[],
 | 
			
		||||
  adminId: string
 | 
			
		||||
  requestData: ApiUserManagement.UserTable[]
 | 
			
		||||
): UserManagement.UserTable[] {
 | 
			
		||||
  const genderMap: Record<
 | 
			
		||||
    NonNullable<ApiUserManagement.UserTable['gender']>,
 | 
			
		||||
@@ -17,21 +16,25 @@ export function adapterOfFetchUserManagementList(
 | 
			
		||||
  // 2. 接口定义的字段有可能为null, 例如 预期是数组却返回了null,导致调用数组方法报错
 | 
			
		||||
  // 3. 字段可能丢失
 | 
			
		||||
 | 
			
		||||
  return requestData.map(item => {
 | 
			
		||||
    const { id, name, age, gender } = item;
 | 
			
		||||
 | 
			
		||||
    const userName = name + (adminId === id ? '(管理员)' : '');
 | 
			
		||||
  return requestData.map((item, index) => {
 | 
			
		||||
    const { id, name: userName, age, gender, phone: userPhone, email: userEmail, role: userRole, disabled } = item;
 | 
			
		||||
 | 
			
		||||
    const userAge = isUndefined(age) ? '无' : String(age);
 | 
			
		||||
 | 
			
		||||
    const userGender = gender !== null ? genderMap[gender] : 'null';
 | 
			
		||||
 | 
			
		||||
    const result: UserManagement.UserTable = {
 | 
			
		||||
      index: index + 1,
 | 
			
		||||
      key: id,
 | 
			
		||||
      id,
 | 
			
		||||
      userName,
 | 
			
		||||
      userAge,
 | 
			
		||||
      userGender,
 | 
			
		||||
      userGenderLabel: EnumGender[userGender]
 | 
			
		||||
      userGenderLabel: EnumGender[userGender],
 | 
			
		||||
      userPhone,
 | 
			
		||||
      userEmail,
 | 
			
		||||
      userRole,
 | 
			
		||||
      disabled
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,15 +8,5 @@ import { adapterOfFetchUserManagementList } from './management.adapter';
 | 
			
		||||
export async function fetchUserManagementList() {
 | 
			
		||||
  const data = await mockRequest.post<ApiUserManagement.UserTable[]>('/getUserManagementList');
 | 
			
		||||
 | 
			
		||||
  const id = '2';
 | 
			
		||||
 | 
			
		||||
  return adapter(adapterOfFetchUserManagementList, data, { error: null, data: id });
 | 
			
		||||
  return adapter(adapterOfFetchUserManagementList, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// export async function fetchFilterUserManagementList(
 | 
			
		||||
//   filterKey: keyof UserManagement.UserTable,
 | 
			
		||||
//   mode: 'fontEnd' | 'backEnd',
 | 
			
		||||
//   source: UserManagement.UserTable[]
 | 
			
		||||
// ) {
 | 
			
		||||
 | 
			
		||||
// }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								src/typings/api.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								src/typings/api.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -36,16 +36,20 @@ declare namespace ApiUserManagement {
 | 
			
		||||
    /** 用户名 */
 | 
			
		||||
    name: string;
 | 
			
		||||
    /** 用户年龄 */
 | 
			
		||||
    age?: number;
 | 
			
		||||
    age: number;
 | 
			
		||||
    /**
 | 
			
		||||
     * 用户性别
 | 
			
		||||
     * - 男 1
 | 
			
		||||
     * - 女 0
 | 
			
		||||
     */
 | 
			
		||||
    gender: '0' | '1' | null;
 | 
			
		||||
    /** 创建时间 */
 | 
			
		||||
    createTime: string;
 | 
			
		||||
    /** 更新时间 */
 | 
			
		||||
    updateTime: string;
 | 
			
		||||
    /** 用户手机号码 */
 | 
			
		||||
    phone: string;
 | 
			
		||||
    /** 用户邮箱 */
 | 
			
		||||
    email: string;
 | 
			
		||||
    /** 用户角色 */
 | 
			
		||||
    role: Auth.RoleType;
 | 
			
		||||
    /** 是否禁用用户 */
 | 
			
		||||
    disabled: boolean;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/typings/business.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								src/typings/business.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -67,6 +67,10 @@ declare namespace Message {
 | 
			
		||||
declare namespace UserManagement {
 | 
			
		||||
  /** 用户表格 */
 | 
			
		||||
  interface UserTable {
 | 
			
		||||
    /** 序号 */
 | 
			
		||||
    index: number;
 | 
			
		||||
    /** 数据的key(id) */
 | 
			
		||||
    key: string;
 | 
			
		||||
    /** 用户id */
 | 
			
		||||
    id: string;
 | 
			
		||||
    /** 用户名 */
 | 
			
		||||
@@ -80,5 +84,13 @@ declare namespace UserManagement {
 | 
			
		||||
     */
 | 
			
		||||
    userGender: keyof typeof import('@/enum').EnumGender;
 | 
			
		||||
    userGenderLabel: import('@/enum').EnumGender;
 | 
			
		||||
    /** 用户手机号 */
 | 
			
		||||
    userPhone: string;
 | 
			
		||||
    /** 用户邮箱 */
 | 
			
		||||
    userEmail: string;
 | 
			
		||||
    /** 用户角色 */
 | 
			
		||||
    userRole: Auth.RoleType;
 | 
			
		||||
    /** 是否禁用用户 */
 | 
			
		||||
    disabled: boolean;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										124
									
								
								src/views/management/user/components/TableActionModal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/views/management/user/components/TableActionModal.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <n-modal v-model:show="modalVisible" preset="card" :title="title" class="w-700px">
 | 
			
		||||
    <n-form label-placement="left" :label-width="80" :model="formModel">
 | 
			
		||||
      <n-grid :cols="24" :x-gap="18">
 | 
			
		||||
        <n-form-item-grid-item :span="12" label="用户名" path="userName">
 | 
			
		||||
          <n-input v-model:value="formModel.userName" />
 | 
			
		||||
        </n-form-item-grid-item>
 | 
			
		||||
        <n-form-item-grid-item :span="12" label="年龄" path="userAge">
 | 
			
		||||
          <n-input v-model:value="formModel.userAge" />
 | 
			
		||||
        </n-form-item-grid-item>
 | 
			
		||||
        <n-form-item-grid-item :span="12" label="性别" path="userGender">
 | 
			
		||||
          <n-input v-model:value="formModel.userGender" />
 | 
			
		||||
        </n-form-item-grid-item>
 | 
			
		||||
        <n-form-item-grid-item :span="12" label="手机号" path="userPhone">
 | 
			
		||||
          <n-input v-model:value="formModel.userPhone" />
 | 
			
		||||
        </n-form-item-grid-item>
 | 
			
		||||
        <n-form-item-grid-item :span="12" label="邮箱" path="userEmail">
 | 
			
		||||
          <n-input v-model:value="formModel.userEmail" />
 | 
			
		||||
        </n-form-item-grid-item>
 | 
			
		||||
        <n-form-item-grid-item :span="12" label="角色" path="userRole">
 | 
			
		||||
          <n-input v-model:value="formModel.userRole" />
 | 
			
		||||
        </n-form-item-grid-item>
 | 
			
		||||
        <n-form-item-grid-item :span="12" label="状态" path="disabled">
 | 
			
		||||
          <n-switch v-model:value="formModel.disabled" />
 | 
			
		||||
        </n-form-item-grid-item>
 | 
			
		||||
      </n-grid>
 | 
			
		||||
    </n-form>
 | 
			
		||||
  </n-modal>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { reactive, computed, watch } from 'vue';
 | 
			
		||||
 | 
			
		||||
defineOptions({ name: 'TableActionModal' });
 | 
			
		||||
 | 
			
		||||
type ModalType = 'add' | 'edit';
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  /** 弹窗可见性 */
 | 
			
		||||
  visible: boolean;
 | 
			
		||||
  /** 弹窗类型 */
 | 
			
		||||
  type?: ModalType;
 | 
			
		||||
  /** 编辑的表格行数据 */
 | 
			
		||||
  editData?: UserManagement.UserTable | null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(defineProps<Props>(), {
 | 
			
		||||
  type: 'add',
 | 
			
		||||
  editData: null
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
interface Emits {
 | 
			
		||||
  (e: 'update:visible', visible: boolean): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<Emits>();
 | 
			
		||||
 | 
			
		||||
const modalVisible = computed({
 | 
			
		||||
  get() {
 | 
			
		||||
    return props.visible;
 | 
			
		||||
  },
 | 
			
		||||
  set(visible) {
 | 
			
		||||
    emit('update:visible', visible);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const title = computed(() => {
 | 
			
		||||
  const titles: Record<ModalType, string> = {
 | 
			
		||||
    add: '添加用户',
 | 
			
		||||
    edit: '编辑用户'
 | 
			
		||||
  };
 | 
			
		||||
  return titles[props.type];
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
type FormModel = Pick<
 | 
			
		||||
  UserManagement.UserTable,
 | 
			
		||||
  'userName' | 'userAge' | 'userGender' | 'userPhone' | 'userEmail' | 'userRole' | 'disabled'
 | 
			
		||||
>;
 | 
			
		||||
 | 
			
		||||
const formModel = reactive<FormModel>(createDefaultFormModel());
 | 
			
		||||
 | 
			
		||||
function createDefaultFormModel(): FormModel {
 | 
			
		||||
  return {
 | 
			
		||||
    userName: '',
 | 
			
		||||
    userAge: '',
 | 
			
		||||
    userGender: 'null',
 | 
			
		||||
    userPhone: '',
 | 
			
		||||
    userEmail: '',
 | 
			
		||||
    userRole: 'user',
 | 
			
		||||
    disabled: true
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleUpdateFormModel(model: Partial<FormModel>) {
 | 
			
		||||
  Object.assign(formModel, model);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleUpdateFormModelByModalType() {
 | 
			
		||||
  const handlers: Record<ModalType, () => void> = {
 | 
			
		||||
    add: () => {
 | 
			
		||||
      const defaultFormModel = createDefaultFormModel();
 | 
			
		||||
      handleUpdateFormModel(defaultFormModel);
 | 
			
		||||
    },
 | 
			
		||||
    edit: () => {
 | 
			
		||||
      if (props.editData) {
 | 
			
		||||
        handleUpdateFormModel(props.editData);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handlers[props.type]();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
  () => props.visible,
 | 
			
		||||
  newValue => {
 | 
			
		||||
    if (newValue) {
 | 
			
		||||
      handleUpdateFormModelByModalType();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped></style>
 | 
			
		||||
							
								
								
									
										3
									
								
								src/views/management/user/components/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/views/management/user/components/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
import TableActionModal from './TableActionModal.vue';
 | 
			
		||||
 | 
			
		||||
export { TableActionModal };
 | 
			
		||||
@@ -1,34 +1,42 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <n-data-table :columns="columns" :data="tableData" :loading="loading" />
 | 
			
		||||
  </div>
 | 
			
		||||
  <n-card title="用户管理" :bordered="false" class="rounded-16px shadow-sm">
 | 
			
		||||
    <n-space class="pb-12px" justify="space-between">
 | 
			
		||||
      <n-space>
 | 
			
		||||
        <n-button type="primary" @click="handleAddTable">
 | 
			
		||||
          <icon-ic-round-plus class="mr-4px text-20px" />
 | 
			
		||||
          新增
 | 
			
		||||
        </n-button>
 | 
			
		||||
        <n-button type="error">
 | 
			
		||||
          <icon-ic-round-delete class="mr-4px text-20px" />
 | 
			
		||||
          删除
 | 
			
		||||
        </n-button>
 | 
			
		||||
        <n-button type="success">
 | 
			
		||||
          <icon-uil:export class="mr-4px text-20px" />
 | 
			
		||||
          导出Excel
 | 
			
		||||
        </n-button>
 | 
			
		||||
      </n-space>
 | 
			
		||||
      <n-space>
 | 
			
		||||
        <n-switch />
 | 
			
		||||
        <icon-mdi-refresh class="text-20px" />
 | 
			
		||||
      </n-space>
 | 
			
		||||
    </n-space>
 | 
			
		||||
    <n-data-table :columns="columns" :data="tableData" :loading="loading" :pagination="pagination" />
 | 
			
		||||
    <table-action-modal v-model:visible="visible" :type="modalType" :edit-data="editData" />
 | 
			
		||||
  </n-card>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import type { DataTableColumns } from 'naive-ui';
 | 
			
		||||
<script setup lang="tsx">
 | 
			
		||||
import { ref, reactive } from 'vue';
 | 
			
		||||
import { NSwitch, NTag, NSpace, NPopconfirm, NButton } from 'naive-ui';
 | 
			
		||||
import type { DataTableColumns, PaginationProps } from 'naive-ui';
 | 
			
		||||
import { fetchUserManagementList } from '@/service';
 | 
			
		||||
import { useLoading } from '@/hooks';
 | 
			
		||||
import { useLoading, useBoolean } from '@/hooks';
 | 
			
		||||
import { TableActionModal } from './components';
 | 
			
		||||
 | 
			
		||||
const { loading, startLoading, endLoading } = useLoading(false);
 | 
			
		||||
 | 
			
		||||
const columns: DataTableColumns = [
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userName',
 | 
			
		||||
    title: '用户名'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userAge',
 | 
			
		||||
    title: '用户年龄'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userGenderLabel',
 | 
			
		||||
    title: '性别'
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
const { bool: visible, setTrue: openModal } = useBoolean();
 | 
			
		||||
 | 
			
		||||
const tableData = ref<UserManagement.UserTable[]>([]);
 | 
			
		||||
 | 
			
		||||
function setTableData(data: UserManagement.UserTable[]) {
 | 
			
		||||
  tableData.value = data;
 | 
			
		||||
}
 | 
			
		||||
@@ -44,6 +52,157 @@ async function getTableData() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const columns: DataTableColumns = [
 | 
			
		||||
  {
 | 
			
		||||
    type: 'selection',
 | 
			
		||||
    align: 'center'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'index',
 | 
			
		||||
    title: '序号',
 | 
			
		||||
    align: 'center'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userName',
 | 
			
		||||
    title: '用户名',
 | 
			
		||||
    align: 'center'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userAge',
 | 
			
		||||
    title: '用户年龄',
 | 
			
		||||
    align: 'center'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userGenderLabel',
 | 
			
		||||
    title: '性别',
 | 
			
		||||
    align: 'center',
 | 
			
		||||
    render: row => {
 | 
			
		||||
      const rowData = row as unknown as UserManagement.UserTable;
 | 
			
		||||
 | 
			
		||||
      if (rowData.userGender !== 'null') {
 | 
			
		||||
        const tagType = {
 | 
			
		||||
          male: 'success',
 | 
			
		||||
          female: 'warning'
 | 
			
		||||
        } as const;
 | 
			
		||||
        return <NTag type={tagType[rowData.userGender]}>{rowData.userGenderLabel}</NTag>;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return <span></span>;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userPhone',
 | 
			
		||||
    title: '手机号码',
 | 
			
		||||
    align: 'center'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userEmail',
 | 
			
		||||
    title: '邮箱',
 | 
			
		||||
    align: 'center'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'userRole',
 | 
			
		||||
    title: '角色',
 | 
			
		||||
    align: 'center',
 | 
			
		||||
    render: row => {
 | 
			
		||||
      const rowData = row as unknown as UserManagement.UserTable;
 | 
			
		||||
 | 
			
		||||
      const tagType = {
 | 
			
		||||
        super: 'primary',
 | 
			
		||||
        admin: 'warning',
 | 
			
		||||
        user: 'success'
 | 
			
		||||
      } as const;
 | 
			
		||||
 | 
			
		||||
      return <NTag type={tagType[rowData.userRole]}>{rowData.userRole}</NTag>;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'disabled',
 | 
			
		||||
    title: '状态',
 | 
			
		||||
    align: 'center',
 | 
			
		||||
    render: row => {
 | 
			
		||||
      const rowData = row as unknown as UserManagement.UserTable;
 | 
			
		||||
 | 
			
		||||
      return (
 | 
			
		||||
        <NSwitch value={rowData.disabled} onUpdateValue={disabled => handleUpdateDisabled(disabled, rowData.id)}>
 | 
			
		||||
          {{ checked: () => '启用', unchecked: () => '禁用' }}
 | 
			
		||||
        </NSwitch>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'actions',
 | 
			
		||||
    title: '操作',
 | 
			
		||||
    align: 'center',
 | 
			
		||||
    render: row => {
 | 
			
		||||
      const rowData = row as unknown as UserManagement.UserTable;
 | 
			
		||||
      return (
 | 
			
		||||
        <NSpace justify={'center'}>
 | 
			
		||||
          <NButton size={'small'} onClick={() => handleEditTable(rowData.id)}>
 | 
			
		||||
            编辑
 | 
			
		||||
          </NButton>
 | 
			
		||||
          <NPopconfirm onPositiveClick={() => handleDeleteTable(rowData.id)}>
 | 
			
		||||
            {{
 | 
			
		||||
              default: () => '确认删除',
 | 
			
		||||
              trigger: () => <NButton size={'small'}>删除</NButton>
 | 
			
		||||
            }}
 | 
			
		||||
          </NPopconfirm>
 | 
			
		||||
        </NSpace>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
function handleUpdateDisabled(disabled: boolean, rowId: string) {
 | 
			
		||||
  const index = tableData.value.findIndex(item => item.id === rowId);
 | 
			
		||||
  if (index > -1) {
 | 
			
		||||
    tableData.value[index].disabled = disabled;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ModalType = 'add' | 'edit';
 | 
			
		||||
 | 
			
		||||
const modalType = ref<ModalType>('add');
 | 
			
		||||
function setModalType(type: ModalType) {
 | 
			
		||||
  modalType.value = type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const editData = ref<UserManagement.UserTable | null>(null);
 | 
			
		||||
function setEditData(data: UserManagement.UserTable | null) {
 | 
			
		||||
  editData.value = data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleAddTable() {
 | 
			
		||||
  openModal();
 | 
			
		||||
  setModalType('add');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleEditTable(rowId: string) {
 | 
			
		||||
  const findItem = tableData.value.find(item => item.id === rowId);
 | 
			
		||||
  if (findItem) {
 | 
			
		||||
    setEditData(findItem);
 | 
			
		||||
  }
 | 
			
		||||
  setModalType('edit');
 | 
			
		||||
  openModal();
 | 
			
		||||
}
 | 
			
		||||
function handleDeleteTable(rowId: string) {
 | 
			
		||||
  window.$message?.info(`点击了删除,rowId为${rowId}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const pagination = reactive<PaginationProps>({
 | 
			
		||||
  page: 1,
 | 
			
		||||
  pageSize: 10,
 | 
			
		||||
  showSizePicker: true,
 | 
			
		||||
  pageSizes: [10, 15, 20, 25, 30],
 | 
			
		||||
  onChange: (page: number) => {
 | 
			
		||||
    pagination.page = page;
 | 
			
		||||
  },
 | 
			
		||||
  onUpdatePageSize: (pageSize: number) => {
 | 
			
		||||
    pagination.pageSize = pageSize;
 | 
			
		||||
    pagination.page = 1;
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
  getTableData();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user