<script setup lang="ts">
|
import { onMounted, reactive, ref } from 'vue'
|
import { Refresh, Search } from '@element-plus/icons-vue'
|
import { ElMessage } from 'element-plus'
|
import { auditCarWashCredential, getCarWashCredentials, getCarWashJumpConfigs, rollbackCarWashCredential, saveCarWashJumpConfig } from '../api/admin'
|
|
const activeTab = ref('configs')
|
const loading = ref(false)
|
const rows = ref<Record<string, any>[]>([])
|
const filters = reactive({ keyword: '', status: undefined as number | undefined, dateRange: [] as string[] })
|
const pagination = reactive({ page: 1, size: 10, total: 0 })
|
const configDialogVisible = ref(false)
|
const configForm = reactive({ merchantId: '', externalLinkType: 'miniProgram', externalMiniProgramAppId: '', externalMiniProgramPath: '', externalWebUrl: '', status: 1 })
|
const statusOptions = [{ label: '待审核', value: 0 }, { label: '已通过', value: 1 }, { label: '已驳回', value: 2 }, { label: '已回滚', value: 3 }]
|
// 后端返回 ISO 时间(2026-09-01T11:29:35),列表统一显示成 "2026-09-01 11:29:35"。
|
function formatDateTime(value?: string) { return typeof value === 'string' && value ? value.replace('T', ' ').slice(0, 19) : '' }
|
async function loadData() { loading.value = true; try { if (activeTab.value === 'configs') { const result = await getCarWashJumpConfigs({ page: pagination.page, size: pagination.size, keyword: filters.keyword || undefined }); rows.value = result.records || []; pagination.total = result.total || 0 } else { const result = await getCarWashCredentials({ page: pagination.page, size: pagination.size, keyword: filters.keyword || undefined, status: filters.status, startDate: filters.dateRange?.[0], endDate: filters.dateRange?.[1] }); rows.value = result.records || []; pagination.total = result.total || 0 } } finally { loading.value = false } }
|
function search() { pagination.page = 1; loadData() }
|
function resetFilters() { Object.assign(filters, { keyword: '', status: undefined, dateRange: [] }); search() }
|
function switchTab() { pagination.page = 1; rows.value = []; loadData() }
|
function openConfig(row: Record<string, any>) { Object.assign(configForm, { merchantId: row.merchantId || row.id, externalLinkType: row.externalLinkType || 'none', externalMiniProgramAppId: row.externalMiniProgramAppId || '', externalMiniProgramPath: row.externalMiniProgramPath || '', externalWebUrl: row.externalWebUrl || '', status: Number(row.serviceStatus ?? row.status ?? 1) }); configDialogVisible.value = true }
|
async function saveConfig() { await saveCarWashJumpConfig(configForm.merchantId, { externalLinkType: configForm.externalLinkType, externalMiniProgramAppId: configForm.externalMiniProgramAppId, externalMiniProgramPath: configForm.externalMiniProgramPath, externalWebUrl: configForm.externalWebUrl, status: configForm.status }); ElMessage.success('保存成功'); configDialogVisible.value = false; await loadData() }
|
async function audit(row: Record<string, any>, status: number) { await auditCarWashCredential(row.id, status, status === 1 ? '后台审核通过' : '后台审核驳回'); ElMessage.success('审核完成'); await loadData() }
|
async function rollback(row: Record<string, any>) { await rollbackCarWashCredential(row.id, '后台回滚权益次数'); ElMessage.success('已回滚'); await loadData() }
|
onMounted(loadData)
|
</script>
|
<template>
|
<div class="page-stack">
|
<div class="toolbar"><div><h2>洗车权益管理</h2><p>维护洗车第三方跳转配置,查看凭证并人工审核/回滚权益次数。</p></div><el-button :icon="Refresh" :loading="loading" @click="loadData">刷新</el-button></div>
|
<section class="panel">
|
<el-tabs v-model="activeTab" @tab-change="switchTab"><el-tab-pane label="跳转配置" name="configs" /><el-tab-pane label="凭证审核" name="credentials" /></el-tabs>
|
<el-form class="filter-form" :model="filters" label-width="84px"><el-form-item label="关键词"><el-input v-model="filters.keyword" clearable placeholder="商家、地址、手机号、凭证编号" /></el-form-item><el-form-item v-if="activeTab === 'credentials'" label="状态"><el-select v-model="filters.status" clearable placeholder="全部"><el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-form-item><el-form-item v-if="activeTab === 'credentials'" label="日期"><el-date-picker v-model="filters.dateRange" type="daterange" value-format="YYYY-MM-DD" /></el-form-item><div class="toolbar-actions"><el-button type="primary" :icon="Search" @click="search">查询</el-button><el-button :icon="Refresh" @click="resetFilters">重置</el-button></div></el-form>
|
<el-table v-if="activeTab === 'configs'" v-loading="loading" :data="rows" border empty-text="暂无跳转配置"><el-table-column prop="merchantId" label="商户ID" width="100" /><el-table-column prop="merchantName" label="商户名称" min-width="160" /><el-table-column prop="externalLinkType" label="跳转类型" min-width="110" /><el-table-column prop="externalMiniProgramAppId" label="小程序AppId" min-width="160" /><el-table-column prop="externalMiniProgramPath" label="小程序路径" min-width="200" show-overflow-tooltip /><el-table-column prop="externalWebUrl" label="网页地址" min-width="200" show-overflow-tooltip /><el-table-column label="状态" width="90"><template #default="{ row }">{{ Number(row.serviceStatus ?? row.status) === 1 ? '启用' : '停用' }}</template></el-table-column><el-table-column label="操作" width="120" fixed="right"><template #default="{ row }"><el-button link type="primary" @click="openConfig(row)">配置</el-button></template></el-table-column></el-table>
|
<el-table v-else v-loading="loading" :data="rows" border empty-text="暂无洗车凭证"><el-table-column prop="credentialNo" label="凭证编号" min-width="130" /><el-table-column prop="talentName" label="持卡人" min-width="110" /><el-table-column prop="talentMobile" label="手机号" min-width="120" /><el-table-column prop="merchantName" label="商户" min-width="150" /><el-table-column prop="submitTime" label="提交时间" min-width="170"><template #default="{ row }">{{ formatDateTime(row.submitTime) }}</template></el-table-column><el-table-column prop="statusText" label="状态" min-width="110" /><el-table-column label="操作" width="210" fixed="right"><template #default="{ row }"><el-button link type="primary" @click="audit(row, 1)">通过</el-button><el-button link type="danger" @click="audit(row, 2)">驳回</el-button><el-button link type="warning" @click="rollback(row)">回滚</el-button></template></el-table-column></el-table>
|
<div class="pagination-row"><el-pagination v-model:current-page="pagination.page" v-model:page-size="pagination.size" background layout="total, prev, pager, next" :total="pagination.total" @change="loadData" /></div>
|
</section>
|
<el-dialog v-model="configDialogVisible" title="洗车跳转配置" width="620px"><el-form :model="configForm" label-width="130px"><el-form-item label="商户ID"><el-input v-model="configForm.merchantId" disabled /></el-form-item><el-form-item label="跳转类型"><el-select v-model="configForm.externalLinkType"><el-option label="第三方小程序" value="miniProgram" /><el-option label="网页" value="web" /><el-option label="不跳转" value="none" /></el-select></el-form-item><el-form-item label="小程序AppId"><el-input v-model="configForm.externalMiniProgramAppId" /></el-form-item><el-form-item label="小程序路径"><el-input v-model="configForm.externalMiniProgramPath" /></el-form-item><el-form-item label="网页地址"><el-input v-model="configForm.externalWebUrl" /></el-form-item><el-form-item label="状态"><el-switch v-model="configForm.status" :active-value="1" :inactive-value="0" /></el-form-item></el-form><template #footer><el-button @click="configDialogVisible = false">取消</el-button><el-button type="primary" @click="saveConfig">保存</el-button></template></el-dialog>
|
</div>
|
</template>
|