v0.0.6 用户认证审核功能

This commit is contained in:
zpc 2025-11-16 23:11:35 +08:00
parent eed67d80f2
commit 835ff6e899
8 changed files with 262 additions and 6 deletions

View File

@ -124,5 +124,26 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
return ExportExcel(result.Item2, result.Item1);
}
/// <summary>
/// 审核认证申请
/// </summary>
/// <param name="parm">审核参数</param>
/// <returns></returns>
[HttpPost("review")]
[ActionPermissionFilter(Permission = "tusercertifications:review")]
[Log(Title = "认证审核", BusinessType = BusinessType.UPDATE)]
public IActionResult ReviewCertification([FromBody] ReviewCertificationDto parm)
{
if (parm.Id == 0)
{
throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空");
}
long reviewerId = HttpContext.GetUId();
var response = _T_UserCertificationsService.ReviewCertification(parm, reviewerId);
return ToResponse(response);
}
}
}

View File

@ -78,4 +78,27 @@ namespace ZR.LiveForum.Model.Liveforum.Dto
[ExcelColumn(Name = "审核状态")]
public string? StatusLabel { get; set; }
}
/// <summary>
/// 认证审核对象
/// </summary>
public class ReviewCertificationDto
{
/// <summary>
/// 认证申请记录ID
/// </summary>
[Required(ErrorMessage = "认证申请记录ID不能为空")]
public long Id { get; set; }
/// <summary>
/// 审核状态1-通过2-拒绝)
/// </summary>
[Required(ErrorMessage = "审核状态不能为空")]
public int Status { get; set; }
/// <summary>
/// 拒绝原因(拒绝时必填)
/// </summary>
public string? RejectReason { get; set; }
}
}

View File

@ -45,7 +45,7 @@ namespace ZR.LiveForum.Model.Liveforum
public int? FanLevel { get; set; }
/// <summary>
/// 审核状态
/// 审核状态 审核状态0-待审核1-通过2-拒绝
/// </summary>
public int? Status { get; set; }

View File

@ -16,6 +16,13 @@ namespace ZR.Service.Liveforum.ILiveforumService
T_UserCertifications AddT_UserCertifications(T_UserCertifications parm);
int UpdateT_UserCertifications(T_UserCertifications parm);
/// <summary>
/// 审核认证申请
/// </summary>
/// <param name="parm">审核参数</param>
/// <param name="reviewerId">审核人用户ID</param>
/// <returns></returns>
int ReviewCertification(ReviewCertificationDto parm, long reviewerId);
PagedInfo<T_UserCertificationsDto> ExportList(T_UserCertificationsQueryDto parm);
}

View File

@ -1,4 +1,4 @@
using ZR.LiveForum.Model.Liveforum.Dto;
using ZR.LiveForum.Model.Liveforum.Dto;
using ZR.LiveForum.Model.Liveforum;
namespace ZR.Service.Liveforum.ILiveforumService

View File

@ -1,7 +1,9 @@
using Infrastructure.Attribute;
using Infrastructure;
using Infrastructure.Attribute;
using Infrastructure.Extensions;
using ZR.LiveForum.Model.Liveforum.Dto;
using ZR.LiveForum.Model.Liveforum;
using ZR.LiveForum.Model.Liveforum.Dto;
using ZR.Repository;
using ZR.Service.Liveforum.ILiveforumService;
@ -13,6 +15,12 @@ namespace ZR.Service.Liveforum
[AppService(ServiceType = typeof(IT_UserCertificationsService), ServiceLifetime = LifeTime.Transient)]
public class T_UserCertificationsService : BaseService<T_UserCertifications>, IT_UserCertificationsService
{
private readonly IT_UsersService _usersService;
public T_UserCertificationsService(IT_UsersService usersService)
{
_usersService = usersService;
}
/// <summary>
/// 查询认证申请记录列表
/// </summary>
@ -66,6 +74,69 @@ namespace ZR.Service.Liveforum
return Update(model, true);
}
/// <summary>
/// 审核认证申请
/// </summary>
/// <param name="parm">审核参数</param>
/// <param name="reviewerId">审核人用户ID</param>
/// <returns></returns>
public int ReviewCertification(ReviewCertificationDto parm, long reviewerId)
{
// 验证审核状态
if (parm.Status != 1 && parm.Status != 2)
{
throw new CustomException(ResultCode.CUSTOM_ERROR, "审核状态无效只能为1通过或2拒绝");
}
// 验证拒绝时拒绝原因必填
if (parm.Status == 2 && string.IsNullOrWhiteSpace(parm.RejectReason))
{
throw new CustomException(ResultCode.CUSTOM_ERROR, "审核拒绝时,拒绝原因不能为空");
}
// 获取认证记录
var certification = GetById(parm.Id);
if (certification == null)
{
throw new CustomException(ResultCode.CUSTOM_ERROR, "认证申请记录不存在");
}
// 验证状态为待审核
if (certification.Status != 0)
{
throw new CustomException(ResultCode.CUSTOM_ERROR, "该认证申请记录已审核,不能重复审核");
}
// 使用事务处理
return Context.Ado.UseTran(() =>
{
// 更新认证申请记录
certification.Status = parm.Status;
certification.ReviewerId = reviewerId;
certification.ReviewedAt = DateTime.Now;
if (parm.Status == 2)
{
certification.RejectReason = parm.RejectReason;
}
Update(certification, false);
// 如果审核通过,更新用户表
if (parm.Status == 1)
{
var user = _usersService.GetById(certification.UserId);
if (user == null)
{
throw new CustomException(ResultCode.CUSTOM_ERROR, "用户不存在");
}
user.CertifiedType = 1;
user.IsCertified = true;
_usersService.UpdateT_Users(user);
}
return 1;
}).IsSuccess ? 1 : 0;
}
/// <summary>
/// 导出认证申请记录
/// </summary>

