feat(system): 实现用户审核功能
- 新增用户模型字段:auditStatus、auditRemark、auditTime - 添加用户审核接口 auditUser,支持单条审核 - 用户列表页增加审核状态筛选项和对应列展示 - 列表行内仅待审核用户显示“审核”操作链接 - 工具栏添加批量审核按钮,实现批量审核功能 - 审核弹窗支持选择通过或拒绝及填写备注 - 审核提交支持单条和批量调用接口 - 保持代码类型检查无新增错误,符合项目字段命名规范
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import type { ApiResult, PageResult } from '@/api';
|
||||
import type { User, UserParam } from './model';
|
||||
import type { User, UserParam, UserAuditRequest } from './model';
|
||||
import { SERVER_API_URL } from '@/config/setting';
|
||||
|
||||
/**
|
||||
@@ -293,3 +293,19 @@ export async function exportUsers(params?: UserParam) {
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核用户
|
||||
* @param id 用户id
|
||||
* @param data 审核结果
|
||||
*/
|
||||
export async function auditUser(id: number, data: UserAuditRequest) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
SERVER_API_URL + '/system/user/audit/' + id,
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
@@ -129,6 +129,12 @@ export interface User {
|
||||
followers?: number;
|
||||
// 推荐人ID
|
||||
dealerId?: number;
|
||||
// 审核状态: 0待审核 1通过 2拒绝
|
||||
auditStatus?: number;
|
||||
// 审核备注
|
||||
auditRemark?: string;
|
||||
// 审核时间
|
||||
auditTime?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,4 +164,16 @@ export interface UserParam extends PageParam {
|
||||
showProfile?: boolean;
|
||||
isStaff?: boolean;
|
||||
templateId?: number;
|
||||
// 审核状态: 0待审核 1通过 2拒绝
|
||||
auditStatus?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户审核请求
|
||||
*/
|
||||
export interface UserAuditRequest {
|
||||
// 审核状态: 1-通过 2-拒绝
|
||||
status: number;
|
||||
// 审核备注
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,18 @@
|
||||
<a-select-option :value="2">普通用户</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="审核状态">
|
||||
<a-select
|
||||
v-model:value="searchWhere.auditStatus"
|
||||
placeholder="全部"
|
||||
allow-clear
|
||||
style="width: 140px"
|
||||
>
|
||||
<a-select-option :value="0">待审核</a-select-option>
|
||||
<a-select-option :value="1">通过</a-select-option>
|
||||
<a-select-option :value="2">拒绝</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" @click="reload()">搜索</a-button>
|
||||
<a-button style="margin-left: 8px" @click="resetSearch">重置</a-button>
|
||||
@@ -84,6 +96,17 @@
|
||||
:disabled="selection.length === 0"
|
||||
>重置密码
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
@click="openBatchAudit"
|
||||
:disabled="selection.length === 0"
|
||||
>
|
||||
<template #icon>
|
||||
<CheckCircleOutlined />
|
||||
</template>
|
||||
<span>批量审核</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
@@ -142,6 +165,12 @@
|
||||
<a-tag v-else-if="record.status === 1" color="red">冻结</a-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'auditStatus'">
|
||||
<a-tag v-if="record.auditStatus === 0" color="orange">待审核</a-tag>
|
||||
<a-tag v-else-if="record.auditStatus === 1" color="green">通过</a-tag>
|
||||
<a-tag v-else-if="record.auditStatus === 2" color="red">拒绝</a-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'platform'">
|
||||
<WechatOutlined v-if="record.platform === 'MP-WEIXIN'" />
|
||||
<Html5Outlined v-if="record.platform === 'H5'" />
|
||||
@@ -168,7 +197,9 @@
|
||||
<template v-if="column.key === 'action'">
|
||||
<div>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-divider type="vertical" v-if="record.auditStatus === 0" />
|
||||
<a v-if="record.auditStatus === 0" @click.stop="openAudit(record)">审核</a>
|
||||
<a-divider type="vertical" v-if="record.auditStatus === 0" />
|
||||
<!-- <a @click="resetPsw(record)">重置</a>-->
|
||||
<!-- <a-divider type="vertical" />-->
|
||||
<a-popconfirm
|
||||
@@ -194,6 +225,28 @@
|
||||
<user-import v-model:visible="showImport" @done="reload" />
|
||||
<!-- 用户详情 -->
|
||||
<user-info v-model:visible="showInfo" :data="current" @done="reload" />
|
||||
<!-- 审核弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="showAudit"
|
||||
:title="auditTitle"
|
||||
@ok="submitAudit"
|
||||
>
|
||||
<a-form :model="auditForm" layout="vertical">
|
||||
<a-form-item label="审核结果">
|
||||
<a-radio-group v-model:value="auditForm.status">
|
||||
<a-radio :value="1">通过</a-radio>
|
||||
<a-radio :value="2">拒绝</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="审核备注">
|
||||
<a-textarea
|
||||
v-model:value="auditForm.remark"
|
||||
:rows="3"
|
||||
placeholder="请输入审核备注(拒绝时建议填写)"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-page-header>
|
||||
</template>
|
||||
|
||||
@@ -209,7 +262,8 @@
|
||||
Html5Outlined,
|
||||
ChromeOutlined,
|
||||
WechatOutlined,
|
||||
ExclamationCircleOutlined
|
||||
ExclamationCircleOutlined,
|
||||
CheckCircleOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro/es';
|
||||
import type {
|
||||
@@ -227,7 +281,8 @@
|
||||
removeUsers,
|
||||
updateUserPassword,
|
||||
updateUser,
|
||||
listUsers
|
||||
listUsers,
|
||||
auditUser
|
||||
} from '@/api/system/user';
|
||||
import type { User, UserParam } from '@/api/system/user/model';
|
||||
import { toTreeData, uuid } from 'ele-admin-pro';
|
||||
@@ -258,17 +313,31 @@
|
||||
const showInfo = ref(false);
|
||||
// 是否显示用户导入弹窗
|
||||
const showImport = ref(false);
|
||||
// 是否显示审核弹窗
|
||||
const showAudit = ref(false);
|
||||
// 是否批量审核
|
||||
const batchAudit = ref(false);
|
||||
// 审核弹窗标题
|
||||
const auditTitle = ref('审核用户');
|
||||
// 审核表单
|
||||
const auditForm = reactive({
|
||||
userId: undefined as number | undefined,
|
||||
status: 1,
|
||||
remark: ''
|
||||
});
|
||||
const searchText = ref('');
|
||||
// 高级筛选条件
|
||||
const searchWhere = reactive({
|
||||
roleId: undefined,
|
||||
platform: undefined,
|
||||
isAdmin: undefined
|
||||
isAdmin: undefined,
|
||||
auditStatus: undefined
|
||||
});
|
||||
const resetSearch = () => {
|
||||
searchWhere.roleId = undefined;
|
||||
searchWhere.platform = undefined;
|
||||
searchWhere.isAdmin = undefined;
|
||||
searchWhere.auditStatus = undefined;
|
||||
reload();
|
||||
};
|
||||
const userStore = useUserStore();
|
||||
@@ -457,6 +526,13 @@
|
||||
align: 'center',
|
||||
width: 90
|
||||
},
|
||||
{
|
||||
title: '审核状态',
|
||||
dataIndex: 'auditStatus',
|
||||
key: 'auditStatus',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '管理员',
|
||||
key: 'isAdmin',
|
||||
@@ -477,7 +553,7 @@
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 120,
|
||||
width: 160,
|
||||
fixed: 'right',
|
||||
align: 'center'
|
||||
}
|
||||
@@ -496,7 +572,8 @@
|
||||
keywords: searchText.value,
|
||||
roleId: searchWhere.roleId,
|
||||
platform: searchWhere.platform,
|
||||
isAdmin: searchWhere.isAdmin || undefined
|
||||
isAdmin: searchWhere.isAdmin || undefined,
|
||||
auditStatus: searchWhere.auditStatus || undefined
|
||||
};
|
||||
return pageUsers({ page, limit, ...params, ...orders });
|
||||
};
|
||||
@@ -604,6 +681,51 @@
|
||||
});
|
||||
};
|
||||
|
||||
/* 打开单条审核弹窗 */
|
||||
const openAudit = (row: User) => {
|
||||
batchAudit.value = false;
|
||||
auditForm.userId = row.userId;
|
||||
auditForm.status = 1;
|
||||
auditForm.remark = '';
|
||||
auditTitle.value = `审核用户 - ${row.nickname || row.username}`;
|
||||
showAudit.value = true;
|
||||
};
|
||||
|
||||
/* 打开批量审核弹窗 */
|
||||
const openBatchAudit = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
batchAudit.value = true;
|
||||
auditForm.userId = undefined;
|
||||
auditForm.status = 1;
|
||||
auditForm.remark = '';
|
||||
auditTitle.value = `批量审核(已选 ${selection.value.length} 条)`;
|
||||
showAudit.value = true;
|
||||
};
|
||||
|
||||
/* 提交审核 */
|
||||
const submitAudit = () => {
|
||||
const hide = message.loading('提交中..', 0);
|
||||
const doOne = (userId: number) =>
|
||||
auditUser(userId, { status: auditForm.status, remark: auditForm.remark });
|
||||
const tasks = batchAudit.value
|
||||
? selection.value.map((d) => doOne(d.userId as number))
|
||||
: [doOne(auditForm.userId as number)];
|
||||
Promise.all(tasks)
|
||||
.then(() => {
|
||||
hide();
|
||||
message.success('审核完成');
|
||||
showAudit.value = false;
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 搜索处理 */
|
||||
const handleSearch = () => {
|
||||
reload();
|
||||
|
||||
Reference in New Issue
Block a user