|
@@ -0,0 +1,405 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="resource-list-container">
|
|
|
|
|
+ <h2 class="page-title">线索管理</h2>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 工具栏 -->
|
|
|
|
|
+ <el-card shadow="never" class="toolbar-card">
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="24">
|
|
|
|
|
+ <el-space wrap>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="filters.name"
|
|
|
|
|
+ placeholder="名称"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ style="width: 200px"
|
|
|
|
|
+ @keyup.enter="loadList"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="filters.phone"
|
|
|
|
|
+ placeholder="手机号"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ style="width: 200px"
|
|
|
|
|
+ @keyup.enter="loadList"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="filters.status"
|
|
|
|
|
+ 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-select
|
|
|
|
|
+ v-model="filters.diploma"
|
|
|
|
|
+ placeholder="学历"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ style="width: 150px"
|
|
|
|
|
+ @change="loadList"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option label="高中" value="高中" />
|
|
|
|
|
+ <el-option label="专科" value="专科" />
|
|
|
|
|
+ <el-option label="本科" value="本科" />
|
|
|
|
|
+ <el-option label="硕士" value="硕士" />
|
|
|
|
|
+ <el-option label="博士" value="博士" />
|
|
|
|
|
+ <el-option label="无" value="无" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="filters.marrStatus"
|
|
|
|
|
+ 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 type="primary" icon="Search" @click="loadList">查询</el-button>
|
|
|
|
|
+ <el-button icon="Refresh" @click="resetFilters">重置</el-button>
|
|
|
|
|
+ </el-space>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </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>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <el-table-column type="index" label="序号" width="60" />
|
|
|
|
|
+ <el-table-column prop="name" label="名称" width="120" />
|
|
|
|
|
+ <el-table-column prop="phone" label="手机号" width="130" />
|
|
|
|
|
+ <el-table-column prop="backupPhone" label="备用手机号" width="130" />
|
|
|
|
|
+ <el-table-column prop="age" label="年龄" width="80" align="center" />
|
|
|
|
|
+ <el-table-column prop="gender" label="性别" width="80" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>{{ row.gender === 1 ? '男' : row.gender === 2 ? '女' : '-' }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="height" label="身高(cm)" width="100" align="center" />
|
|
|
|
|
+ <el-table-column prop="diploma" label="学历" width="100" align="center" />
|
|
|
|
|
+ <el-table-column prop="marrStatus" label="婚姻状况" width="100" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <span>{{ getMarrStatusText(row.marrStatus) }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="occupation" label="职业" width="120" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column prop="address" label="住址" min-width="150" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column prop="status" label="审核状态" width="120" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag :type="getStatusType(row.status)" size="small">
|
|
|
|
|
+ {{ getStatusText(row.status) }}
|
|
|
|
|
+ </el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="createTime" label="创建时间" width="180" />
|
|
|
|
|
+ <el-table-column label="操作" width="150" fixed="right">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ link
|
|
|
|
|
+ @click="handleDetail(row)"
|
|
|
|
|
+ >
|
|
|
|
|
+ 详情
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ link
|
|
|
|
|
+ @click="handleAudit(row)"
|
|
|
|
|
+ >
|
|
|
|
|
+ 审核
|
|
|
|
|
+ </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"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div v-if="auditData" style="margin-bottom: 20px;">
|
|
|
|
|
+ <el-descriptions :column="1" border>
|
|
|
|
|
+ <el-descriptions-item label="名称">{{ auditData.name }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="手机号">{{ auditData.phone }}</el-descriptions-item>
|
|
|
|
|
+ </el-descriptions>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-form :model="auditForm" label-width="100px">
|
|
|
|
|
+ <el-form-item label="审核结果" required>
|
|
|
|
|
+ <el-radio-group v-model="auditForm.status">
|
|
|
|
|
+ <el-radio :label="1">审核通过</el-radio>
|
|
|
|
|
+ <el-radio :label="2">审核失败</el-radio>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item
|
|
|
|
|
+ label="失败原因"
|
|
|
|
|
+ v-if="auditForm.status === 2"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="auditForm.rejectReason"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="4"
|
|
|
|
|
+ placeholder="请输入审核失败原因"
|
|
|
|
|
+ maxlength="200"
|
|
|
|
|
+ show-word-limit
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="auditDialogVisible = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="submitAudit" :loading="auditLoading">确定</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 详情弹框 -->
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ v-model="detailDialogVisible"
|
|
|
|
|
+ title="线索详情"
|
|
|
|
|
+ width="800px"
|
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-descriptions :column="2" border v-if="detailData">
|
|
|
|
|
+ <el-descriptions-item label="资源ID">{{ detailData.resourceId }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="红娘ID">{{ detailData.matchmakerId }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="名称">{{ detailData.name }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="手机号">{{ detailData.phone }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="备用手机号">{{ detailData.backupPhone || '-' }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="年龄">{{ detailData.age }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="性别">
|
|
|
|
|
+ {{ detailData.gender === 1 ? '男' : detailData.gender === 2 ? '女' : '-' }}
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="身高">{{ detailData.height }}cm</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="体重">{{ detailData.weight }}kg</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="星座">{{ detailData.constellation || '-' }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="学历">{{ detailData.diploma || '-' }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="婚姻状况">{{ getMarrStatusText(detailData.marrStatus) }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="收入">{{ detailData.income || '-' }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="职业">{{ detailData.occupation || '-' }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="住址">{{ detailData.address || '-' }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="户籍所在地">{{ detailData.domicile || '-' }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="购房">
|
|
|
|
|
+ {{ detailData.house === 1 ? '有' : detailData.house === 0 ? '无' : '-' }}
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="购车">
|
|
|
|
|
+ {{ detailData.car === 1 ? '有' : detailData.car === 0 ? '无' : '-' }}
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="审核状态">
|
|
|
|
|
+ <el-tag :type="getStatusType(detailData.status)" size="small">
|
|
|
|
|
+ {{ getStatusText(detailData.status) }}
|
|
|
|
|
+ </el-tag>
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="审核失败原因" :span="2" v-if="detailData.rejectReason">
|
|
|
|
|
+ {{ detailData.rejectReason }}
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="择偶标准" :span="2">
|
|
|
|
|
+ {{ detailData.mateSelectionCriteria || '-' }}
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="创建时间">{{ detailData.createTime }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="更新时间">{{ detailData.updateTime }}</el-descriptions-item>
|
|
|
|
|
+ </el-descriptions>
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="detailDialogVisible = false">关闭</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { ref, reactive, onMounted } from 'vue'
|
|
|
|
|
+import { ElMessage } 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 currentPage = ref(1)
|
|
|
|
|
+const pageSize = ref(10)
|
|
|
|
|
+const total = ref(0)
|
|
|
|
|
+const list = ref([])
|
|
|
|
|
+
|
|
|
|
|
+const filters = reactive({
|
|
|
|
|
+ name: '',
|
|
|
|
|
+ phone: '',
|
|
|
|
|
+ status: null,
|
|
|
|
|
+ diploma: null,
|
|
|
|
|
+ marrStatus: null
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const detailDialogVisible = ref(false)
|
|
|
|
|
+const detailData = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+const auditDialogVisible = ref(false)
|
|
|
|
|
+const auditData = ref(null)
|
|
|
|
|
+const auditLoading = ref(false)
|
|
|
|
|
+const auditForm = reactive({
|
|
|
|
|
+ status: 1,
|
|
|
|
|
+ rejectReason: ''
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const loadList = async () => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ page: currentPage.value,
|
|
|
|
|
+ pageSize: pageSize.value
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (filters.name && filters.name.trim()) {
|
|
|
|
|
+ params.name = filters.name.trim()
|
|
|
|
|
+ }
|
|
|
|
|
+ if (filters.phone && filters.phone.trim()) {
|
|
|
|
|
+ params.phone = filters.phone.trim()
|
|
|
|
|
+ }
|
|
|
|
|
+ if (filters.status !== null && filters.status !== undefined) {
|
|
|
|
|
+ params.status = filters.status
|
|
|
|
|
+ }
|
|
|
|
|
+ if (filters.diploma && filters.diploma.trim()) {
|
|
|
|
|
+ params.diploma = filters.diploma.trim()
|
|
|
|
|
+ }
|
|
|
|
|
+ if (filters.marrStatus !== null && filters.marrStatus !== undefined) {
|
|
|
|
|
+ params.marrStatus = filters.marrStatus
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const response = await request.get(API_ENDPOINTS.MY_RESOURCE_LIST, { params })
|
|
|
|
|
+
|
|
|
|
|
+ if (response.code === 200) {
|
|
|
|
|
+ const data = response.data || {}
|
|
|
|
|
+ list.value = data.list || data.records || []
|
|
|
|
|
+ total.value = data.total || 0
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response.message || response.msg || '加载失败')
|
|
|
|
|
+ list.value = []
|
|
|
|
|
+ total.value = 0
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载失败:', error)
|
|
|
|
|
+ ElMessage.error('加载失败: ' + (error.message || '未知错误'))
|
|
|
|
|
+ list.value = []
|
|
|
|
|
+ total.value = 0
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const resetFilters = () => {
|
|
|
|
|
+ filters.name = ''
|
|
|
|
|
+ filters.phone = ''
|
|
|
|
|
+ filters.status = null
|
|
|
|
|
+ filters.diploma = null
|
|
|
|
|
+ filters.marrStatus = null
|
|
|
|
|
+ currentPage.value = 1
|
|
|
|
|
+ loadList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getStatusText = (status) => {
|
|
|
|
|
+ const texts = { 0: '待审核', 1: '审核通过', 2: '审核失败' }
|
|
|
|
|
+ return texts[status] || '未知'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getStatusType = (status) => {
|
|
|
|
|
+ const types = { 0: 'warning', 1: 'success', 2: 'danger' }
|
|
|
|
|
+ return types[status] || ''
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getMarrStatusText = (marrStatus) => {
|
|
|
|
|
+ const texts = { 0: '未婚', 1: '离异', 2: '丧偶' }
|
|
|
|
|
+ return texts[marrStatus] || '-'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleDetail = async (row) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await request.get(`${API_ENDPOINTS.MY_RESOURCE_DETAIL}/${row.resourceId}`)
|
|
|
|
|
+ if (response.code === 200) {
|
|
|
|
|
+ detailData.value = response.data
|
|
|
|
|
+ detailDialogVisible.value = true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response.message || response.msg || '获取详情失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取详情失败:', error)
|
|
|
|
|
+ ElMessage.error('获取详情失败: ' + (error.message || '未知错误'))
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleAudit = (row) => {
|
|
|
|
|
+ auditData.value = row
|
|
|
|
|
+ auditForm.status = 1
|
|
|
|
|
+ auditForm.rejectReason = ''
|
|
|
|
|
+ auditDialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const submitAudit = async () => {
|
|
|
|
|
+ if (!auditData.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (auditForm.status === 2 && !auditForm.rejectReason.trim()) {
|
|
|
|
|
+ ElMessage.warning('请填写审核失败原因')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ auditLoading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ status: auditForm.status
|
|
|
|
|
+ }
|
|
|
|
|
+ if (auditForm.status === 2 && auditForm.rejectReason.trim()) {
|
|
|
|
|
+ params.rejectReason = auditForm.rejectReason.trim()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const response = await request.put(
|
|
|
|
|
+ `${API_ENDPOINTS.MY_RESOURCE_AUDIT}/${auditData.value.resourceId}/audit`,
|
|
|
|
|
+ null,
|
|
|
|
|
+ { params }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if (response.code === 200) {
|
|
|
|
|
+ ElMessage.success(response.message || response.msg || '审核成功')
|
|
|
|
|
+ auditDialogVisible.value = false
|
|
|
|
|
+ loadList()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response.message || response.msg || '审核失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('审核失败:', error)
|
|
|
|
|
+ ElMessage.error('审核失败: ' + (error.message || '未知错误'))
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ auditLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => loadList())
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+@import '@/assets/list-common.css';
|
|
|
|
|
+
|
|
|
|
|
+.resource-list-container {
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|
|
|
|
|
+
|