yeg
2 天以前 d8eaa16682cf180e9563d6be05fb43057daf6c07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { Plus, Refresh, Search } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { createDisplayService, getDisplayServiceCategories, getDisplayServiceDetail, getDisplayServices, updateDisplayService, updateDisplayServiceSort, updateDisplayServiceStatus } from '../api/admin'
 
const loading = ref(false)
const rows = ref<Record<string, any>[]>([])
const categories = ref<Record<string, any>[]>([])
const dialogVisible = ref(false)
const editingId = ref<number | string | null>(null)
const filters = reactive({ keyword: '', category: '', status: undefined as number | undefined })
const pagination = reactive({ page: 1, size: 10, total: 0 })
const form = reactive({ merchantName: '', category: '', contactName: '', contactMobile: '', address: '', logoUrl: '', coverUrl: '', serviceLabel: '', rightsText: '', handlingInstructions: '', sortNo: 0, status: 1, recommend: 0, cardPolicies: [] as any[] })
async function loadCategories() { try { categories.value = await getDisplayServiceCategories() } catch { categories.value = [] } }
async function loadData() { loading.value = true; try { const result = await getDisplayServices({ page: pagination.page, size: pagination.size, keyword: filters.keyword || undefined, category: filters.category || undefined, status: filters.status }); 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: '', category: '', status: undefined }); search() }
function resetForm(row?: Record<string, any>) { editingId.value = row?.serviceId || row?.id || null; Object.assign(form, { merchantName: row?.merchantName || '', category: row?.category || '', contactName: row?.contactName || '', contactMobile: row?.contactMobile || '', address: row?.address || '', logoUrl: row?.logoUrl || '', coverUrl: row?.coverUrl || '', serviceLabel: row?.serviceLabel || '', rightsText: row?.rightsText || '', handlingInstructions: row?.handlingInstructions || '', sortNo: Number(row?.sortNo || 0), status: Number(row?.status ?? 1), recommend: Number(row?.recommend ?? 0), cardPolicies: row?.cardPolicies || [] }) }
function openCreate() { resetForm(); dialogVisible.value = true }
async function openEdit(row: Record<string, any>) { const detail = await getDisplayServiceDetail(row.serviceId || row.id); resetForm(detail); dialogVisible.value = true }
async function save() { if (editingId.value) await updateDisplayService(editingId.value, form); else await createDisplayService(form); ElMessage.success('保存成功'); dialogVisible.value = false; await loadData() }
async function toggleStatus(row: Record<string, any>) { await updateDisplayServiceStatus(row.serviceId || row.id, Number(row.status) === 1 ? 0 : 1); ElMessage.success('状态已更新'); await loadData() }
async function changeSort(row: Record<string, any>) { await updateDisplayServiceSort(row.serviceId || row.id, Number(row.sortNo || 0)); ElMessage.success('排序已更新'); await loadData() }
onMounted(async () => { await loadCategories(); await loadData() })
</script>
<template>
  <div class="page-stack">
    <div class="toolbar"><div><h2>展示类服务管理</h2><p>维护停车、体检、购房、购车、家电、公寓租赁等展示服务。</p></div><div class="toolbar-actions"><el-button :icon="Refresh" :loading="loading" @click="loadData">刷新</el-button><el-button type="primary" :icon="Plus" @click="openCreate">新增服务</el-button></div></div>
    <section class="panel">
      <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 label="分类"><el-select v-model="filters.category" clearable placeholder="全部"><el-option label="全部" value="" /><el-option v-for="item in categories" :key="item.key || item.categoryKey" :label="item.name || item.categoryLabel" :value="item.key || item.categoryKey" /></el-select></el-form-item><el-form-item label="状态"><el-select v-model="filters.status" clearable placeholder="全部"><el-option label="上架" :value="1" /><el-option label="下架" :value="0" /></el-select></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-loading="loading" :data="rows" border empty-text="暂无展示服务数据"><el-table-column prop="merchantName" label="服务名称" min-width="150" /><el-table-column prop="categoryName" label="分类" min-width="120" /><el-table-column prop="contactName" label="联系人" min-width="100" /><el-table-column prop="contactMobile" label="联系电话" min-width="130" /><el-table-column prop="address" label="地址" min-width="170" show-overflow-tooltip /><el-table-column prop="sortNo" label="排序" min-width="80" /><el-table-column label="状态" min-width="90"><template #default="{ row }">{{ Number(row.status) === 1 ? '上架' : '下架' }}</template></el-table-column><el-table-column label="操作" width="240" fixed="right"><template #default="{ row }"><el-button link type="primary" @click="openEdit(row)">编辑</el-button><el-button link type="primary" @click="toggleStatus(row)">{{ Number(row.status) === 1 ? '下架' : '上架' }}</el-button><el-button link type="primary" @click="changeSort(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="dialogVisible" title="展示类服务" width="760px"><el-form :model="form" label-width="110px"><el-form-item label="服务名称"><el-input v-model="form.merchantName" /></el-form-item><el-form-item label="分类"><el-select v-model="form.category"><el-option v-for="item in categories" :key="item.key || item.categoryKey" :label="item.name || item.categoryLabel" :value="item.key || item.categoryKey" /></el-select></el-form-item><el-form-item label="联系人"><el-input v-model="form.contactName" /></el-form-item><el-form-item label="联系电话"><el-input v-model="form.contactMobile" /></el-form-item><el-form-item label="地址"><el-input v-model="form.address" /></el-form-item><el-form-item label="封面图"><el-input v-model="form.coverUrl" /></el-form-item><el-form-item label="服务标签"><el-input v-model="form.serviceLabel" /></el-form-item><el-form-item label="权益说明"><el-input v-model="form.rightsText" type="textarea" :rows="4" /></el-form-item><el-form-item label="办理说明"><el-input v-model="form.handlingInstructions" type="textarea" :rows="4" /></el-form-item><el-form-item label="排序"><el-input-number v-model="form.sortNo" :min="0" /></el-form-item><el-form-item label="推荐"><el-switch v-model="form.recommend" :active-value="1" :inactive-value="0" /></el-form-item><el-form-item label="状态"><el-switch v-model="form.status" :active-value="1" :inactive-value="0" /></el-form-item></el-form><template #footer><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="save">保存</el-button></template></el-dialog>
  </div>
</template>