后台增加撤销用户实名功能
实名姓名与收款账户不一致会导致收款码登记失败,新增后台撤销实名能力: - 新增 user:revoke_realname 权限,授予超级管理员与运营角色 - 撤销时重置用户实名状态为未认证并删除实名记录,使其可重新认证,写入审计日志 - 用户管理页新增实名状态列与"撤销实名"操作(含原因弹窗) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8192344027
commit
4d54f1b03a
@@ -7,6 +7,7 @@ import { reactive, ref } from 'vue'
|
||||
import {
|
||||
fetchAdminUsers,
|
||||
freezeAdminUser,
|
||||
revokeAdminUserRealname,
|
||||
setAdminUserDepositFreeQuota,
|
||||
unfreezeAdminUser,
|
||||
type AdminUserItem,
|
||||
@@ -14,14 +15,16 @@ import {
|
||||
} from '@/features/admin/api/adminUsers'
|
||||
import { centToYuan, formatCent, yuanToCent } from '@/shared/utils/money'
|
||||
import { useAdminPaginatedTable } from '@/features/admin/composables/useAdminPaginatedTable'
|
||||
import { userStatusLabel } from '@/shared/utils/statusLabels'
|
||||
import { realnameStatusLabel, userStatusLabel } from '@/shared/utils/statusLabels'
|
||||
import { formatDateTime } from '@/shared/utils/time'
|
||||
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||
|
||||
const submitting = ref(false)
|
||||
const activeUser = ref<AdminUserItem | null>(null)
|
||||
const quotaUser = ref<AdminUserItem | null>(null)
|
||||
const realnameUser = ref<AdminUserItem | null>(null)
|
||||
const freezeReason = ref('')
|
||||
const revokeRealnameReason = ref('')
|
||||
const quotaAmount = ref(0)
|
||||
|
||||
const filters = reactive<AdminUserQuery>({
|
||||
@@ -104,6 +107,26 @@ async function handleUnfreeze(row: AdminUserItem) {
|
||||
}
|
||||
}
|
||||
|
||||
function openRevokeRealname(row: AdminUserItem) {
|
||||
realnameUser.value = row
|
||||
revokeRealnameReason.value = ''
|
||||
}
|
||||
|
||||
async function handleRevokeRealname() {
|
||||
if (!realnameUser.value) return
|
||||
submitting.value = true
|
||||
try {
|
||||
await revokeAdminUserRealname(realnameUser.value.id, revokeRealnameReason.value)
|
||||
ElMessage.success('已撤销实名,用户可重新认证')
|
||||
realnameUser.value = null
|
||||
await loadUsers()
|
||||
} catch (error) {
|
||||
ElMessage.error(readError(error, '撤销实名失败'))
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function moneyCent(value: number | string | undefined) {
|
||||
return formatCent(Number(value || 0))
|
||||
}
|
||||
@@ -161,6 +184,9 @@ function moneyCent(value: number | string | undefined) {
|
||||
<el-table-column label="状态" width="110">
|
||||
<template #default="{ row }">{{ userStatusLabel(row.status) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实名状态" width="110">
|
||||
<template #default="{ row }">{{ realnameStatusLabel(row.realname_status) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="免押额度" width="130">
|
||||
<template #default="{ row }">¥{{ moneyCent(row.deposit_free_quota_cent) }}</template>
|
||||
</el-table-column>
|
||||
@@ -173,9 +199,18 @@ function moneyCent(value: number | string | undefined) {
|
||||
<el-table-column label="注册时间" min-width="180">
|
||||
<template #default="{ row }">{{ formatDateTime(row.created_at) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220">
|
||||
<el-table-column label="操作" width="320">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" @click="openDepositQuota(row)">免押</el-button>
|
||||
<el-button
|
||||
v-if="row.realname_status !== 'unverified'"
|
||||
size="small"
|
||||
type="warning"
|
||||
:loading="submitting"
|
||||
@click="openRevokeRealname(row)"
|
||||
>
|
||||
撤销实名
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.status === 'active'"
|
||||
size="small"
|
||||
@@ -229,6 +264,36 @@ function moneyCent(value: number | string | undefined) {
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:model-value="!!realnameUser"
|
||||
title="撤销实名认证"
|
||||
width="560px"
|
||||
@update:model-value="realnameUser = null"
|
||||
>
|
||||
<div v-if="realnameUser" class="dialog-body">
|
||||
<p>
|
||||
<strong>{{ realnameUser.phone }}</strong> · {{ realnameUser.nickname }}
|
||||
</p>
|
||||
<el-alert
|
||||
type="warning"
|
||||
:closable="false"
|
||||
title="撤销后该用户实名信息将被清除,需重新完成实名认证后才能下单与登记收款码。"
|
||||
/>
|
||||
<el-input
|
||||
v-model="revokeRealnameReason"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="填写撤销原因(如实名姓名与收款账户不一致),便于审计追踪"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="realnameUser = null">取消</el-button>
|
||||
<el-button type="warning" :loading="submitting" @click="handleRevokeRealname"
|
||||
>确认撤销</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:model-value="!!quotaUser"
|
||||
title="设置免押额度"
|
||||
|
||||
Reference in New Issue
Block a user