231 lines
7.5 KiB
Vue
231 lines
7.5 KiB
Vue
<template>
|
|||
|
|
<el-container class="review-page">
|
||
|
|
<el-header class="header">
|
||
|
|
<h2>资料审核</h2>
|
||
|
|
<el-tag type="warning" v-if="stats.pending > 0">待审核 {{ stats.pending }}</el-tag>
|
||
|
|
<el-tag type="info" v-if="stats.processing > 0">审核中 {{ stats.processing }}</el-tag>
|
||
|
|
</el-header>
|
||
|
|
|
||
|
|
<el-main>
|
||
|
|
<el-tabs v-model="activeTab">
|
||
|
|
<el-tab-pane label="待审核队列" name="pending">
|
||
|
|
<el-table :data="pendingTasks" v-loading="loading">
|
||
|
|
<el-table-column prop="userId" label="用户ID" width="120" />
|
||
|
|
<el-table-column prop="reviewType" label="审核类型" width="120" />
|
||
|
|
<el-table-column prop="submittedAt" label="提交时间" width="180">
|
||
|
|
<template #default="{ row }">
|
||
|
|
{{ formatTime(row.submittedAt) }}
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
<el-table-column label="操作" width="120">
|
||
|
|
<template #default="{ row }">
|
||
|
|
<el-button type="primary" size="small" @click="handleClaim(row)">领取</el-button>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
</el-table>
|
||
|
|
<el-empty v-if="!loading && pendingTasks.length === 0" description="暂无待审核任务" />
|
||
|
|
</el-tab-pane>
|
||
|
|
|
||
|
|
<el-tab-pane label="我的审核" name="my">
|
||
|
|
<el-table :data="myTasks" v-loading="loading">
|
||
|
|
<el-table-column prop="userId" label="用户ID" width="120" />
|
||
|
|
<el-table-column prop="status" label="状态" width="100">
|
||
|
|
<template #default="{ row }">
|
||
|
|
<el-tag :type="statusType(row.status)">{{ statusText(row.status) }}</el-tag>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
<el-table-column prop="completedAt" label="完成时间" width="180">
|
||
|
|
<template #default="{ row }">
|
||
|
|
{{ row.completedAt ? formatTime(row.completedAt) : '-' }}
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
<el-table-column label="操作" width="120">
|
||
|
|
<template #default="{ row }">
|
||
|
|
<el-button size="small" @click="handleView(row)">查看</el-button>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
</el-table>
|
||
|
|
</el-tab-pane>
|
||
|
|
</el-tabs>
|
||
|
|
</el-main>
|
||
|
|
|
||
|
|
<!-- 审核详情抽屉 -->
|
||
|
|
<el-drawer v-model="detailVisible" title="审核详情" size="500px">
|
||
|
|
<template v-if="currentTask">
|
||
|
|
<el-descriptions :column="1" border>
|
||
|
|
<el-descriptions-item label="用户ID">{{ currentTask.userId }}</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="审核类型">{{ currentTask.reviewType }}</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="提交时间">{{ formatTime(currentTask.submittedAt) }}</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="当前状态">
|
||
|
|
<el-tag :type="statusType(currentTask.status)">{{ statusText(currentTask.status) }}</el-tag>
|
||
|
|
</el-descriptions-item>
|
||
|
|
</el-descriptions>
|
||
|
|
|
||
|
|
<el-divider>用户资料</el-divider>
|
||
|
|
<el-descriptions :column="2" border v-if="currentTask.userProfile">
|
||
|
|
<el-descriptions-item label="姓名">{{ currentTask.userProfile.displayName }}</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="性别">{{ currentTask.userProfile.gender }}</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="年龄">{{ currentTask.userProfile.age }}岁</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="身高">{{ currentTask.userProfile.heightCm }}cm</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="婚姻状况">{{ currentTask.userProfile.maritalStatus }}</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="学历">{{ currentTask.userProfile.educationCode }}</el-descriptions-item>
|
||
|
|
<el-descriptions-item label="自我介绍" :span="2">
|
||
|
|
{{ currentTask.userProfile.selfIntro || '暂未填写' }}
|
||
|
|
</el-descriptions-item>
|
||
|
|
</el-descriptions>
|
||
|
|
|
||
|
|
<el-divider>审核操作</el-divider>
|
||
|
|
<el-form :model="reviewForm" label-width="80px">
|
||
|
|
<el-form-item label="审核意见">
|
||
|
|
<el-input v-model="reviewForm.comment" type="textarea" :rows="3" placeholder="请输入审核意见" />
|
||
|
|
</el-form-item>
|
||
|
|
<el-form-item label="审核原因">
|
||
|
|
<el-select v-model="reviewForm.reasonCodes" multiple placeholder="可选" style="width:100%">
|
||
|
|
<el-option
|
||
|
|
v-for="reason in reasonOptions"
|
||
|
|
:key="reason.code"
|
||
|
|
:label="reason.name"
|
||
|
|
:value="reason.code"
|
||
|
|
/>
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
<el-form-item>
|
||
|
|
<el-button type="success" @click="handleApprove" :loading="submitting">通过</el-button>
|
||
|
|
<el-button type="warning" @click="handleNeedEdit" :loading="submitting">需修改</el-button>
|
||
|
|
<el-button type="danger" @click="handleReject" :loading="submitting">拒绝</el-button>
|
||
|
|
</el-form-item>
|
||
|
|
</el-form>
|
||
|
|
</template>
|
||
|
|
</el-drawer>
|
||
|
|
</el-container>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref, onMounted } from 'vue'
|
||
|
|
import { ElMessage } from 'element-plus'
|
||
|
|
|
||
|
|
const activeTab = ref('pending')
|
||
|
|
const loading = ref(false)
|
||
|
|
const submitting = ref(false)
|
||
|
|
const detailVisible = ref(false)
|
||
|
|
const stats = ref({ pending: 0, processing: 0 })
|
||
|
|
const pendingTasks = ref<any[]>([])
|
||
|
|
const myTasks = ref<any[]>([])
|
||
|
|
const currentTask = ref<any>(null)
|
||
|
|
const reasonOptions = ref<any[]>([])
|
||
|
|
|
||
|
|
const reviewForm = ref({
|
||
|
|
comment: '',
|
||
|
|
reasonCodes: [] as string[]
|
||
|
|
})
|
||
|
|
|
||
|
|
async function loadStats() {
|
||
|
|
// TODO: Phase 05 实现真实API调用
|
||
|
|
stats.value = { pending: 12, processing: 3 }
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatTime(ts?: string) {
|
||
|
|
if (!ts) return '-'
|
||
|
|
return new Date(ts).toLocaleString('zh-CN')
|
||
|
|
}
|
||
|
|
|
||
|
|
function statusType(status: string) {
|
||
|
|
const map: Record<string, string> = {
|
||
|
|
pending: 'warning',
|
||
|
|
processing: 'info',
|
||
|
|
approved: 'success',
|
||
|
|
need_edit: 'warning',
|
||
|
|
rejected: 'danger'
|
||
|
|
}
|
||
|
|
return map[status] || ''
|
||
|
|
}
|
||
|
|
|
||
|
|
function statusText(status: string) {
|
||
|
|
const map: Record<string, string> = {
|
||
|
|
pending: '待审核',
|
||
|
|
processing: '审核中',
|
||
|
|
approved: '已通过',
|
||
|
|
need_edit: '需修改',
|
||
|
|
rejected: '已拒绝'
|
||
|
|
}
|
||
|
|
return map[status] || status
|
||
|
|
}
|
||
|
|
|
||
|
|
function handleClaim(_row: any) {
|
||
|
|
// TODO: 调用 API 领取
|
||
|
|
ElMessage.success('领取成功')
|
||
|
|
}
|
||
|
|
|
||
|
|
function handleView(row: any) {
|
||
|
|
currentTask.value = row
|
||
|
|
detailVisible.value = true
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleApprove() {
|
||
|
|
submitting.value = true
|
||
|
|
try {
|
||
|
|
// TODO: 调用 API
|
||
|
|
ElMessage.success('审核通过')
|
||
|
|
detailVisible.value = false
|
||
|
|
await loadStats()
|
||
|
|
} finally {
|
||
|
|
submitting.value = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleNeedEdit() {
|
||
|
|
submitting.value = true
|
||
|
|
try {
|
||
|
|
ElMessage.success('已标记需修改')
|
||
|
|
detailVisible.value = false
|
||
|
|
await loadStats()
|
||
|
|
} finally {
|
||
|
|
submitting.value = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleReject() {
|
||
|
|
submitting.value = true
|
||
|
|
try {
|
||
|
|
ElMessage.success('已拒绝')
|
||
|
|
detailVisible.value = false
|
||
|
|
await loadStats()
|
||
|
|
} finally {
|
||
|
|
submitting.value = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
loadStats()
|
||
|
|
})
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.review-page {
|
||
|
|
height: 100vh;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
}
|
||
|
|
|
||
|
|
.header {
|
||
|
|
background: #fff;
|
||
|
|
padding: 16px 24px;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 16px;
|
||
|
|
border-bottom: 1px solid #e4e7ed;
|
||
|
|
}
|
||
|
|
|
||
|
|
.header h2 {
|
||
|
|
margin: 0;
|
||
|
|
font-size: 18px;
|
||
|
|
color: #303133;
|
||
|
|
}
|
||
|
|
|
||
|
|
.el-main {
|
||
|
|
flex: 1;
|
||
|
|
padding: 20px;
|
||
|
|
overflow: auto;
|
||
|
|
}
|
||
|
|
</style>
|