添加用户页面.
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import qs from 'query-string';
|
|
||||||
import { DataGrid, Pagination } from '@/types/global';
|
import { DataGrid, Pagination } from '@/types/global';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,6 +20,8 @@ export interface UserCreateRequest {
|
|||||||
*/
|
*/
|
||||||
export interface UserUpdateRequest extends UserCreateRequest {
|
export interface UserUpdateRequest extends UserCreateRequest {
|
||||||
id: number;
|
id: number;
|
||||||
|
roles?: Array<number>;
|
||||||
|
password?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +45,6 @@ export interface UserQueryRequest extends Pagination {
|
|||||||
export interface UserQueryResponse {
|
export interface UserQueryResponse {
|
||||||
id?: number;
|
id?: number;
|
||||||
username?: string;
|
username?: string;
|
||||||
password?: string;
|
|
||||||
nickname?: string;
|
nickname?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
mobile?: string;
|
mobile?: string;
|
||||||
@@ -71,6 +71,27 @@ export function updateUser(request: UserUpdateRequest) {
|
|||||||
return axios.put('/infra/system-user/update', request);
|
return axios.put('/infra/system-user/update', request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户状态
|
||||||
|
*/
|
||||||
|
export function updateUserStatus(request: UserUpdateRequest) {
|
||||||
|
return axios.put('/infra/system-user/update-status', request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户角色
|
||||||
|
*/
|
||||||
|
export function updateUserRole(request: UserUpdateRequest) {
|
||||||
|
return axios.put('/infra/system-user/update-role', request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置用户密码
|
||||||
|
*/
|
||||||
|
export function resetUserPassword(request: UserUpdateRequest) {
|
||||||
|
return axios.put('/infra/system-user/reset-password', request);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过 id 查询用户
|
* 通过 id 查询用户
|
||||||
*/
|
*/
|
||||||
@@ -79,15 +100,10 @@ export function getUser(id: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过 id 批量查询用户
|
* 查询所有用户
|
||||||
*/
|
*/
|
||||||
export function getUserList(idList: Array<number>) {
|
export function getUserList() {
|
||||||
return axios.get<UserQueryResponse[]>('/infra/system-user/list', {
|
return axios.get<UserQueryResponse[]>('/infra/system-user/list');
|
||||||
params: { idList },
|
|
||||||
paramsSerializer: params => {
|
|
||||||
return qs.stringify(params, { arrayFormat: 'comma' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,14 +120,3 @@ export function deleteUser(id: number) {
|
|||||||
return axios.delete('/infra/system-user/delete', { params: { id } });
|
return axios.delete('/infra/system-user/delete', { params: { id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过 id 批量删除用户
|
|
||||||
*/
|
|
||||||
export function batchDeleteUser(idList: Array<number>) {
|
|
||||||
return axios.delete('/infra/system-user/delete-batch', {
|
|
||||||
params: { idList },
|
|
||||||
paramsSerializer: params => {
|
|
||||||
return qs.stringify(params, { arrayFormat: 'comma' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ const columns = [
|
|||||||
title: '组件名称',
|
title: '组件名称',
|
||||||
dataIndex: 'component',
|
dataIndex: 'component',
|
||||||
slotName: 'component',
|
slotName: 'component',
|
||||||
width: 150,
|
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: true,
|
tooltip: true,
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
body-class="modal-form"
|
body-class="modal-form"
|
||||||
title-align="start"
|
title-align="start"
|
||||||
:title="title"
|
:title="title"
|
||||||
:top="120"
|
:top="80"
|
||||||
:align-center="false"
|
:align-center="false"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<a-form-item field="status" label="角色状态" label-col-flex="50px">
|
<a-form-item field="status" label="角色状态" label-col-flex="50px">
|
||||||
<a-select v-model="formModel.status"
|
<a-select v-model="formModel.status"
|
||||||
placeholder="请选择角色状态"
|
placeholder="请选择角色状态"
|
||||||
:options="toOptions(ROLE_STATUS_ENUM)"
|
:options="toOptions(RoleStatusEnum)"
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-query-header>
|
</a-query-header>
|
||||||
@@ -62,24 +62,24 @@
|
|||||||
</template>
|
</template>
|
||||||
<!-- 状态 -->
|
<!-- 状态 -->
|
||||||
<template #status="{ record }">
|
<template #status="{ record }">
|
||||||
<a-tag :color="getEnumValue(record.status, ROLE_STATUS_ENUM,'color')">
|
<a-tag :color="getEnumValue(record.status, RoleStatusEnum,'color')">
|
||||||
{{ getEnumValue(record.status, ROLE_STATUS_ENUM) }}
|
{{ getEnumValue(record.status, RoleStatusEnum) }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #handle="{ record }">
|
<template #handle="{ record }">
|
||||||
<div class="table-handle-wrapper">
|
<div class="table-handle-wrapper">
|
||||||
<!-- 修改状态 -->
|
<!-- 修改状态 -->
|
||||||
<a-popconfirm :content="`确定要${toggleEnumValue(record.status, ROLE_STATUS_ENUM, 'label')}当前角色吗?`"
|
<a-popconfirm :content="`确定要${toggleEnumValue(record.status, RoleStatusEnum, 'label')}当前角色吗?`"
|
||||||
position="left"
|
position="left"
|
||||||
type="warning"
|
type="warning"
|
||||||
@ok="toggleRoleStatus(record)">
|
@ok="toggleRoleStatus(record)">
|
||||||
<a-button v-permission="['infra:system-role:delete']"
|
<a-button v-permission="['infra:system-role:delete']"
|
||||||
:disabled="record.code === 'admin'"
|
:disabled="record.code === 'admin'"
|
||||||
:status="toggleEnumValue(record.status, ROLE_STATUS_ENUM, 'status')"
|
:status="toggleEnumValue(record.status, RoleStatusEnum, 'status')"
|
||||||
type="text"
|
type="text"
|
||||||
size="mini">
|
size="mini">
|
||||||
{{ toggleEnumValue(record.status, ROLE_STATUS_ENUM, 'label') }}
|
{{ toggleEnumValue(record.status, RoleStatusEnum, 'label') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
<!-- 绑定菜单 -->
|
<!-- 绑定菜单 -->
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import columns from '../types/table.columns';
|
import columns from '../types/table.columns';
|
||||||
import { ROLE_STATUS_ENUM } from '../types/enum.types';
|
import { RoleStatusEnum } from '../types/enum.types';
|
||||||
import { toOptions, getEnumValue, toggleEnumValue, toggleEnum } from '@/utils/enum';
|
import { toOptions, getEnumValue, toggleEnumValue, toggleEnum } from '@/utils/enum';
|
||||||
import { defaultPagination } from '@/types/table';
|
import { defaultPagination } from '@/types/table';
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
const toggleRoleStatus = async (record: any) => {
|
const toggleRoleStatus = async (record: any) => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const toggleStatus = toggleEnum(record.status, ROLE_STATUS_ENUM);
|
const toggleStatus = toggleEnum(record.status, RoleStatusEnum);
|
||||||
// 调用修改接口
|
// 调用修改接口
|
||||||
await updateRoleStatus({ id: record.id, status: toggleStatus.value });
|
await updateRoleStatus({ id: record.id, status: toggleStatus.value });
|
||||||
Message.success(`${toggleStatus.label}成功`);
|
Message.success(`${toggleStatus.label}成功`);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* 角色状态
|
* 角色状态
|
||||||
*/
|
*/
|
||||||
export const ROLE_STATUS_ENUM = {
|
export const RoleStatusEnum = {
|
||||||
DISABLED: {
|
DISABLED: {
|
||||||
value: 0,
|
value: 0,
|
||||||
label: '停用',
|
label: '停用',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const columns = [
|
|||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
slotName: 'createTime',
|
slotName: 'createTime',
|
||||||
|
width: 180,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: ({ record }) => {
|
render: ({ record }) => {
|
||||||
return dateFormat(new Date(record.createTime));
|
return dateFormat(new Date(record.createTime));
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
body-class="modal-form"
|
body-class="modal-form"
|
||||||
title-align="start"
|
title-align="start"
|
||||||
:title="title"
|
:title="title"
|
||||||
:top="120"
|
:top="80"
|
||||||
:align-center="false"
|
:align-center="false"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
@@ -22,20 +22,18 @@
|
|||||||
:rules="formRules">
|
:rules="formRules">
|
||||||
<!-- 用户名 -->
|
<!-- 用户名 -->
|
||||||
<a-form-item field="username" label="用户名">
|
<a-form-item field="username" label="用户名">
|
||||||
<a-input v-model="formModel.username" placeholder="请输入用户名" />
|
<a-input v-model="formModel.username" :disabled="!isAddHandle" placeholder="请输入用户名" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 密码 -->
|
<!-- 密码 -->
|
||||||
<a-form-item field="password" label="密码">
|
<a-form-item v-if="isAddHandle"
|
||||||
<a-input v-model="formModel.password" placeholder="请输入密码" />
|
field="password"
|
||||||
|
label="密码">
|
||||||
|
<a-input-password v-model="formModel.password" placeholder="请输入密码" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 花名 -->
|
<!-- 花名 -->
|
||||||
<a-form-item field="nickname" label="花名">
|
<a-form-item field="nickname" label="花名">
|
||||||
<a-input v-model="formModel.nickname" placeholder="请输入花名" />
|
<a-input v-model="formModel.nickname" placeholder="请输入花名" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 头像地址 -->
|
|
||||||
<a-form-item field="avatar" label="头像地址">
|
|
||||||
<a-input v-model="formModel.avatar" placeholder="请输入头像地址" />
|
|
||||||
</a-form-item>
|
|
||||||
<!-- 手机号 -->
|
<!-- 手机号 -->
|
||||||
<a-form-item field="mobile" label="手机号">
|
<a-form-item field="mobile" label="手机号">
|
||||||
<a-input v-model="formModel.mobile" placeholder="请输入手机号" />
|
<a-input v-model="formModel.mobile" placeholder="请输入手机号" />
|
||||||
@@ -44,17 +42,6 @@
|
|||||||
<a-form-item field="email" label="邮箱">
|
<a-form-item field="email" label="邮箱">
|
||||||
<a-input v-model="formModel.email" placeholder="请输入邮箱" />
|
<a-input v-model="formModel.email" placeholder="请输入邮箱" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 用户状态 0停用 1启用 2锁定 -->
|
|
||||||
<a-form-item field="status" label="用户状态 0停用 1启用 2锁定">
|
|
||||||
<a-input-number v-model="formModel.status" placeholder="请输入用户状态 0停用 1启用 2锁定" />
|
|
||||||
</a-form-item>
|
|
||||||
<!-- 最后登录时间 -->
|
|
||||||
<a-form-item field="lastLoginTime" label="最后登录时间">
|
|
||||||
<a-date-picker v-model="formModel.lastLoginTime"
|
|
||||||
style="width: 100%"
|
|
||||||
placeholder="请选择最后登录时间"
|
|
||||||
show-time />
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@@ -73,6 +60,7 @@
|
|||||||
import formRules from '../types/form.rules';
|
import formRules from '../types/form.rules';
|
||||||
import { createUser, updateUser } from '@/api/user/user';
|
import { createUser, updateUser } from '@/api/user/user';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import { md5 } from '@/utils';
|
||||||
|
|
||||||
const { visible, setVisible } = useVisible();
|
const { visible, setVisible } = useVisible();
|
||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
@@ -86,11 +74,8 @@
|
|||||||
username: undefined,
|
username: undefined,
|
||||||
password: undefined,
|
password: undefined,
|
||||||
nickname: undefined,
|
nickname: undefined,
|
||||||
avatar: undefined,
|
|
||||||
mobile: undefined,
|
mobile: undefined,
|
||||||
email: undefined,
|
email: undefined,
|
||||||
status: undefined,
|
|
||||||
lastLoginTime: undefined,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -135,7 +120,7 @@
|
|||||||
}
|
}
|
||||||
if (isAddHandle.value) {
|
if (isAddHandle.value) {
|
||||||
// 新增
|
// 新增
|
||||||
await createUser(formModel as any);
|
await createUser({ ...formModel, password: md5(formModel.password) } as any);
|
||||||
Message.success('创建成功');
|
Message.success('创建成功');
|
||||||
emits('added');
|
emits('added');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,44 +6,33 @@
|
|||||||
@submit="fetchTableData"
|
@submit="fetchTableData"
|
||||||
@reset="fetchTableData">
|
@reset="fetchTableData">
|
||||||
<!-- id -->
|
<!-- id -->
|
||||||
<a-form-item field="id" label="id" label-col-flex="60px">
|
<a-form-item field="id" label="id" label-col-flex="50px">
|
||||||
<a-input-number v-model="formModel.id" placeholder="请输入id" allow-clear/>
|
<a-input-number v-model="formModel.id" placeholder="请输入id" allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 用户名 -->
|
<!-- 用户名 -->
|
||||||
<a-form-item field="username" label="用户名" label-col-flex="60px">
|
<a-form-item field="username" label="用户名" label-col-flex="50px">
|
||||||
<a-input v-model="formModel.username" placeholder="请输入用户名" allow-clear/>
|
<a-input v-model="formModel.username" placeholder="请输入用户名" allow-clear />
|
||||||
</a-form-item>
|
|
||||||
<!-- 密码 -->
|
|
||||||
<a-form-item field="password" label="密码" label-col-flex="60px">
|
|
||||||
<a-input v-model="formModel.password" placeholder="请输入密码" allow-clear/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 花名 -->
|
<!-- 花名 -->
|
||||||
<a-form-item field="nickname" label="花名" label-col-flex="60px">
|
<a-form-item field="nickname" label="花名" label-col-flex="50px">
|
||||||
<a-input v-model="formModel.nickname" placeholder="请输入花名" allow-clear/>
|
<a-input v-model="formModel.nickname" placeholder="请输入花名" allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 头像地址 -->
|
<!-- 用户状态 -->
|
||||||
<a-form-item field="avatar" label="头像地址" label-col-flex="60px">
|
<a-form-item field="status" label="用户状态 " label-col-flex="50px">
|
||||||
<a-input v-model="formModel.avatar" placeholder="请输入头像地址" allow-clear/>
|
<a-select
|
||||||
|
v-model="formModel.status"
|
||||||
|
:options="toOptions(UserStatusEnum)"
|
||||||
|
placeholder="请选择用户状态"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 手机号 -->
|
<!-- 手机号 -->
|
||||||
<a-form-item field="mobile" label="手机号" label-col-flex="60px">
|
<a-form-item field="mobile" label="手机号" label-col-flex="50px">
|
||||||
<a-input v-model="formModel.mobile" placeholder="请输入手机号" allow-clear/>
|
<a-input v-model="formModel.mobile" placeholder="请输入手机号" allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 邮箱 -->
|
<!-- 邮箱 -->
|
||||||
<a-form-item field="email" label="邮箱" label-col-flex="60px">
|
<a-form-item field="email" label="邮箱" label-col-flex="50px">
|
||||||
<a-input v-model="formModel.email" placeholder="请输入邮箱" allow-clear/>
|
<a-input v-model="formModel.email" placeholder="请输入邮箱" allow-clear />
|
||||||
</a-form-item>
|
|
||||||
<!-- 用户状态 0停用 1启用 2锁定 -->
|
|
||||||
<a-form-item field="status" label="用户状态 0停用 1启用 2锁定" label-col-flex="60px">
|
|
||||||
<a-input-number v-model="formModel.status" placeholder="请输入用户状态 0停用 1启用 2锁定" allow-clear/>
|
|
||||||
</a-form-item>
|
|
||||||
<!-- 最后登录时间 -->
|
|
||||||
<a-form-item field="lastLoginTime" label="最后登录时间" label-col-flex="60px">
|
|
||||||
<a-date-picker v-model="formModel.lastLoginTime"
|
|
||||||
style="width: 100%"
|
|
||||||
placeholder="请选择最后登录时间"
|
|
||||||
show-time
|
|
||||||
allow-clear/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-query-header>
|
</a-query-header>
|
||||||
</a-card>
|
</a-card>
|
||||||
@@ -66,21 +55,6 @@
|
|||||||
<icon-plus />
|
<icon-plus />
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<!-- 删除 -->
|
|
||||||
<a-popconfirm position="br"
|
|
||||||
type="warning"
|
|
||||||
:content="`确认删除选中的${selectedKeys.length}条记录吗?`"
|
|
||||||
@ok="deleteSelectRows">
|
|
||||||
<a-button v-permission="['infra:system-user:delete']"
|
|
||||||
type="secondary"
|
|
||||||
status="danger"
|
|
||||||
:disabled="selectedKeys.length === 0">
|
|
||||||
删除
|
|
||||||
<template #icon>
|
|
||||||
<icon-delete />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -91,16 +65,38 @@
|
|||||||
label-align="left"
|
label-align="left"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
v-model:selectedKeys="selectedKeys"
|
|
||||||
:row-selection="rowSelection"
|
|
||||||
:data="tableRenderData"
|
:data="tableRenderData"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
||||||
@page-size-change="(size) => fetchTableData(pagination.current, size)"
|
@page-size-change="(size) => fetchTableData(pagination.current, size)"
|
||||||
:bordered="false">
|
:bordered="false">
|
||||||
|
<!-- 状态 -->
|
||||||
|
<template #status="{ record }">
|
||||||
|
<a-tag :color="getEnumValue(record.status, UserStatusEnum,'color')">
|
||||||
|
{{ getEnumValue(record.status, UserStatusEnum) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #handle="{ record }">
|
<template #handle="{ record }">
|
||||||
<div class="table-handle-wrapper">
|
<div class="table-handle-wrapper">
|
||||||
|
<!-- 启用/停用 -->
|
||||||
|
<a-popconfirm :content="`确定要${UserStatusEnum.ENABLED.value === record.status
|
||||||
|
? UserStatusEnum.DISABLED.label
|
||||||
|
: UserStatusEnum.ENABLED.label}当前用户?`"
|
||||||
|
position="left"
|
||||||
|
type="warning"
|
||||||
|
@ok="updateStatus(record)">
|
||||||
|
<a-button type="text"
|
||||||
|
size="mini"
|
||||||
|
:disabled="record.id === userStore.id"
|
||||||
|
v-permission="['infra:system-user:update-status']">
|
||||||
|
{{
|
||||||
|
UserStatusEnum.ENABLED.value === record.status
|
||||||
|
? UserStatusEnum.DISABLED.label
|
||||||
|
: UserStatusEnum.ENABLED.label
|
||||||
|
}}
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
<!-- 修改 -->
|
<!-- 修改 -->
|
||||||
<a-button type="text"
|
<a-button type="text"
|
||||||
size="mini"
|
size="mini"
|
||||||
@@ -108,6 +104,20 @@
|
|||||||
@click="emits('openUpdate', record)">
|
@click="emits('openUpdate', record)">
|
||||||
修改
|
修改
|
||||||
</a-button>
|
</a-button>
|
||||||
|
<!-- 重置密码 -->
|
||||||
|
<a-button type="text"
|
||||||
|
size="mini"
|
||||||
|
v-permission="['infra:system-user:reset-password']"
|
||||||
|
@click="emits('openResetPassword', record)">
|
||||||
|
重置密码
|
||||||
|
</a-button>
|
||||||
|
<!-- 分配角色 -->
|
||||||
|
<a-button type="text"
|
||||||
|
size="mini"
|
||||||
|
v-permission="['infra:system-user:update-role']"
|
||||||
|
@click="emits('openUpdateRole', record)">
|
||||||
|
分配角色
|
||||||
|
</a-button>
|
||||||
<!-- 删除 -->
|
<!-- 删除 -->
|
||||||
<a-popconfirm content="确认删除这条记录吗?"
|
<a-popconfirm content="确认删除这条记录吗?"
|
||||||
position="left"
|
position="left"
|
||||||
@@ -115,6 +125,7 @@
|
|||||||
@ok="deleteRow(record)">
|
@ok="deleteRow(record)">
|
||||||
<a-button type="text" size="mini"
|
<a-button type="text" size="mini"
|
||||||
status="danger"
|
status="danger"
|
||||||
|
:disabled="record.id === userStore.id"
|
||||||
v-permission="['infra:system-user:delete']">
|
v-permission="['infra:system-user:delete']">
|
||||||
删除
|
删除
|
||||||
</a-button>
|
</a-button>
|
||||||
@@ -133,19 +144,20 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { batchDeleteUser, deleteUser, getUserPage, UserQueryRequest, UserQueryResponse } from '@/api/user/user';
|
import { deleteUser, getUserPage, updateUserStatus, UserQueryRequest, UserQueryResponse } from '@/api/user/user';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import columns from '../types/table.columns';
|
import columns from '../types/table.columns';
|
||||||
import { defaultPagination, defaultRowSelection } from '@/types/table';
|
import { UserStatusEnum } from '../types/enum.types';
|
||||||
|
import { defaultPagination } from '@/types/table';
|
||||||
|
import { toOptions, getEnumValue } from '@/utils/enum';
|
||||||
|
import { useUserStore } from '@/store';
|
||||||
|
|
||||||
const tableRenderData = ref<UserQueryResponse[]>();
|
const tableRenderData = ref<UserQueryResponse[]>();
|
||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
const emits = defineEmits(['openAdd', 'openUpdate']);
|
const emits = defineEmits(['openAdd', 'openUpdate', 'openResetPassword', 'openUpdateRole']);
|
||||||
|
|
||||||
const pagination = reactive(defaultPagination());
|
const pagination = reactive(defaultPagination());
|
||||||
const selectedKeys = ref<number[]>([]);
|
|
||||||
const rowSelection = reactive(defaultRowSelection());
|
|
||||||
|
|
||||||
const formModel = reactive<UserQueryRequest>({
|
const formModel = reactive<UserQueryRequest>({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
@@ -159,20 +171,7 @@
|
|||||||
lastLoginTime: undefined,
|
lastLoginTime: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 删除选中行
|
const userStore = useUserStore();
|
||||||
const deleteSelectRows = async () => {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
// 调用删除接口
|
|
||||||
await batchDeleteUser(selectedKeys.value);
|
|
||||||
Message.success(`成功删除${selectedKeys.value.length}条数据`);
|
|
||||||
selectedKeys.value = [];
|
|
||||||
// 重新加载数据
|
|
||||||
await fetchTableData();
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除当前行
|
// 删除当前行
|
||||||
const deleteRow = async ({ id }: { id: number }) => {
|
const deleteRow = async ({ id }: { id: number }) => {
|
||||||
@@ -188,6 +187,25 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
const updateStatus = async (record: any) => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
// 更新状态
|
||||||
|
const newStatus = UserStatusEnum.ENABLED.value === record.status
|
||||||
|
? UserStatusEnum.DISABLED
|
||||||
|
: UserStatusEnum.ENABLED;
|
||||||
|
await updateUserStatus({
|
||||||
|
id: record.id,
|
||||||
|
status: newStatus.value
|
||||||
|
});
|
||||||
|
Message.success(`${newStatus.label}成功`);
|
||||||
|
record.status = newStatus.value;
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 添加后回调
|
// 添加后回调
|
||||||
const addedCallback = () => {
|
const addedCallback = () => {
|
||||||
fetchTableData();
|
fetchTableData();
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
<div class="layout-container">
|
<div class="layout-container">
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<user-table ref="table"
|
<user-table ref="table"
|
||||||
@openAdd="() => modal.openAdd()"
|
@openAdd="() => modal.openAdd()"
|
||||||
@openUpdate="(e) => modal.openUpdate(e)" />
|
@openUpdate="(e) => modal.openUpdate(e)" />
|
||||||
<!-- 添加修改模态框 -->
|
<!-- 添加修改模态框 -->
|
||||||
<user-form-modal ref="modal"
|
<user-form-modal ref="modal"
|
||||||
@added="() => table.addedCallback()"
|
@added="() => table.addedCallback()"
|
||||||
@updated="() => table.updatedCallback()" />
|
@updated="() => table.updatedCallback()" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,21 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*用户状态
|
||||||
*/
|
*/
|
||||||
export const USER_STATUS_ENUM = {
|
export const UserStatusEnum = {
|
||||||
DISABLED: {
|
DISABLED: {
|
||||||
value: null,
|
value: 0,
|
||||||
label: '',
|
label: '停用',
|
||||||
color: '',
|
color: 'orange',
|
||||||
status: '0',
|
|
||||||
name: 'DISABLED',
|
|
||||||
},
|
},
|
||||||
ENABLED: {
|
ENABLED: {
|
||||||
value: null,
|
value: 1,
|
||||||
label: '',
|
label: '启用',
|
||||||
color: '',
|
color: 'blue',
|
||||||
status: '1',
|
|
||||||
name: 'ENABLED',
|
|
||||||
},
|
},
|
||||||
LOCKED: {
|
LOCKED: {
|
||||||
value: null,
|
value: 2,
|
||||||
label: '',
|
label: '锁定',
|
||||||
color: '',
|
color: 'orange',
|
||||||
status: '2',
|
|
||||||
name: 'LOCKED',
|
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,18 @@ export const username = [{
|
|||||||
}, {
|
}, {
|
||||||
maxLength: 32,
|
maxLength: 32,
|
||||||
message: '用户名长度不能大于32位'
|
message: '用户名长度不能大于32位'
|
||||||
|
}, {
|
||||||
|
match: /^[a-zA-Z0-9]{4,32}$/,
|
||||||
|
message: '用户名只能是 4-32 位的数字以及字母'
|
||||||
}] as FieldRule[];
|
}] as FieldRule[];
|
||||||
|
|
||||||
export const password = [{
|
export const password = [{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入密码'
|
message: '请输入密码'
|
||||||
}, {
|
}, {
|
||||||
maxLength: 64,
|
minLength: 8,
|
||||||
message: '密码长度不能大于64位'
|
maxLength: 32,
|
||||||
|
message: '密码长度需要在 8-32 位之间'
|
||||||
}] as FieldRule[];
|
}] as FieldRule[];
|
||||||
|
|
||||||
export const nickname = [{
|
export const nickname = [{
|
||||||
@@ -24,47 +28,20 @@ export const nickname = [{
|
|||||||
message: '花名长度不能大于16位'
|
message: '花名长度不能大于16位'
|
||||||
}] as FieldRule[];
|
}] as FieldRule[];
|
||||||
|
|
||||||
export const avatar = [{
|
|
||||||
required: true,
|
|
||||||
message: '请输入头像地址'
|
|
||||||
}, {
|
|
||||||
maxLength: 500,
|
|
||||||
message: '头像地址长度不能大于500位'
|
|
||||||
}] as FieldRule[];
|
|
||||||
|
|
||||||
export const mobile = [{
|
export const mobile = [{
|
||||||
required: true,
|
|
||||||
message: '请输入手机号'
|
|
||||||
}, {
|
|
||||||
maxLength: 15,
|
maxLength: 15,
|
||||||
message: '手机号长度不能大于15位'
|
message: '手机号长度不能大于15位'
|
||||||
}] as FieldRule[];
|
}] as FieldRule[];
|
||||||
|
|
||||||
export const email = [{
|
export const email = [{
|
||||||
required: true,
|
|
||||||
message: '请输入邮箱'
|
|
||||||
}, {
|
|
||||||
maxLength: 64,
|
maxLength: 64,
|
||||||
message: '邮箱长度不能大于64位'
|
message: '邮箱长度不能大于64位'
|
||||||
}] as FieldRule[];
|
}] as FieldRule[];
|
||||||
|
|
||||||
export const status = [{
|
|
||||||
required: true,
|
|
||||||
message: '请输入用户状态 0停用 1启用 2锁定'
|
|
||||||
}] as FieldRule[];
|
|
||||||
|
|
||||||
export const lastLoginTime = [{
|
|
||||||
required: true,
|
|
||||||
message: '请输入最后登录时间'
|
|
||||||
}] as FieldRule[];
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
nickname,
|
nickname,
|
||||||
avatar,
|
|
||||||
mobile,
|
mobile,
|
||||||
email,
|
email,
|
||||||
status,
|
|
||||||
lastLoginTime,
|
|
||||||
} as Record<string, FieldRule | FieldRule[]>;
|
} as Record<string, FieldRule | FieldRule[]>;
|
||||||
|
|||||||
@@ -13,28 +13,12 @@ const columns = [
|
|||||||
title: '用户名',
|
title: '用户名',
|
||||||
dataIndex: 'username',
|
dataIndex: 'username',
|
||||||
slotName: 'username',
|
slotName: 'username',
|
||||||
align: 'center',
|
|
||||||
ellipsis: true,
|
|
||||||
tooltip: true,
|
|
||||||
}, {
|
|
||||||
title: '密码',
|
|
||||||
dataIndex: 'password',
|
|
||||||
slotName: 'password',
|
|
||||||
align: 'center',
|
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: true,
|
tooltip: true,
|
||||||
}, {
|
}, {
|
||||||
title: '花名',
|
title: '花名',
|
||||||
dataIndex: 'nickname',
|
dataIndex: 'nickname',
|
||||||
slotName: 'nickname',
|
slotName: 'nickname',
|
||||||
align: 'center',
|
|
||||||
ellipsis: true,
|
|
||||||
tooltip: true,
|
|
||||||
}, {
|
|
||||||
title: '头像地址',
|
|
||||||
dataIndex: 'avatar',
|
|
||||||
slotName: 'avatar',
|
|
||||||
align: 'center',
|
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: true,
|
tooltip: true,
|
||||||
}, {
|
}, {
|
||||||
@@ -48,11 +32,10 @@ const columns = [
|
|||||||
title: '邮箱',
|
title: '邮箱',
|
||||||
dataIndex: 'email',
|
dataIndex: 'email',
|
||||||
slotName: 'email',
|
slotName: 'email',
|
||||||
align: 'center',
|
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: true,
|
tooltip: true,
|
||||||
}, {
|
}, {
|
||||||
title: '用户状态 0停用 1启用 2锁定',
|
title: '用户状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
slotName: 'status',
|
slotName: 'status',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
@@ -60,36 +43,15 @@ const columns = [
|
|||||||
title: '最后登录时间',
|
title: '最后登录时间',
|
||||||
dataIndex: 'lastLoginTime',
|
dataIndex: 'lastLoginTime',
|
||||||
slotName: 'lastLoginTime',
|
slotName: 'lastLoginTime',
|
||||||
|
width: 180,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: ({ record }) => {
|
render: ({ record }) => {
|
||||||
return record.lastLoginTime && dateFormat(new Date(record.lastLoginTime));
|
return record.lastLoginTime && dateFormat(new Date(record.lastLoginTime));
|
||||||
},
|
},
|
||||||
}, {
|
|
||||||
title: '创建时间',
|
|
||||||
dataIndex: 'createTime',
|
|
||||||
slotName: 'createTime',
|
|
||||||
render: ({ record }) => {
|
|
||||||
return dateFormat(new Date(record.createTime));
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
title: '修改时间',
|
|
||||||
dataIndex: 'updateTime',
|
|
||||||
slotName: 'updateTime',
|
|
||||||
render: ({ record }) => {
|
|
||||||
return dateFormat(new Date(record.createTime));
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
title: '创建人',
|
|
||||||
dataIndex: 'creator',
|
|
||||||
slotName: 'creator',
|
|
||||||
}, {
|
|
||||||
title: '修改人',
|
|
||||||
dataIndex: 'updater',
|
|
||||||
slotName: 'updater',
|
|
||||||
}, {
|
}, {
|
||||||
title: '操作',
|
title: '操作',
|
||||||
slotName: 'handle',
|
slotName: 'handle',
|
||||||
width: 130,
|
width: 290,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user