<script setup>
|
import { onMounted, reactive, ref } from 'vue'
|
import { useRouter } from 'vue-router'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { Refresh, Search, Setting, View } from '@element-plus/icons-vue'
|
import { getGuideUsers, updateGuideUserStatus } from '@/api/users'
|
|
const router = useRouter()
|
const loading = ref(false)
|
const records = ref([])
|
const total = ref(0)
|
const dateRange = ref([])
|
const query = reactive({
|
page: 1,
|
size: 10,
|
keyword: '',
|
status: null,
|
rating: null,
|
teamType: null,
|
})
|
|
const formatDateTime = (value) => value ? value.replace('T', ' ').slice(0, 19) : '-'
|
const guideStatusMeta = (status) => ({
|
0: { label: '禁用', type: 'danger' },
|
1: { label: '启用', type: 'success' },
|
2: { label: '待审核', type: 'warning' },
|
3: { label: '已注销', type: 'info' },
|
}[status] || { label: '未知', type: 'info' })
|
|
const loadGuides = async () => {
|
loading.value = true
|
try {
|
const [startDate, endDate] = dateRange.value || []
|
const result = await getGuideUsers({
|
page: query.page,
|
size: query.size,
|
keyword: query.keyword.trim() || undefined,
|
status: query.status ?? undefined,
|
startDate,
|
endDate,
|
ratingLevel: query.rating || undefined,
|
teamType: query.teamType || undefined,
|
})
|
records.value = result.records
|
total.value = result.total
|
} finally {
|
loading.value = false
|
}
|
}
|
|
const search = () => { query.page = 1; loadGuides() }
|
const reset = () => {
|
Object.assign(query, { page: 1, size: 10, keyword: '', status: null, rating: null, teamType: null })
|
dateRange.value = []
|
loadGuides()
|
}
|
|
const changeStatus = async (guide) => {
|
const nextStatus = guide.status === 1 ? 0 : 1
|
const action = nextStatus === 1 ? '启用' : '禁用'
|
try {
|
await ElMessageBox.confirm(`确认${action}导游“${guide.realName || guide.username}”吗?`, `${action}导游`, {
|
type: 'warning', confirmButtonText: `确认${action}`, cancelButtonText: '取消',
|
})
|
await updateGuideUserStatus(guide.id, nextStatus)
|
ElMessage.success(`${action}成功`)
|
loadGuides()
|
} catch (error) {
|
if (error !== 'cancel' && error !== 'close') throw error
|
}
|
}
|
|
const changePage = (page) => { query.page = page; loadGuides() }
|
const changePageSize = (size) => { query.page = 1; query.size = size; loadGuides() }
|
|
onMounted(loadGuides)
|
</script>
|
|
<template>
|
<section class="guide-list-page">
|
<el-card class="query-card" shadow="never">
|
<h2>查询表格</h2>
|
<el-form class="query-form" label-position="left" label-width="72px" @submit.prevent="search">
|
<el-form-item label="导游搜索">
|
<el-input v-model="query.keyword" clearable placeholder="请输入导游手机号/姓名/编号" @keyup.enter="search" />
|
</el-form-item>
|
<el-form-item label="创建时间">
|
<el-date-picker v-model="dateRange" type="daterange" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
|
</el-form-item>
|
<el-form-item label="状态">
|
<el-select v-model="query.status" clearable placeholder="全部">
|
<el-option label="启用" :value="1" />
|
<el-option label="禁用" :value="0" />
|
<el-option label="已注销" :value="3" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="评分">
|
<el-select v-model="query.rating" clearable placeholder="全部">
|
<el-option label="4分及以上" value="high" />
|
<el-option label="3-4分" value="medium" />
|
<el-option label="3分以下" value="low" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="讲解队/个人">
|
<el-select v-model="query.teamType" clearable placeholder="全部">
|
<el-option label="个人" value="personal" /><el-option label="讲解队" value="team" />
|
</el-select>
|
</el-form-item>
|
<div class="query-actions">
|
<el-button type="primary" :icon="Search" @click="search">查询</el-button>
|
<el-button :icon="Refresh" @click="reset">重置</el-button>
|
</div>
|
</el-form>
|
</el-card>
|
|
<el-card class="table-card" shadow="never">
|
<div class="table-toolbar">
|
<el-button type="primary" :icon="Setting" @click="router.push('/guides/auto-disable')">自动禁用设置</el-button>
|
</div>
|
<el-table v-loading="loading" :data="records" border row-key="id">
|
<el-table-column prop="id" label="导游编号" width="105" align="center" />
|
<el-table-column prop="realName" label="导游姓名" min-width="110" align="center">
|
<template #default="{ row }">{{ row.realName || '-' }}</template>
|
</el-table-column>
|
<el-table-column prop="mobile" label="手机号" min-width="135" align="center">
|
<template #default="{ row }">{{ row.mobile || '-' }}</template>
|
</el-table-column>
|
<el-table-column label="注册时间" min-width="165" align="center">
|
<template #default="{ row }">{{ formatDateTime(row.createdAt) }}</template>
|
</el-table-column>
|
<el-table-column label="讲解队/个人" width="125" align="center">
|
<template #default="{ row }">{{ row.teamName || row.teamType }}</template>
|
</el-table-column>
|
<el-table-column prop="acceptedOrderCount" label="接单总数" width="105" align="center" />
|
<el-table-column prop="currentMonthOrderCount" label="本月接单" width="105" align="center" />
|
<el-table-column label="评分" width="90" align="center">
|
<template #default="{ row }">{{ Number(row.rating).toFixed(1) }}</template>
|
</el-table-column>
|
<el-table-column label="状态" width="90" align="center">
|
<template #default="{ row }">
|
<el-tag :type="guideStatusMeta(row.status).type" effect="plain">{{ guideStatusMeta(row.status).label }}</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" width="190" fixed="right" align="center">
|
<template #default="{ row }">
|
<el-button link type="primary" :icon="View" @click="router.push(`/guides/${row.id}`)">详情</el-button>
|
<el-button v-if="row.status === 0 || row.status === 1" link :type="row.status === 1 ? 'danger' : 'success'" @click="changeStatus(row)">{{ row.status === 1 ? '禁用' : '启用' }}</el-button>
|
</template>
|
</el-table-column>
|
<template #empty><el-empty description="暂无符合条件的导游" /></template>
|
</el-table>
|
|
<div class="pagination-row">
|
<span>共 {{ total }} 条</span>
|
<el-pagination
|
background
|
layout="sizes, prev, pager, next, jumper"
|
:current-page="query.page"
|
:page-size="query.size"
|
:page-sizes="[10, 20, 50]"
|
:total="total"
|
@current-change="changePage"
|
@size-change="changePageSize"
|
/>
|
</div>
|
</el-card>
|
</section>
|
</template>
|
|
<style scoped>
|
.guide-list-page { display: flex; flex-direction: column; gap: 18px; }
|
.query-card, .table-card { border: 0; border-radius: 4px; }
|
.query-card h2 { margin: 0 0 22px; color: #1f2937; font-size: 18px; }
|
.query-form { display: grid; grid-template-columns: 1fr 1fr 1fr auto; column-gap: 28px; }
|
.query-form :deep(.el-form-item) { margin-right: 0; }
|
.query-form :deep(.el-select), .query-form :deep(.el-date-editor) { width: 100%; }
|
.query-actions { display: flex; flex-direction: column; gap: 10px; grid-column: 4; grid-row: 1 / span 2; }
|
.table-toolbar { margin-bottom: 18px; }
|
.pagination-row { display: flex; justify-content: flex-end; align-items: center; gap: 18px; margin-top: 24px; }
|
.pagination-row > span { color: #64748b; font-size: 13px; }
|
</style>
|