detail.vue 10.5 KB
<template>
	<view class="main">
		<view class="toptitle">
			<view class="toptitle_left" @click="ht">
				<u-icon name="arrow-left" color="#fff" size="20"></u-icon>
			</view>
			<view class="toptitle_title">
				反馈详情
			</view>
		</view>
		<!-- 设备问题反馈详情 -->
		<view class="box" v-if="detail.type === 'sbwtfk'">
			<view class="top2" v-if="detail.title">
				<span class="f4">设备名</span>
				<span class="f5">{{detail.title}}</span>
			</view>
			<view class="top2" v-if="detail.nr">
				<span class="f4">故障信息</span>
				<span class="f5">{{detail.nr}}</span>
			</view>
			<view class="top2" v-if="detail.sbmc">
				<span class="f4">设备名称</span>
				<span class="f5">{{detail.sbmc}}</span>
			</view>
			<view class="top2" v-if="detail.shry">
				<span class="f4">售后人员</span>
				<span class="f5">{{detail.shry}}</span>
			</view>
			<view class="top2" v-if="detail.shdh">
				<span class="f4">售后电话</span>
				<span class="f5">{{detail.shdh}}</span>
			</view>
			<view class="top2" v-if="detail.shyx">
				<span class="f4">售后邮箱</span>
				<span class="f5">{{detail.shyx}}</span>
			</view>
			<view class="top2" v-if="detail.fbsj">
				<span class="f4">提交时间</span>
				<span class="f5">{{timestampToTime(detail.fbsj)}}</span>
			</view>
			<view class="top2" v-if="detail.clr">
				<span class="f4">处理人</span>
				<span class="f5">{{detail.clr}}</span>
			</view>
			<view class="top2">
				<span class="f4">处理状态</span>
				<span class="f5" :style="{ color: getStatusColor(detail.cljg) }">{{detail.cljg == null ? '未处理' : detail.cljg}}</span>
			</view>
			<view class="top2" v-if="detail.fkjg">
				<span class="f4">反馈结果</span>
				<span class="f5">{{detail.fkjg}}</span>
			</view>
			
			<!-- 附件和图片 -->
			<view v-if="(detail.fj1 && detail.fj1.length > 0) || (detail.fj2 && detail.fj2.length > 0)" style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #e5e5e5;">
				<view class="top" style="margin-bottom: 15px;">
					<span class="f1">附件和图片</span>
				</view>
				<!-- 视频附件 -->
				<view v-if="detail.fj1 && detail.fj1.length > 0" style="margin-top: 10px;">
					<view style="margin-bottom: 10px; font-weight: bold;">视频附件:</view>
					<view v-for="(file, index) in detail.fj1" :key="index" style="display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom: 1px solid #e5e5e5;">
						<view style="display: flex; align-items: center; flex: 1;">
							<u-icon name="play-circle-fill" color="#0052D8" size="28" style="margin-right: 10px;"></u-icon>
							<text style="flex: 1;">{{file.name || '视频文件'}}</text>
						</view>
						<u-button size="small" type="primary" text="查看" @click="previewFile(file)"></u-button>
					</view>
				</view>
				<!-- 图片附件 -->
				<view v-if="detail.fj2 && detail.fj2.length > 0" style="margin-top: 10px;">
					<view style="margin-bottom: 10px; font-weight: bold;">图片附件:</view>
					<view style="display: flex; flex-wrap: wrap; gap: 10px;">
						<image 
							v-for="(img, index) in detail.fj2" 
							:key="index"
							:src="getFullUrl(img.url)" 
							mode="aspectFill"
							style="width: 30%; height: 200rpx; border-radius: 6px;"
							@click="previewImage(index)"
						></image>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 系统问题反馈详情 -->
		<view class="box" v-if="detail.type === 'xtwtfk'">
			<view class="top2" v-if="detail.qxgn">
				<span class="f4">问题分类</span>
				<span class="f5">{{detail.qxgn}}</span>
			</view>
			<view class="top2" v-if="detail.nr">
				<span class="f4">问题描述</span>
				<span class="f5">{{detail.nr}}</span>
			</view>
			<view class="top2" v-if="detail.clr">
				<span class="f4">对接人员</span>
				<span class="f5">{{detail.clr}}</span>
			</view>
			<view class="top2" v-if="detail.fbsj">
				<span class="f4">提交时间</span>
				<span class="f5">{{timestampToTime(detail.fbsj)}}</span>
			</view>
			<view class="top2">
				<span class="f4">处理状态</span>
				<span class="f5" :style="{ color: getStatusColor(detail.cljg) }">{{detail.cljg == null ? '未处理' : detail.cljg}}</span>
			</view>
			<view class="top2" v-if="detail.fkjg">
				<span class="f4">反馈结果</span>
				<span class="f5">{{detail.fkjg}}</span>
			</view>
			
			<!-- 附件和图片 -->
			<view v-if="(detail.fj1 && detail.fj1.length > 0) || (detail.fj2 && detail.fj2.length > 0)" style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #e5e5e5;">
				<view class="top" style="margin-bottom: 15px;">
					<span class="f1">附件和图片</span>
				</view>
				<!-- 视频附件 -->
				<view v-if="detail.fj1 && detail.fj1.length > 0" style="margin-top: 10px;">
					<view style="margin-bottom: 10px; font-weight: bold;">视频附件:</view>
					<view v-for="(file, index) in detail.fj1" :key="index" style="display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom: 1px solid #e5e5e5;">
						<view style="display: flex; align-items: center; flex: 1;">
							<u-icon name="play-circle-fill" color="#0052D8" size="28" style="margin-right: 10px;"></u-icon>
							<text style="flex: 1;">{{file.name || '视频文件'}}</text>
						</view>
						<u-button size="small" type="primary" text="查看" @click="previewFile(file)"></u-button>
					</view>
				</view>
				<!-- 图片附件 -->
				<view v-if="detail.fj2 && detail.fj2.length > 0" style="margin-top: 10px;">
					<view style="margin-bottom: 10px; font-weight: bold;">图片附件:</view>
					<view style="display: flex; flex-wrap: wrap; gap: 10px;">
						<image 
							v-for="(img, index) in detail.fj2" 
							:key="index"
							:src="getFullUrl(img.url)" 
							mode="aspectFill"
							style="width: 30%; height: 200rpx; border-radius: 6px;"
							@click="previewImage(index)"
						></image>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			detail: {},
			baseUrl: 'https://hhjj.antissoft.com'
		}
	},
	onLoad() {
		const detailStr = uni.getStorageSync('fkDetail');
		console.log('详情页加载,原始数据:', detailStr);
		if (detailStr) {
			try {
				this.detail = JSON.parse(detailStr);
				console.log('解析后的详情数据:', this.detail);
				
				// 确保附件字段是数组
				if (!Array.isArray(this.detail.fj1)) {
					// 如果 fj1 是字符串,尝试解析
					if (typeof this.detail.fj1 === 'string' && this.detail.fj1) {
						try {
							this.detail.fj1 = JSON.parse(this.detail.fj1);
						} catch (e) {
							console.warn('解析 fj1 JSON 失败:', e);
							this.detail.fj1 = [];
						}
					} else {
						this.detail.fj1 = [];
					}
				}
				if (!Array.isArray(this.detail.fj2)) {
					// 如果 fj2 是字符串,尝试解析
					if (typeof this.detail.fj2 === 'string' && this.detail.fj2) {
						try {
							this.detail.fj2 = JSON.parse(this.detail.fj2);
						} catch (e) {
							console.warn('解析 fj2 JSON 失败:', e);
							this.detail.fj2 = [];
						}
					} else {
						this.detail.fj2 = [];
					}
				}
				
				console.log('处理后的附件数据 - fj1(视频):', this.detail.fj1);
				console.log('处理后的附件数据 - fj2(图片):', this.detail.fj2);
				console.log('fj1 数量:', this.detail.fj1 ? this.detail.fj1.length : 0);
				console.log('fj2 数量:', this.detail.fj2 ? this.detail.fj2.length : 0);
			} catch (e) {
				console.error('解析详情数据失败:', e);
				this.detail = {};
			}
		} else {
			console.warn('未找到详情数据');
		}
	},
	methods: {
		ht() {
			uni.navigateBack({
				delta: 1
			});
		},
		timestampToTime(timestamp) {
			if (!timestamp) return '';
			const date = new Date(timestamp);
			const Y = date.getFullYear() + '-';
			const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
			const D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
			const h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
			const m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
			const s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
			return Y + M + D + h + m + s;
		},
		getStatusColor(cljg) {
			if (!cljg) return '#999';
			if (cljg.includes('已处理')) return '#67C23A';
			if (cljg.includes('进行中')) return '#E6A23C';
			if (cljg.includes('未处理')) return '#F56C6C';
			return '#999';
		},
		getFullUrl(url) {
			if (!url) return '';
			if (url.startsWith('http://') || url.startsWith('https://')) {
				return url;
			}
			return this.baseUrl + url;
		},
		previewImage(index) {
			const images = (this.detail.fj2 || []).map(img => this.getFullUrl(img.url));
			uni.previewImage({
				current: index,
				urls: images
			});
		},
		getFileType(file) {
			const raw = (file.name || file.url || '').toLowerCase();
			return raw.includes('.') ? raw.split('.').pop() : '';
		},
		isVideoType(type) {
			const videoTypes = ['mp4', 'mov', 'avi', 'wmv', 'mkv', 'webm', 'mpeg', 'mpg', 'flv', '3gp'];
			return videoTypes.includes((type || '').toLowerCase());
		},
		isImageType(type) {
			const imageTypes = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'];
			return imageTypes.includes((type || '').toLowerCase());
		},
		isPdfType(type) {
			return (type || '').toLowerCase() === 'pdf';
		},
		previewFile(file) {
			const fileUrl = this.getFullUrl(file.url);
			const fileType = this.getFileType(file);
			
			// 图片预览
			if (this.isImageType(fileType)) {
				uni.previewImage({
					current: 0,
					urls: [fileUrl]
				});
				return;
			}
			
			// PDF预览
			if (this.isPdfType(fileType)) {
				uni.setStorageSync('wjurl', fileUrl);
				uni.navigateTo({
					url: '/pages/pdf/pdf'
				});
				return;
			}
			
			// 视频预览
			if (this.isVideoType(fileType)) {
				uni.setStorageSync('videoUrl', fileUrl);
				uni.setStorageSync('videoName', file.name || '视频');
				uni.navigateTo({
					url: '/pages/new/zlgl/video-preview'
				});
				return;
			}
			
			// 其他文件类型提示
			uni.showToast({
				title: '该文件类型暂不支持在线预览',
				icon: 'none',
				duration: 2000
			});
		}
	}
}
</script>

<style scoped lang="scss">
@import 'index.scss';

.box {
	.top2 {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 15px 10px;
		border-bottom: 1px solid #e5e5e5;
		
		.f4 {
			font-size: 14px;
			color: #666;
			flex-shrink: 0;
		}
		
		.f5 {
			font-size: 14px;
			color: #333;
			text-align: right;
			flex: 1;
			margin-left: 10px;
			word-break: break-all;
		}
	}
	
	.top2:last-child {
		border-bottom: none;
	}
}
</style>