265 lines
5.1 KiB
Vue
265 lines
5.1 KiB
Vue
<template>
|
||||
|
|
<view class="feedback-detail-page" :class="`theme-${themeMode}`">
|
|||
|
|
<view v-if="loading" class="loading-state">正在加载反馈详情…</view>
|
|||
|
|
<view v-else-if="feedback" class="detail-card">
|
|||
|
|
<view class="detail-header">
|
|||
|
|
<view>
|
|||
|
|
<text class="detail-type">{{ getTypeLabel(feedback.type) }}</text>
|
|||
|
|
<text class="detail-time">{{ feedback.created_date || '时间未知' }}</text>
|
|||
|
|
</view>
|
|||
|
|
<u-icon name="chat" color="#ff8a3d" size="40" />
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="detail-section">
|
|||
|
|
<text class="detail-label">问题描述</text>
|
|||
|
|
<text class="detail-content">{{ feedback.content || '/' }}</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="detail-section">
|
|||
|
|
<text class="detail-label">联系方式</text>
|
|||
|
|
<text class="detail-content">{{ feedback.contact || '未填写' }}</text>
|
|||
|
|
</view>
|
|||
|
|
<view v-if="imageList.length" class="detail-section">
|
|||
|
|
<text class="detail-label">截图附件</text>
|
|||
|
|
<view class="image-list">
|
|||
|
|
<image v-for="image in imageList" :key="image" :src="image" mode="aspectFill" @tap="previewImage(image)" />
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view v-if="feedback.reply_content" class="reply-card">
|
|||
|
|
<view class="reply-header">
|
|||
|
|
<text class="reply-title">管理员回复</text>
|
|||
|
|
<text class="reply-time">{{ feedback.reply_date || '' }}</text>
|
|||
|
|
</view>
|
|||
|
|
<text class="reply-content">{{ feedback.reply_content }}</text>
|
|||
|
|
<text v-if="feedback.reply_name" class="reply-admin">回复人:{{ feedback.reply_name }}</text>
|
|||
|
|
</view>
|
|||
|
|
<view v-else class="pending-reply">该反馈暂未收到回复,请耐心等待。</view>
|
|||
|
|
</view>
|
|||
|
|
<u-empty v-else mode="data" text="反馈记录不存在" icon="data" />
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import { getMyFeedbackDetail } from '@/api/feedback.js'
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
loading: true,
|
|||
|
|
feedback: null,
|
|||
|
|
feedbackId: ''
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
computed: {
|
|||
|
|
imageList() {
|
|||
|
|
return Array.isArray(this.feedback?.images)
|
|||
|
|
? this.feedback.images.filter((image) => typeof image === 'string' && image)
|
|||
|
|
: []
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
onLoad(options) {
|
|||
|
|
this.feedbackId = String(options?.id || '')
|
|||
|
|
this.loadFeedbackDetail()
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
getTypeLabel(type) {
|
|||
|
|
return {
|
|||
|
|
bug: '功能异常',
|
|||
|
|
suggestion: '体验建议',
|
|||
|
|
correction: '内容纠错'
|
|||
|
|
}[type] || '问题反馈'
|
|||
|
|
},
|
|||
|
|
async loadFeedbackDetail() {
|
|||
|
|
if (!this.feedbackId) {
|
|||
|
|
this.loading = false
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
this.loading = true
|
|||
|
|
try {
|
|||
|
|
this.feedback = await getMyFeedbackDetail(this.feedbackId)
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('[scanapp] 获取反馈详情失败', error)
|
|||
|
|
this.feedback = null
|
|||
|
|
} finally {
|
|||
|
|
this.loading = false
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
previewImage(current) {
|
|||
|
|
uni.previewImage({
|
|||
|
|
current,
|
|||
|
|
urls: this.imageList
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.feedback-detail-page {
|
|||
|
|
min-height: 100vh;
|
|||
|
|
padding: 28rpx 24rpx 48rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
background: #f4f6fb;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.loading-state {
|
|||
|
|
padding: 80rpx 0;
|
|||
|
|
color: #7d8798;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-card {
|
|||
|
|
padding: 34rpx;
|
|||
|
|
border-radius: 28rpx;
|
|||
|
|
background: #ffffff;
|
|||
|
|
box-shadow: 0 16rpx 40rpx rgba(23, 35, 61, 0.06);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-header {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
padding-bottom: 28rpx;
|
|||
|
|
border-bottom: 1rpx solid #edf0f5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-type,
|
|||
|
|
.detail-time,
|
|||
|
|
.detail-label,
|
|||
|
|
.detail-content {
|
|||
|
|
display: block;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-type {
|
|||
|
|
color: #ff8a3d;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-time {
|
|||
|
|
margin-top: 10rpx;
|
|||
|
|
color: #7d8798;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-section {
|
|||
|
|
padding-top: 28rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-label {
|
|||
|
|
color: #7d8798;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-content {
|
|||
|
|
margin-top: 12rpx;
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.image-list {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
margin-top: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.image-list image {
|
|||
|
|
width: 180rpx;
|
|||
|
|
height: 180rpx;
|
|||
|
|
margin-right: 14rpx;
|
|||
|
|
margin-bottom: 14rpx;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reply-card {
|
|||
|
|
margin-top: 32rpx;
|
|||
|
|
padding: 24rpx;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
background: #fff8f2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reply-header {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reply-title {
|
|||
|
|
color: #d86c2d;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reply-time,
|
|||
|
|
.reply-admin {
|
|||
|
|
color: #8b735f;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reply-content {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 14rpx;
|
|||
|
|
color: #3e3128;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reply-admin {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 14rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.pending-reply {
|
|||
|
|
margin-top: 32rpx;
|
|||
|
|
padding: 24rpx;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
color: #7d8798;
|
|||
|
|
background: #f3f5f8;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark.feedback-detail-page {
|
|||
|
|
background: #151923;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .detail-card {
|
|||
|
|
background: #222936;
|
|||
|
|
box-shadow: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .detail-header {
|
|||
|
|
border-color: #364152;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .detail-content {
|
|||
|
|
color: #f2f5fa;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .detail-label,
|
|||
|
|
.theme-dark .detail-time,
|
|||
|
|
.theme-dark .loading-state {
|
|||
|
|
color: #aeb9ca;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .reply-card {
|
|||
|
|
background: #34291f;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .reply-content {
|
|||
|
|
color: #f2e6da;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .reply-time,
|
|||
|
|
.theme-dark .reply-admin,
|
|||
|
|
.theme-dark .pending-reply {
|
|||
|
|
color: #c7b8a8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .pending-reply {
|
|||
|
|
background: #1c2431;
|
|||
|
|
}
|
|||
|
|
</style>
|