You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

549 lines
15 KiB

<template>
<view class="order-detail-container">
<!-- 日期信息 -->
<view class="order-date">
<view class="order-date-icon">
<u-icon name="calendar" color="#FFAA48" size="22"></u-icon>
</view>
<view class="order-date-text">{{ orderDate }}</view>
</view>
<!-- 个人准备 -->
<view class="order-section" v-if="fileList.glove || fileList.ShoeCover">
<view class="order-section-title">个人准备</view>
<view class="order-section-content">
<!-- 手套照片 -->
<view class="order-image-item" v-if="fileList.glove && fileList.glove.length > 0">
<view class="order-image-label">手套照片 ({{ fileList.glove.length }}张)</view>
<view class="order-image-container">
<image
class="order-image"
v-for="(photo, index) in fileList.glove"
:key="index"
:src="photo.url"
mode="aspectFill"
@click="previewImage(fileList.glove.map(p => p.url), photo.url)">
</image>
</view>
</view>
<!-- 鞋套照片 -->
<view class="order-image-item" v-if="fileList.ShoeCover && fileList.ShoeCover.length > 0">
<view class="order-image-label">鞋套照片 ({{ fileList.ShoeCover.length }}张)</view>
<view class="order-image-container">
<image
class="order-image"
v-for="(photo, index) in fileList.ShoeCover"
:key="index"
:src="photo.url"
mode="aspectFill"
@click="previewImage(fileList.ShoeCover.map(p => p.url), photo.url)">
</image>
</view>
</view>
</view>
</view>
<!-- 宠物状况记录 -->
<view class="order-section" v-if="petList && petList.length > 0">
<view class="order-section-title">宠物状况记录</view>
<view class="order-section-content">
<view class="pet-record" v-for="(pet, index) in petList" :key="index">
<view class="pet-name">{{ pet.title }} ({{ getPetPhotoCount(index) }}张)</view>
<view class="pet-images" v-if="fileList['pet' + index] && fileList['pet' + index].length > 0">
<view class="pet-image-container" v-for="(photo, photoIndex) in fileList['pet' + index]" :key="photoIndex">
<image
class="pet-image"
:src="photo.url"
mode="aspectFill"
@click="previewImage(fileList['pet' + index].map(p => p.url), photo.url)">
</image>
</view>
</view>
</view>
</view>
</view>
<!-- 基础服务记录 -->
<view class="order-section" v-if="hasBasicServices">
<view class="order-section-title">基础服务记录</view>
<view class="order-section-content">
<!-- 粮碗前后对比 -->
<view class="service-record" v-if="fileList.foodA || fileList.foodB">
<view class="service-name">粮碗前后对比</view>
<view class="service-comparison">
<view class="service-before-after">
<view class="service-image-container" v-if="fileList.foodA && fileList.foodA.length > 0">
<image
class="service-image"
:src="fileList.foodA[0].url"
mode="aspectFill"
@click="previewImage([fileList.foodA[0].url], fileList.foodA[0].url)">
</image>
<view class="service-image-label">前</view>
</view>
<view class="service-image-container" v-if="fileList.foodB && fileList.foodB.length > 0">
<image
class="service-image"
:src="fileList.foodB[0].url"
mode="aspectFill"
@click="previewImage([fileList.foodB[0].url], fileList.foodB[0].url)">
</image>
<view class="service-image-label">后</view>
</view>
</view>
</view>
</view>
<!-- 水碗前后对比 -->
<view class="service-record" v-if="fileList.waterA || fileList.waterB">
<view class="service-name">水碗前后对比</view>
<view class="service-comparison">
<view class="service-before-after">
<view class="service-image-container" v-if="fileList.waterA && fileList.waterA.length > 0">
<image
class="service-image"
:src="fileList.waterA[0].url"
mode="aspectFill"
@click="previewImage([fileList.waterA[0].url], fileList.waterA[0].url)">
</image>
<view class="service-image-label">前</view>
</view>
<view class="service-image-container" v-if="fileList.waterB && fileList.waterB.length > 0">
<image
class="service-image"
:src="fileList.waterB[0].url"
mode="aspectFill"
@click="previewImage([fileList.waterB[0].url], fileList.waterB[0].url)">
</image>
<view class="service-image-label">后</view>
</view>
</view>
</view>
</view>
<!-- 猫砂盆、尿垫前后对比 -->
<view class="service-record" v-if="fileList.urinalA || fileList.urinalB">
<view class="service-name">猫砂盆、尿垫前后对比</view>
<view class="service-comparison">
<view class="service-before-after">
<view class="service-image-container" v-if="fileList.urinalA && fileList.urinalA.length > 0">
<image
class="service-image"
:src="fileList.urinalA[0].url"
mode="aspectFill"
@click="previewImage([fileList.urinalA[0].url], fileList.urinalA[0].url)">
</image>
<view class="service-image-label">前</view>
</view>
<view class="service-image-container" v-if="fileList.urinalB && fileList.urinalB.length > 0">
<image
class="service-image"
:src="fileList.urinalB[0].url"
mode="aspectFill"
@click="previewImage([fileList.urinalB[0].url], fileList.urinalB[0].url)">
</image>
<view class="service-image-label">后</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 定制服务记录 -->
<view class="order-section" v-if="projectList && projectList.length > 0">
<view class="order-section-title">定制服务记录</view>
<view class="order-section-content">
<view class="custom-service">
<view class="custom-service-item" v-for="(project, index) in projectList" :key="index">
<view class="custom-service-name">{{ project.title }} ({{ getProjectPhotoCount(index) }})</view>
<view class="custom-service-images" v-if="fileList['project' + index] && fileList['project' + index].length > 0">
<image
class="custom-service-image"
v-for="(photo, photoIndex) in fileList['project' + index]"
:key="photoIndex"
:src="photo.url"
mode="aspectFill"
@click="previewImage(fileList['project' + index].map(p => p.url), photo.url)">
</image>
</view>
</view>
</view>
</view>
</view>
<!-- 补充信息 -->
<view class="order-section" v-if="form.notes">
<view class="order-section-title">补充信息</view>
<view class="order-section-content">
<view class="notes-content">{{ form.notes }}</view>
</view>
</view>
</view>
</template>
<script>
import { appletOrderDateFrequencyById } from '@/api/order/order.js'
export default {
data() {
return {
id: null,
orderDate: '',
form: {},
fileList: {},
petList: [],
projectList: [],
isRead: false
}
},
computed: {
hasBasicServices() {
return (this.fileList.foodA && this.fileList.foodA.length > 0) ||
(this.fileList.foodB && this.fileList.foodB.length > 0) ||
(this.fileList.waterA && this.fileList.waterA.length > 0) ||
(this.fileList.waterB && this.fileList.waterB.length > 0) ||
(this.fileList.urinalA && this.fileList.urinalA.length > 0) ||
(this.fileList.urinalB && this.fileList.urinalB.length > 0);
}
},
onLoad(options) {
if (options.id) {
this.id = options.id;
this.loadOrderDetail();
}
},
methods: {
loadOrderDetail() {
appletOrderDateFrequencyById(this.id)
.then(res => {
const data = res.data.check;
const frequency = res.data.frequency;
this.isRead = frequency.status == 2;
// 设置订单日期
if (frequency.serviceDate) {
this.orderDate = this.formatDate(frequency.serviceDate);
}
if(res.code == 200 && data) {
this.form = data;
// 回显手套照片
if(data.glovePhoto) {
this.$set(this.fileList, 'glove', data.glovePhoto.split(',').map(url => ({ url })));
}
// 回显鞋套照片
if(data.shoeCoverPhoto) {
this.$set(this.fileList, 'ShoeCover', data.shoeCoverPhoto.split(',').map(url => ({ url })));
}
// 回显宠物照片
if(data.petPhoto) {
const pets = JSON.parse(data.petPhoto);
this.petList = pets;
pets.forEach((pet, index) => {
if(pet.fileList) {
this.$set(this.fileList, 'pet' + index, pet.fileList.split(',').map(url => ({ url })));
}
});
}
// 回显项目照片
if(data.workDogImage) {
const pList = JSON.parse(data.workDogImage);
this.projectList = pList;
pList.forEach((project, index) => {
if(project.fileList) {
this.$set(this.fileList, 'project' + index, project.fileList.split(',').map(url => ({ url })));
}
});
}
// 回显粮碗照片
if(data.grainBowlFront) this.$set(this.fileList, 'foodA', data.grainBowlFront.split(',').map(url => ({ url })));
if(data.grainBowlAfter) this.$set(this.fileList, 'foodB', data.grainBowlAfter.split(',').map(url => ({ url })));
// 回显水碗照片
if(data.waterBowlFront) this.$set(this.fileList, 'waterA', data.waterBowlFront.split(',').map(url => ({ url })));
if(data.waterBowlAfter) this.$set(this.fileList, 'waterB', data.waterBowlAfter.split(',').map(url => ({ url })));
// 回显猫砂盆/尿垫照片
if(data.basinFront) this.$set(this.fileList, 'urinalA', data.basinFront.split(',').map(url => ({ url })));
if(data.basinAfter) this.$set(this.fileList, 'urinalB', data.basinAfter.split(',').map(url => ({ url })));
} else {
// 如果没有数据,从frequency中初始化基础结构
let projectNameList = [];
frequency.pets.forEach((pet, i) => {
this.$set(this.fileList, 'pet' + i, []);
pet.orderItemList.forEach((item, index) => {
this.$set(this.fileList, 'project' + index, []);
});
});
frequency.pets.forEach((pet, i) => {
this.petList.push({
title: pet.name,
id: pet.id,
});
pet.orderItemList.forEach((item, index) => {
if(!projectNameList.includes(item.productName)){
projectNameList.push(item.productName);
this.projectList.push({
title: item.productName,
ids: [item.id]
});
} else {
this.projectList[projectNameList.indexOf(item.productName)].ids.push(item.id);
}
});
});
}
})
.catch(err => {
console.error('加载订单详情失败:', err);
uni.showToast({
title: '加载失败',
icon: 'none'
});
});
},
// 获取宠物照片数量
getPetPhotoCount(index) {
const photos = this.fileList['pet' + index];
return photos ? photos.length : 0;
},
// 获取项目照片数量
getProjectPhotoCount(index) {
const photos = this.fileList['project' + index];
return photos ? photos.length : 0;
},
// 格式化日期
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}年${month}月${day}日`;
},
// 图片预览功能
previewImage(urls, current) {
if (!urls || urls.length === 0) return;
uni.previewImage({
urls: urls,
current: current || urls[0],
indicator: 'number',
loop: true
});
}
}
}
</script>
<style lang="scss">
.order-detail-container {
padding: 15px;
background-color: #f5f5f7;
min-height: 100vh;
}
.order-date {
display: flex;
align-items: center;
justify-content: center;
padding: 12px 16px;
background-color: #FFF9EF;
border-radius: 10px;
margin-bottom: 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
.order-date-icon {
margin-right: 12px;
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
background-color: rgba(255, 170, 72, 0.1);
border-radius: 50%;
}
.order-date-text {
color: #A94F20;
font-size: 16px;
font-weight: 500;
letter-spacing: 0.5px;
}
}
.order-section {
background-color: #fff;
border-radius: 8px;
margin-bottom: 15px;
overflow: hidden;
.order-section-title {
padding: 12px 15px;
border-bottom: 1px solid #f0f0f0;
color: #333;
font-size: 16px;
font-weight: 500;
position: relative;
&::before {
content: '';
position: absolute;
left: 0;
top: 12px;
height: 16px;
width: 4px;
background-color: #ffaa48;
border-radius: 0 2px 2px 0;
}
}
.order-section-content {
padding: 15px;
}
}
.order-image-item {
margin-bottom: 15px;
.order-image-label {
color: #666;
font-size: 14px;
margin-bottom: 8px;
}
.order-image-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
.order-image {
width: 80px;
height: 80px;
border-radius: 4px;
object-fit: cover;
}
}
}
.pet-record {
margin-bottom: 20px;
.pet-name {
color: #333;
font-size: 15px;
font-weight: 500;
margin-bottom: 10px;
}
.pet-images {
display: flex;
flex-wrap: wrap;
gap: 10px;
.pet-image-container {
.pet-image {
width: 80px;
height: 80px;
border-radius: 4px;
object-fit: cover;
}
}
}
}
.service-record {
margin-bottom: 20px;
.service-name {
color: #333;
font-size: 15px;
font-weight: 500;
margin-bottom: 10px;
}
.service-comparison {
.service-before-after {
display: flex;
gap: 15px;
.service-image-container {
position: relative;
.service-image {
width: 80px;
height: 80px;
border-radius: 4px;
object-fit: cover;
}
.service-image-label {
position: absolute;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.5);
color: #fff;
padding: 2px 8px;
font-size: 12px;
border-radius: 0 0 0 4px;
}
}
}
}
}
.custom-service {
.custom-service-item {
margin-bottom: 15px;
.custom-service-name {
color: #333;
font-size: 15px;
font-weight: 500;
margin-bottom: 10px;
}
.custom-service-images {
display: flex;
flex-wrap: wrap;
gap: 10px;
.custom-service-image {
width: 80px;
height: 80px;
border-radius: 4px;
object-fit: cover;
}
}
}
}
.notes-content {
color: #333;
font-size: 14px;
line-height: 1.6;
padding: 12px 16px;
background-color: #F5F5F5;
border-radius: 8px;
min-height: 120px;
white-space: pre-wrap;
word-break: break-word;
}
</style>