|
|
@@ -0,0 +1,359 @@
|
|
|
+<template>
|
|
|
+ <div class="case-audit-container">
|
|
|
+ <h2 class="page-title">案例审核</h2>
|
|
|
+
|
|
|
+ <el-card shadow="never" class="toolbar-card">
|
|
|
+ <el-space wrap>
|
|
|
+ <el-input
|
|
|
+ v-model="filters.maleRealName"
|
|
|
+ placeholder="按男方姓名模糊搜索"
|
|
|
+ clearable
|
|
|
+ style="width: 200px"
|
|
|
+ @keyup.enter="loadList"
|
|
|
+ >
|
|
|
+ <template #append>
|
|
|
+ <el-button icon="Search" @click="loadList" />
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ <el-input
|
|
|
+ v-model="filters.femaleRealName"
|
|
|
+ placeholder="按女方姓名模糊搜索"
|
|
|
+ clearable
|
|
|
+ style="width: 200px"
|
|
|
+ @keyup.enter="loadList"
|
|
|
+ >
|
|
|
+ <template #append>
|
|
|
+ <el-button icon="Search" @click="loadList" />
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ <el-select
|
|
|
+ v-model="filters.auditStatus"
|
|
|
+ placeholder="审核状态"
|
|
|
+ clearable
|
|
|
+ style="width: 150px"
|
|
|
+ @change="loadList"
|
|
|
+ >
|
|
|
+ <el-option label="待审核" :value="0" />
|
|
|
+ <el-option label="审核通过" :value="1" />
|
|
|
+ <el-option label="审核失败" :value="2" />
|
|
|
+ </el-select>
|
|
|
+ <el-button icon="Refresh" @click="resetFilters">重置</el-button>
|
|
|
+ </el-space>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-card shadow="never" class="table-card">
|
|
|
+ <el-table v-loading="loading" :data="list" stripe>
|
|
|
+ <template #empty>
|
|
|
+ <div class="custom-empty-state">
|
|
|
+ <el-icon class="empty-icon"><Document /></el-icon>
|
|
|
+ <div class="empty-text">暂无案例记录</div>
|
|
|
+ <div class="empty-hint">等待红娘上传成功案例后在此审核</div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-table-column type="index" label="序号" width="60" />
|
|
|
+ <el-table-column prop="maleRealName" label="男方姓名" min-width="120">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="data-highlight">{{ row.maleRealName || '-' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="femaleRealName" label="女方姓名" min-width="120">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="data-highlight">{{ row.femaleRealName || '-' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="caseType" label="案例类型" width="100" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tag size="small" :type="row.caseType === 1 ? 'success' : 'warning'">
|
|
|
+ {{ row.caseType === 1 ? '订婚' : row.caseType === 2 ? '领证结婚' : '-' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="caseDate" label="成功日期" width="120" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="text-muted">{{ formatDate(row.caseDate) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="auditStatus" label="审核状态" width="120" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tag
|
|
|
+ size="small"
|
|
|
+ :type="getAuditStatusType(row.auditStatus)"
|
|
|
+ effect="light"
|
|
|
+ >
|
|
|
+ {{ getAuditStatusText(row.auditStatus) }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="auditRemark" label="审核备注" min-width="200" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="text-muted">{{ row.auditRemark || '-' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="createdAt" label="上传时间" width="180">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="text-muted">{{ formatDateTime(row.createdAt) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="updatedAt" label="更改时间" width="180">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="text-muted">{{ formatDateTime(row.updatedAt) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="auditedAt" label="审核时间" width="180">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="text-muted">{{ formatDateTime(row.auditedAt) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="auditDuration" label="审核耗时" width="120" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span v-if="row.auditDuration" class="data-highlight">{{ row.auditDuration }}</span>
|
|
|
+ <span v-else style="color: #999;">-</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="120" fixed="right">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="handleAudit(row)"
|
|
|
+ :disabled="row.auditStatus === 1 || row.auditStatus === 2"
|
|
|
+ >
|
|
|
+ 审核
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <div class="pagination-container">
|
|
|
+ <el-pagination
|
|
|
+ v-model:current-page="currentPage"
|
|
|
+ v-model:page-size="pageSize"
|
|
|
+ :total="total"
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ @size-change="loadList"
|
|
|
+ @current-change="loadList"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 审核弹框 -->
|
|
|
+ <el-dialog
|
|
|
+ v-model="auditDialogVisible"
|
|
|
+ title="案例审核"
|
|
|
+ width="500px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <el-form :model="auditForm" label-width="100px">
|
|
|
+ <el-form-item label="男方姓名">
|
|
|
+ <span>{{ currentRow?.maleRealName || '-' }}</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="女方姓名">
|
|
|
+ <span>{{ currentRow?.femaleRealName || '-' }}</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="审核操作" required>
|
|
|
+ <el-radio-group v-model="auditForm.action">
|
|
|
+ <el-radio :label="1">审核通过</el-radio>
|
|
|
+ <el-radio :label="2">审核不通过</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item
|
|
|
+ v-if="auditForm.action === 2"
|
|
|
+ label="审核备注"
|
|
|
+ required
|
|
|
+ :rules="[{ required: true, message: '请输入审核备注', trigger: 'blur' }]"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="auditForm.auditRemark"
|
|
|
+ type="textarea"
|
|
|
+ :rows="4"
|
|
|
+ placeholder="请输入审核不通过的原因(失败原因)"
|
|
|
+ maxlength="500"
|
|
|
+ show-word-limit
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="auditDialogVisible = false">取消</el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="submitAudit"
|
|
|
+ :loading="auditing"
|
|
|
+ :disabled="auditForm.action === 2 && !auditForm.auditRemark?.trim()"
|
|
|
+ >
|
|
|
+ 确定
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, reactive, onMounted } from 'vue'
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+import { Document } from '@element-plus/icons-vue'
|
|
|
+import request from '@/utils/request'
|
|
|
+import { API_ENDPOINTS } from '@/config/api'
|
|
|
+
|
|
|
+const loading = ref(false)
|
|
|
+const list = ref([])
|
|
|
+const total = ref(0)
|
|
|
+const currentPage = ref(1)
|
|
|
+const pageSize = ref(10)
|
|
|
+const auditing = ref(false)
|
|
|
+const auditDialogVisible = ref(false)
|
|
|
+const currentRow = ref(null)
|
|
|
+
|
|
|
+const filters = reactive({
|
|
|
+ maleRealName: '',
|
|
|
+ femaleRealName: '',
|
|
|
+ auditStatus: null
|
|
|
+})
|
|
|
+
|
|
|
+const auditForm = reactive({
|
|
|
+ action: 1, // 1-通过, 2-不通过
|
|
|
+ auditRemark: ''
|
|
|
+})
|
|
|
+
|
|
|
+const loadList = async () => {
|
|
|
+ loading.value = true
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ page: currentPage.value,
|
|
|
+ pageSize: pageSize.value
|
|
|
+ }
|
|
|
+ if (filters.maleRealName && filters.maleRealName.trim()) {
|
|
|
+ params.maleRealName = filters.maleRealName.trim()
|
|
|
+ }
|
|
|
+ if (filters.femaleRealName && filters.femaleRealName.trim()) {
|
|
|
+ params.femaleRealName = filters.femaleRealName.trim()
|
|
|
+ }
|
|
|
+ if (filters.auditStatus !== null && filters.auditStatus !== undefined) {
|
|
|
+ params.auditStatus = filters.auditStatus
|
|
|
+ }
|
|
|
+ const res = await request.get(API_ENDPOINTS.SUCCESS_CASE_UPLOAD_LIST, { params })
|
|
|
+ if (res.code === 200) {
|
|
|
+ const data = res.data || {}
|
|
|
+ list.value = data.list || data.records || []
|
|
|
+ total.value = data.total || list.value.length
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载案例列表失败:', error)
|
|
|
+ ElMessage.error('加载案例列表失败')
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const resetFilters = () => {
|
|
|
+ filters.maleRealName = ''
|
|
|
+ filters.femaleRealName = ''
|
|
|
+ filters.auditStatus = null
|
|
|
+ currentPage.value = 1
|
|
|
+ loadList()
|
|
|
+}
|
|
|
+
|
|
|
+const getAuditStatusText = (status) => {
|
|
|
+ const statusMap = {
|
|
|
+ 0: '待审核',
|
|
|
+ 1: '审核通过',
|
|
|
+ 2: '审核失败'
|
|
|
+ }
|
|
|
+ return statusMap[status] || '未知'
|
|
|
+}
|
|
|
+
|
|
|
+const getAuditStatusType = (status) => {
|
|
|
+ const typeMap = {
|
|
|
+ 0: 'warning',
|
|
|
+ 1: 'success',
|
|
|
+ 2: 'danger'
|
|
|
+ }
|
|
|
+ return typeMap[status] || ''
|
|
|
+}
|
|
|
+
|
|
|
+const formatDate = (date) => {
|
|
|
+ if (!date) return '-'
|
|
|
+ const d = new Date(date)
|
|
|
+ return d.toLocaleDateString('zh-CN')
|
|
|
+}
|
|
|
+
|
|
|
+const formatDateTime = (date) => {
|
|
|
+ if (!date) return '-'
|
|
|
+ const d = new Date(date)
|
|
|
+ return d.toLocaleString('zh-CN', {
|
|
|
+ year: 'numeric',
|
|
|
+ month: '2-digit',
|
|
|
+ day: '2-digit',
|
|
|
+ hour: '2-digit',
|
|
|
+ minute: '2-digit'
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const handleAudit = (row) => {
|
|
|
+ if (row.auditStatus === 1 || row.auditStatus === 2) {
|
|
|
+ ElMessage.warning('该案例已审核,无需重复操作')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ currentRow.value = row
|
|
|
+ auditForm.action = 1
|
|
|
+ auditForm.auditRemark = ''
|
|
|
+ auditDialogVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+const submitAudit = async () => {
|
|
|
+ if (!currentRow.value) {
|
|
|
+ ElMessage.error('请选择要审核的案例')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (auditForm.action === 2 && !auditForm.auditRemark?.trim()) {
|
|
|
+ ElMessage.warning('审核不通过时,必须填写审核备注')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ auditing.value = true
|
|
|
+ let res
|
|
|
+
|
|
|
+ if (auditForm.action === 1) {
|
|
|
+ // 审核通过
|
|
|
+ res = await request.post(
|
|
|
+ `${API_ENDPOINTS.SUCCESS_CASE_UPLOAD_APPROVE}/${currentRow.value.id}`
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ // 审核不通过
|
|
|
+ res = await request.post(
|
|
|
+ `${API_ENDPOINTS.SUCCESS_CASE_UPLOAD_REJECT}/${currentRow.value.id}`,
|
|
|
+ {
|
|
|
+ auditRemark: auditForm.auditRemark.trim()
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ if (res.code === 200) {
|
|
|
+ ElMessage.success(auditForm.action === 1 ? '审核通过成功' : '审核不通过操作成功')
|
|
|
+ auditDialogVisible.value = false
|
|
|
+ loadList()
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg || '审核操作失败')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('审核操作失败:', error)
|
|
|
+ ElMessage.error(error.response?.data?.msg || error.message || '审核操作失败')
|
|
|
+ } finally {
|
|
|
+ auditing.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(loadList)
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+@import '@/assets/list-common.css';
|
|
|
+
|
|
|
+.case-audit-container {
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|