fix:修复投诉与建议图片多文件上传bug
This commit is contained in:
+118
-47
@@ -12,11 +12,22 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 标题 -->
|
||||
<view class="title-section">
|
||||
<text class="title-text">{{ detail.title || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 问题描述 -->
|
||||
<view class="content-section">
|
||||
<view class="content-text">{{ detail.content || '-' }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 联系电话 -->
|
||||
<view class="contact-section" v-if="detail.phone">
|
||||
<text class="contact-label">{{ $t('feedback.contactPhone') }}</text>
|
||||
<text class="contact-value">{{ detail.phone }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 上传图片 -->
|
||||
<view class="image-section" v-if="getImageList(detail).length > 0">
|
||||
<view class="image-list">
|
||||
@@ -39,14 +50,14 @@
|
||||
<view class="divider-line"></view>
|
||||
</view>
|
||||
<view class="reply-list">
|
||||
<view class="reply-item" v-for="(reply, index) in allReplies" :key="index"
|
||||
<view class="reply-item" v-for="(reply, index) in allReplies" :key="reply.id || index"
|
||||
:class="{ 'reply-platform': reply.isPlatform, 'reply-user': !reply.isPlatform }">
|
||||
<view class="reply-avatar" :class="{ 'avatar-platform': reply.isPlatform, 'avatar-user': !reply.isPlatform }">
|
||||
<text class="avatar-text">{{ reply.isPlatform ? '平台' : '我' }}</text>
|
||||
</view>
|
||||
<view class="reply-content-wrapper">
|
||||
<view class="reply-name-time">
|
||||
<text class="reply-name">{{ reply.isPlatform ? $t('feedback.platform') : $t('feedback.me') }}</text>
|
||||
<text class="reply-name">{{ reply.senderName || (reply.isPlatform ? $t('feedback.platform') : $t('feedback.me')) }}</text>
|
||||
<text class="reply-time">{{ formatTime(reply.createTime) }}</text>
|
||||
</view>
|
||||
<view class="reply-content">{{ reply.content || '-' }}</view>
|
||||
@@ -56,7 +67,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 底部输入框 -->
|
||||
<view class="bottom-input-bar" v-if="detail.status === 'processing'">
|
||||
<view class="bottom-input-bar" v-if="canSendMessage">
|
||||
<view class="input-wrapper">
|
||||
<textarea class="reply-input" v-model="replyContent" :placeholder="$t('feedback.replyPlaceholder')"
|
||||
maxlength="500" :auto-height="true"></textarea>
|
||||
@@ -71,14 +82,16 @@
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted
|
||||
onMounted,
|
||||
computed
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
getFeedbackDetail,
|
||||
submitFeedbackReply
|
||||
getFeedbackMessages,
|
||||
sendFeedbackMessage
|
||||
} from '../../config/api/feedback.js';
|
||||
import {
|
||||
useI18n
|
||||
@@ -97,12 +110,15 @@
|
||||
|
||||
// 初始化状态
|
||||
const detail = ref({});
|
||||
const replyList = ref([]);
|
||||
const userReplyList = ref([]);
|
||||
const allReplies = ref([]);
|
||||
const replyContent = ref('');
|
||||
const feedbackId = ref('');
|
||||
|
||||
const canSendMessage = computed(() => {
|
||||
const status = detail.value?.status
|
||||
return ['pending', 'in_progress'].includes(status)
|
||||
})
|
||||
|
||||
// 页面加载
|
||||
onLoad(async (options) => {
|
||||
if (options.id) {
|
||||
@@ -119,33 +135,49 @@
|
||||
}
|
||||
});
|
||||
|
||||
// 加载详情
|
||||
const loadDetail = async () => {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: $t('common.loading')
|
||||
const normalizeMessages = (messages = []) => {
|
||||
return (messages || [])
|
||||
.map(message => ({
|
||||
...message,
|
||||
isPlatform: message.senderType === 'staff' || message.senderType === 'platform' || message.isPlatform === true
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const timeA = new Date(a.createTime || 0).getTime();
|
||||
const timeB = new Date(b.createTime || 0).getTime();
|
||||
return timeA - timeB;
|
||||
});
|
||||
}
|
||||
|
||||
const loadMessages = async (initialMessages) => {
|
||||
try {
|
||||
if (Array.isArray(initialMessages)) {
|
||||
allReplies.value = normalizeMessages(initialMessages);
|
||||
return;
|
||||
}
|
||||
if (!feedbackId.value) return;
|
||||
const res = await getFeedbackMessages(feedbackId.value);
|
||||
if (res.code === 200) {
|
||||
allReplies.value = normalizeMessages(res.data || []);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取对话消息失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 加载详情
|
||||
const loadDetail = async (options = {}) => {
|
||||
const shouldShowLoading = options.showLoading !== false;
|
||||
try {
|
||||
if (shouldShowLoading) {
|
||||
uni.showLoading({
|
||||
title: $t('common.loading')
|
||||
});
|
||||
}
|
||||
|
||||
const res = await getFeedbackDetail(feedbackId.value);
|
||||
if (res.code === 200 && res.data) {
|
||||
detail.value = res.data;
|
||||
|
||||
// 分离平台回复和用户回复
|
||||
const replies = res.data.replies || res.data.replyList || [];
|
||||
replyList.value = replies.filter(reply => reply.replyType === 'platform' || reply.isPlatform);
|
||||
userReplyList.value = replies.filter(reply => reply.replyType === 'user' || !reply.isPlatform);
|
||||
|
||||
// 合并所有回复并按时间排序
|
||||
allReplies.value = replies
|
||||
.map(reply => ({
|
||||
...reply,
|
||||
isPlatform: reply.replyType === 'platform' || reply.isPlatform === true
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const timeA = new Date(a.createTime || 0).getTime();
|
||||
const timeB = new Date(b.createTime || 0).getTime();
|
||||
return timeA - timeB;
|
||||
});
|
||||
await loadMessages(res.data.messages);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || $t('feedback.getDetailFailed'),
|
||||
@@ -165,7 +197,9 @@
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
if (shouldShowLoading) {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -184,8 +218,7 @@
|
||||
title: $t('common.submitting')
|
||||
});
|
||||
|
||||
const res = await submitFeedbackReply({
|
||||
feedbackId: feedbackId.value,
|
||||
const res = await sendFeedbackMessage(feedbackId.value, {
|
||||
content: replyContent.value.trim()
|
||||
});
|
||||
|
||||
@@ -195,8 +228,10 @@
|
||||
icon: 'success'
|
||||
});
|
||||
replyContent.value = '';
|
||||
// 重新加载详情
|
||||
await loadDetail();
|
||||
// 重新加载详情和对话
|
||||
await loadDetail({
|
||||
showLoading: false
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || $t('feedback.replyFailed'),
|
||||
@@ -217,9 +252,9 @@
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
'processing': $t('feedback.processing'),
|
||||
'completed': $t('feedback.completed'),
|
||||
'pending': $t('feedback.pending')
|
||||
'pending': $t('feedback.pending'),
|
||||
'in_progress': $t('feedback.processing'),
|
||||
'resolved': $t('feedback.completed')
|
||||
};
|
||||
return statusMap[status] || $t('feedback.pending');
|
||||
};
|
||||
@@ -227,9 +262,9 @@
|
||||
// 获取状态样式类
|
||||
const getStatusClass = (status) => {
|
||||
const classMap = {
|
||||
'processing': 'status-processing',
|
||||
'completed': 'status-completed',
|
||||
'pending': 'status-pending'
|
||||
'pending': 'status-pending',
|
||||
'in_progress': 'status-processing',
|
||||
'resolved': 'status-completed'
|
||||
};
|
||||
return classMap[status] || 'status-pending';
|
||||
};
|
||||
@@ -270,14 +305,17 @@
|
||||
|
||||
// 获取图片列表(支持字符串或数组)
|
||||
const getImageList = (item) => {
|
||||
if (!item || !item.picturePath) return [];
|
||||
if (Array.isArray(item.picturePath)) return item.picturePath;
|
||||
if (typeof item.picturePath === 'string') {
|
||||
// 如果是逗号分隔的字符串,拆分为数组
|
||||
if (item.picturePath.includes(',')) {
|
||||
return item.picturePath.split(',').filter(img => img.trim());
|
||||
if (!item) return [];
|
||||
const pictureSource = item.pictureUrls ?? item.picturePath;
|
||||
if (!pictureSource) return [];
|
||||
if (Array.isArray(pictureSource)) {
|
||||
return pictureSource.filter(img => !!img);
|
||||
}
|
||||
if (typeof pictureSource === 'string') {
|
||||
if (pictureSource.includes(',')) {
|
||||
return pictureSource.split(',').map(img => img.trim()).filter(img => img);
|
||||
}
|
||||
return [item.picturePath];
|
||||
return pictureSource.trim() ? [pictureSource.trim()] : [];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
@@ -362,6 +400,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 标题
|
||||
.title-section {
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.title-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #111;
|
||||
}
|
||||
}
|
||||
|
||||
// 问题描述
|
||||
.content-section {
|
||||
margin-bottom: 20rpx;
|
||||
@@ -374,6 +423,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 联系方式
|
||||
.contact-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 16rpx;
|
||||
background: #fafafa;
|
||||
border-radius: 12rpx;
|
||||
|
||||
.contact-label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.contact-value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片区域
|
||||
.image-section {
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
Reference in New Issue
Block a user