Files
yuezi-saas/client/src/views/my/Complaints.vue
T

109 lines
4.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { showToast } from 'vant'
import { complaintApi } from '@/api/index'
const router = useRouter()
const list = ref([])
const loading = ref(true)
const showForm = ref(false)
const submitting = ref(false)
const form = ref({ type: '', content: '' })
const typeOptions = [
{ text: '服务质量', value: '服务质量' },
{ text: '餐饮问题', value: '餐饮问题' },
{ text: '环境卫生', value: '环境卫生' },
{ text: '其他', value: '其他' },
]
const statusLabel = { 0: '待处理', 1: '处理中', 2: '已解决', 3: '已关闭' }
const statusColor = { 0: 'warning', 1: 'primary', 2: 'success', 3: 'default' }
const typeLabel = { 1: '服务质量', 2: '餐饮问题', 3: '环境卫生', 4: '其他' }
onMounted(fetchList)
async function fetchList() {
loading.value = true
try {
const res = await complaintApi.list()
list.value = res.data?.data?.list || []
} catch { } finally { loading.value = false }
}
async function submit() {
if (!form.value.type || !form.value.content) {
showToast('请填写投诉类型和内容')
return
}
submitting.value = true
try {
// 后端 complaints.type 是 tinyInteger,这里把中文选项映射为数字
const typeMap = { '服务质量': 1, '餐饮问题': 2, '环境卫生': 3, '其他': 4 }
const payload = {
...form.value,
type: typeMap[form.value.type] ?? form.value.type,
}
await complaintApi.create(payload)
showToast({ type: 'success', message: '提交成功' })
showForm.value = false
form.value = { type: '', content: '' }
fetchList()
} catch { showToast('提交失败') } finally { submitting.value = false }
}
</script>
<template>
<div class="page">
<van-nav-bar title="投诉反馈" left-arrow @click-left="router.back()">
<template #right>
<van-icon name="plus" size="18" color="#e8718d" @click="showForm = true" />
</template>
</van-nav-bar>
<div class="content">
<van-loading v-if="loading" vertical color="#e8718d" class="center-load" />
<van-empty v-else-if="!list.length" description="暂无投诉记录" image="comment-o" />
<div v-else>
<div v-for="item in list" :key="item.id" class="item-card">
<div class="item-header">
<span class="item-type">{{ typeLabel[item.type] || '其他' }}</span>
<van-tag :type="statusColor[item.status] || 'default'" size="small">{{ statusLabel[item.status] || '待处理' }}</van-tag>
</div>
<p class="item-content">{{ item.content }}</p>
<p class="item-time">{{ item.created_at?.slice(0, 16) }}</p>
<div v-if="item.reply" class="item-reply">
<span class="reply-label">回复</span>{{ item.reply }}
</div>
</div>
</div>
</div>
<!-- 提交表单 -->
<van-popup v-model:show="showForm" round position="bottom" :style="{ padding: '24px 16px 40px' }">
<h3 class="popup-title">提交投诉反馈</h3>
<van-cell-group inset style="margin-top:8px">
<van-field label="类型" v-model="form.type" placeholder="如:服务质量 / 餐饮问题" />
<van-field label="内容" v-model="form.content" type="textarea" placeholder="请详细描述您的问题..." :rows="4" />
</van-cell-group>
<van-button block round type="primary" color="linear-gradient(135deg,#f5a0b0,#e8718d)" style="margin-top:16px" :loading="submitting" @click="submit">提交</van-button>
</van-popup>
</div>
</template>
<style scoped>
.page { background: #f8f0f5; min-height: 100vh; }
.content { padding: 16px; }
.center-load { display: flex; justify-content: center; padding: 60px 0; }
.item-card { background: white; border-radius: 16px; padding: 16px; margin-bottom: 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.04); }
.item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.item-type { font-size: 14px; font-weight: 600; color: #333; }
.item-content { font-size: 13px; color: #555; margin: 0 0 6px; line-height: 1.5; }
.item-time { font-size: 11px; color: #999; margin: 0; }
.item-reply { margin-top: 8px; padding: 8px; background: #f5f5f5; border-radius: 8px; font-size: 12px; color: #555; }
.reply-label { color: #e8718d; font-weight: 600; }
.popup-title { font-size: 16px; font-weight: 600; text-align: center; margin: 0 0 16px; }
</style>