View File

@ -60,3 +60,15 @@ export function deltusercertifications(pid) {
export async function exporttusercertifications(query) {
await downFile('liveforum/tusercertifications/export', { ...query })
}
/**
* 审核认证申请
* @param {审核参数} data
*/
export function reviewcertification(data) {
return request({
url: 'liveforum/tusercertifications/review',
method: 'post',
data: data,
})
}

View File

@ -75,9 +75,17 @@
<el-table-column prop="reviewedAt" label="审核完成时间" :show-overflow-tooltip="true" v-if="columns.showColumn('reviewedAt')"/>
<el-table-column prop="createdAt" label="认证申请创建时间" :show-overflow-tooltip="true" v-if="columns.showColumn('createdAt')"/>
<el-table-column prop="updatedAt" label="记录更新时间" :show-overflow-tooltip="true" v-if="columns.showColumn('updatedAt')"/>
<el-table-column label="操作" width="160">
<el-table-column label="操作" width="200">
<template #default="scope">
<el-button type="primary" size="small" icon="view" title="详情" @click="handlePreview(scope.row)"></el-button>
<el-button
v-if="scope.row.status === 0"
type="warning"
size="small"
icon="edit"
title="审核"
v-hasPermi="['tusercertifications:review']"
@click="handleReview(scope.row)"></el-button>
<el-button type="success" size="small" icon="edit" title="编辑" v-hasPermi="['tusercertifications:edit']" @click="handleUpdate(scope.row)"></el-button>
<el-button type="danger" size="small" icon="delete" title="删除" v-hasPermi="['tusercertifications:delete']" @click="handleDelete(scope.row)"></el-button>
</template>
@ -140,13 +148,42 @@
<el-button type="primary" :loading="state.submitLoading" @click="submitForm">{{ $t('btn.submit') }}</el-button>
</template>
</el-dialog>
<!-- 审核弹窗 -->
<el-dialog title="审核认证申请" :lock-scroll="false" v-model="reviewDialogOpen" width="500px">
<el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="100px">
<el-form-item label="审核结果" prop="status">
<el-radio-group v-model="reviewForm.status">
<el-radio :label="1">通过</el-radio>
<el-radio :label="2">拒绝</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="reviewForm.status === 2"
label="拒绝原因"
prop="rejectReason">
<el-input
v-model="reviewForm.rejectReason"
type="textarea"
:rows="4"
placeholder="请输入拒绝原因"
maxlength="500"
show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<el-button text @click="closeReviewDialog">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" :loading="reviewSubmitLoading" @click="submitReview">{{ $t('btn.submit') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="tusercertifications">
import { listtusercertifications,
addtusercertifications, deltusercertifications,
updatetusercertifications,gettusercertifications,
updatetusercertifications,gettusercertifications,
reviewcertification,
}
from '@/api/liveforum/tusercertifications.js'
const { proxy } = getCurrentInstance()
@ -395,5 +432,90 @@ function handleExport() {
})
}
/*************** 审核相关方法 ***************/
//
const reviewDialogOpen = ref(false)
const reviewFormRef = ref()
const reviewSubmitLoading = ref(false)
const reviewForm = reactive({
id: null,
status: 1, // 1-2-
rejectReason: '',
})
const reviewRules = {
status: [{ required: true, message: "请选择审核结果", trigger: "change" }],
rejectReason: [
{
required: true,
message: "拒绝原因不能为空",
trigger: "blur",
validator: (rule, value, callback) => {
if (reviewForm.status === 2 && (!value || value.trim() === '')) {
callback(new Error("拒绝原因不能为空"))
} else {
callback()
}
}
}
],
}
//
function handleReview(row) {
resetReviewForm()
reviewForm.id = row.id
reviewDialogOpen.value = true
}
//
function resetReviewForm() {
reviewForm.id = null
reviewForm.status = 1
reviewForm.rejectReason = ''
if (reviewFormRef.value) {
reviewFormRef.value.resetFields()
}
}
//
function submitReview() {
reviewFormRef.value.validate((valid) => {
if (valid) {
//
if (reviewForm.status === 2 && (!reviewForm.rejectReason || reviewForm.rejectReason.trim() === '')) {
proxy.$modal.msgError("拒绝原因不能为空")
return
}
reviewSubmitLoading.value = true
const submitData = {
id: reviewForm.id,
status: reviewForm.status,
rejectReason: reviewForm.status === 2 ? reviewForm.rejectReason : null,
}
reviewcertification(submitData).then((res) => {
const { code, msg } = res
if (code == 200) {
proxy.$modal.msgSuccess("审核成功")
reviewDialogOpen.value = false
getList()
} else {
proxy.$modal.msgError(msg || "审核失败")
}
})
.finally(() => {
reviewSubmitLoading.value = false
})
}
})
}
//
function closeReviewDialog() {
reviewDialogOpen.value = false
resetReviewForm()
}
handleQuery()
</script>