- 新增frequency.js接口文件,包含日订单列表查询、详情获取和打卡功能 - 修改myOrdersManage页面,使用新版日订单接口替代旧接口 - 更新timelineService组件,适配新版数据结构和展示逻辑 - 重构打卡页面,支持多宠物和多服务项目的打卡记录 - 调整环境配置,将默认环境改为develop并更新本地开发地址master
@ -0,0 +1,40 @@ | |||
import request from '@/utils/request' | |||
// 新版本日订单查询日订单列表 | |||
export function appletOrderDateFrequencyList(params) { | |||
return request({ | |||
headers: { | |||
"isToken": true | |||
}, | |||
url: "/applet/appletOrderDateFrequency/list", | |||
method: 'get', | |||
params | |||
}) | |||
} | |||
// 新版本日订单查询详情 | |||
export function appletOrderDateFrequencyById(id) { | |||
return request({ | |||
headers: { | |||
"isToken": true | |||
}, | |||
url: "/applet/appletOrderDateFrequency/" + id, | |||
method: 'get', | |||
}) | |||
} | |||
// 新版本日订单打卡 | |||
export function appletOrderDateFrequencyCheck(data) { | |||
return request({ | |||
headers: { | |||
"isToken": true | |||
}, | |||
url: "/applet/appletOrderDateFrequency/check", | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
export default { | |||
appletOrderDateFrequencyList, | |||
appletOrderDateFrequencyById, | |||
appletOrderDateFrequencyCheck, | |||
} |
@ -0,0 +1,462 @@ | |||
<template> | |||
<!-- <view>打卡</view> --> | |||
<view class="box box-size"> | |||
<view class="top box-size" :style="{borderRadius:'16rpx'}"> | |||
<view class="form-title"> | |||
个人准备 | |||
</view> | |||
<view class="mt32 ml10"> | |||
<span :style="{fontSize:'30rpx',fontWeight:'400'}">手套照片</span> | |||
<span :style="{fontSize:'26rpx',color:'#C7C7C7'}">(至少1张)</span> | |||
</view> | |||
<view class="level"> | |||
<view class="mt20 ml10"> | |||
<up-upload :fileList="fileList.glove" @afterRead="afterRead" @delete="deletePic" name="glove" | |||
multiple :maxCount="2" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
</view> | |||
</view> | |||
<view class="mt32 ml10"> | |||
<span :style="{fontSize:'30rpx',fontWeight:'400'}">鞋套照片</span> | |||
<span :style="{fontSize:'26rpx',color:'#C7C7C7'}">(至少1张)</span> | |||
</view> | |||
<view class="level"> | |||
<view class="mt20 ml10"> | |||
<up-upload :fileList="fileList.ShoeCover" @afterRead="afterRead" @delete="deletePic" | |||
name="ShoeCover" multiple :maxCount="2" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="top mt24 box-size" :style="{borderRadius:'16rpx'}"> | |||
<view class="form-title"> | |||
宠物状态记录 | |||
</view> | |||
<view v-for="(pet, index) in petList" :key="index"> | |||
<view class="mt32 ml10"> | |||
<span :style="{fontSize:'30rpx',fontWeight:'400'}">{{ pet.title }}照片</span> | |||
<span :style="{fontSize:'26rpx',color:'#C7C7C7'}">(至少2张)</span> | |||
</view> | |||
<view class="level"> | |||
<view class="mt20 ml10 mr20"> | |||
<up-upload :fileList="fileList['pet' + index]" @afterRead="afterRead" @delete="deletePic" | |||
:name="'pet' + index" multiple :maxCount="2" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" | |||
:style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="top mt24 box-size" :style="{borderRadius:'16rpx'}"> | |||
<view class="form-title"> | |||
基础服务记录 | |||
</view> | |||
<view class="mt32 ml10" :style="{fontSize:'30rpx',fontWeight:'400'}">粮碗前后对比 </view> | |||
<view class="level"> | |||
<view class="mt20 ml10"> | |||
<up-upload :fileList="fileList.foodA" @afterRead="afterRead" @delete="deletePic" name="foodA" | |||
multiple :maxCount="1" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
<view class="jus-center level" :style="{color:'#999999',fontSize:'22rpx',width:'131rpx'}">前</view> | |||
</view> | |||
<view class="mt20 ml10 ml28"> | |||
<up-upload :fileList="fileList.foodB" @afterRead="afterRead" @delete="deletePic" name="foodB" | |||
multiple :maxCount="1" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
<view class="jus-center level" :style="{color:'#999999',fontSize:'22rpx',width:'131rpx'}">后</view> | |||
</view> | |||
</view> | |||
<view class="mt32 ml10" :style="{fontSize:'30rpx',fontWeight:'400'}">水碗前后对比 </view> | |||
<view class="level"> | |||
<view class="mt20 ml10"> | |||
<up-upload :fileList="fileList.waterA" @afterRead="afterRead" @delete="deletePic" name="waterA" | |||
multiple :maxCount="1" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
<view class="jus-center level" :style="{color:'#999999',fontSize:'22rpx',width:'131rpx'}">前</view> | |||
</view> | |||
<view class="mt20 ml10 ml28"> | |||
<up-upload :fileList="fileList.waterB" @afterRead="afterRead" @delete="deletePic" name="waterB" | |||
multiple :maxCount="1" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
<view class="jus-center level" :style="{color:'#999999',fontSize:'22rpx',width:'131rpx'}">后</view> | |||
</view> | |||
</view> | |||
<view class="mt32 ml10" :style="{fontSize:'30rpx',fontWeight:'400'}">猫砂盆、尿垫前后对比 </view> | |||
<view class="level"> | |||
<view class="mt20 ml10"> | |||
<up-upload :fileList="fileList.urinalA" @afterRead="afterRead" @delete="deletePic" name="urinalA" | |||
multiple :maxCount="1" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
<view class="jus-center level" :style="{color:'#999999',fontSize:'22rpx',width:'131rpx'}">前</view> | |||
</view> | |||
<view class="mt20 ml10 ml28"> | |||
<up-upload :fileList="fileList.urinalB" @afterRead="afterRead" @delete="deletePic" name="urinalB" | |||
multiple :maxCount="1" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
<view class="jus-center level" :style="{color:'#999999',fontSize:'22rpx',width:'131rpx'}">后</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="top mt24 box-size" :style="{borderRadius:'16rpx'}"> | |||
<view class="form-title"> | |||
定制服务记录 | |||
</view> | |||
<view class="mt32 ml10"> | |||
<span :style="{fontSize:'30rpx',fontWeight:'400'}">遛狗</span> | |||
<span :style="{fontSize:'26rpx',color:'#C7C7C7'}">(2-3张)</span> | |||
</view> | |||
<view class="level"> | |||
<view class="mt20 ml10 mr20"> | |||
<up-upload :fileList="fileList.testa" @afterRead="afterRead" @delete="deletePic" name="testa" | |||
multiple :maxCount="3" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
</view> | |||
</view> | |||
<view class="mt32 ml10"> | |||
<span :style="{fontSize:'30rpx',fontWeight:'400'}">陪玩</span> | |||
<span :style="{fontSize:'26rpx',color:'#C7C7C7'}">(2-3张)</span> | |||
</view> | |||
<view class="level"> | |||
<view class="mt20 ml10 mr20"> | |||
<up-upload :fileList="fileList.testb" @afterRead="afterRead" @delete="deletePic" name="testb" | |||
multiple :maxCount="3" width="131rpx" height="131rpx" :disabled="isRead"> | |||
<image src="/static/images/ydd/add_photo.png" mode="" :style="{width:'131rpx',height:'131rpx'}"> | |||
</image> | |||
</up-upload> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="top mt24 box-size" :style="{borderRadius:'16rpx'}"> | |||
<view class="form-title"> | |||
其他补充信息(必填) | |||
</view> | |||
<view class="mt32 ml10" :style="{color:'#999999',fontSize:'30rpx'}"> | |||
可记录一下今日趣事、宠物状况、提醒事项等 | |||
</view> | |||
<view class="mt24"> | |||
<textarea cols="30" rows="10" | |||
placeholder="请输入内容" | |||
v-model="content" | |||
:style="{color:'#999999',fontSize:'30rpx',backgroundColor:'#F5F5F5',borderRadius:'16rpx',width:'681rpx',height:'180rpx'}" | |||
class="pd20 box-size" :disabled="isRead"></textarea> | |||
</view> | |||
</view> | |||
<view class="buttom mt60 box-size" | |||
v-if="!isRead" | |||
style="display: flex;gap: 20rpx;" | |||
> | |||
<view class="buttom-item buttom-item-2 level size-30" | |||
@click="saveDraft(false)" | |||
:style="{borderRadius:'41rpx',color:'#ff842c'}"> | |||
保存草稿 | |||
</view> | |||
<view class="buttom-item level size-30" | |||
@click="submit" | |||
:style="{borderRadius:'41rpx',color:'#fff'}"> | |||
确定提交 | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script setup> | |||
import { | |||
onMounted, | |||
reactive, | |||
ref, | |||
} from "vue"; | |||
import { | |||
onLoad | |||
} from '@dcloudio/uni-app' | |||
import { | |||
ossUpload | |||
} from '@/utils/oss-upload/oss/index.js' | |||
import { orderItemLogGetByOrderId } from '@/api/order/order.js' | |||
import { | |||
getOrderPetById, | |||
orderItemLogAddOrUpdate, | |||
} from "@/api/order/order.js"; | |||
onLoad((options) => { | |||
orderId.value = options.id || null; | |||
isRead.value = options.isRead || false; | |||
itemOrderID.value = options.itemID | |||
serviceId.value = options.serviceId; | |||
GetByOrderId() | |||
}); | |||
const orderId = ref(0) | |||
const itemOrderID = ref(0) | |||
const serviceId = ref(0) | |||
const isRead = ref(false) | |||
const content = ref('') | |||
const fileList = reactive({ | |||
// glove: [],//手套 | |||
// ShoeCover: [],//鞋套 | |||
// food: [],//粮碗 | |||
// water: [],//水碗 | |||
// urinal: [],//猫砂盆、尿盆 | |||
}) | |||
const form = ref({}) | |||
const petList = ref([ | |||
// { | |||
// title: '小汪' | |||
// }, | |||
// { | |||
// title: '大黄' | |||
// }, | |||
]) | |||
// 删除图片 | |||
const deletePic = (event) => { | |||
if (fileList[event.name]) { | |||
fileList[event.name].splice(event.index, 1); | |||
} | |||
}; | |||
// 新增图片 | |||
const afterRead = (event) => { | |||
if (!fileList[event.name]) { | |||
fileList[event.name] = [] | |||
} | |||
event.file.forEach(n => { | |||
ossUpload(n.url) | |||
.then(url => { | |||
fileList[event.name].push({ | |||
url | |||
}) | |||
}) | |||
}) | |||
}; | |||
function submit() { | |||
// 参数效验 | |||
if (!fileList.glove || fileList.glove.length == 0) { | |||
return msg('请上传鞋套照片') | |||
} | |||
if (!fileList.ShoeCover || fileList.ShoeCover.length == 0) { | |||
return msg('请上传鞋套照片') | |||
} | |||
for (let i = 0; i < petList.value.length; i++) { | |||
if (!fileList['pet' + i] || fileList['pet' + i].length < 2) { | |||
return msg(`请上传${petList.value[i].title}照片`) | |||
} | |||
} | |||
if (!fileList.foodA || fileList.foodA.length < 1 || | |||
!fileList.foodB || fileList.foodB.length < 1) { | |||
return msg('请上传粮碗前后照片') | |||
} | |||
if (!fileList.waterA || fileList.waterA.length < 1 || | |||
!fileList.waterB || fileList.waterB.length < 1) { | |||
return msg('请上传水碗前后照片') | |||
} | |||
if (!fileList.urinalA || fileList.urinalA.length < 1 || | |||
!fileList.urinalB || fileList.urinalB.length < 1) { | |||
return msg('请上传猫砂盆、尿盆照片') | |||
} | |||
if(!content.value){ | |||
return msg('请填写补充信息') | |||
} | |||
saveDraft(true) | |||
} | |||
function GetByOrderId(){ | |||
orderItemLogGetByOrderId(serviceId.value) | |||
.then(res => { | |||
if(res.code == 200 && res.data) { | |||
const data = res.data; | |||
form.value = data | |||
// 回显手套照片 | |||
if(data.glovePhoto) { | |||
fileList.glove = data.glovePhoto.split(',').map(url => ({ url })); | |||
} | |||
// 回显鞋套照片 | |||
if(data.shoeCoverPhoto) { | |||
fileList.ShoeCover = data.shoeCoverPhoto.split(',').map(url => ({ url })); | |||
} | |||
// 回显宠物照片 | |||
if(data.petPhoto) { | |||
const pets = JSON.parse(data.petPhoto); | |||
petList.value = pets; | |||
pets.forEach((pet, index) => { | |||
if(pet.fileList) { | |||
fileList['pet' + index] = pet.fileList.split(',').map(url => ({ url })); | |||
} | |||
}); | |||
} | |||
// 回显粮碗照片 | |||
if(data.grainBowlFront) fileList.foodA = data.grainBowlFront.split(',').map(url => ({ url })); | |||
if(data.grainBowlAfter) fileList.foodB = data.grainBowlAfter.split(',').map(url => ({ url })); | |||
// 回显水碗照片 | |||
if(data.waterBowlFront) fileList.waterA = data.waterBowlFront.split(',').map(url => ({ url })); | |||
if(data.waterBowlAfter) fileList.waterB = data.waterBowlAfter.split(',').map(url => ({ url })); | |||
// 回显猫砂盆/尿垫照片 | |||
if(data.basinFront) fileList.urinalA = data.basinFront.split(',').map(url => ({ url })); | |||
if(data.basinAfter) fileList.urinalB = data.basinAfter.split(',').map(url => ({ url })); | |||
// 回显定制服务照片 | |||
if(data.workDogImage) fileList.testa = data.workDogImage.split(',').map(url => ({ url })); | |||
if(data.workPalyImage) fileList.testb = data.workPalyImage.split(',').map(url => ({ url })); | |||
}else{ | |||
getOrderPetByIdFN() | |||
} | |||
}) | |||
} | |||
function getOrderPetByIdFN(){ | |||
getOrderPetById(orderId.value) | |||
.then(res => { | |||
if(res.code == 200){ | |||
res.data.forEach((n, i) => { | |||
fileList['pet' + i] = [] | |||
}) | |||
res.data.forEach((n, i) => { | |||
petList.value.push({ | |||
title : n.name, | |||
id : n.id, | |||
}) | |||
}) | |||
} | |||
}) | |||
} | |||
function saveDraft(flag) { | |||
// 将所有图片数组转换为逗号分隔的字符串 | |||
const params = { | |||
orderId: orderId.value, | |||
itemOrderId : itemOrderID.value, | |||
itemDateId : serviceId.value, | |||
glovePhoto: fileList.glove?.map(item => item.url).join(',') || '', | |||
shoeCoverPhoto: fileList.ShoeCover?.map(item => item.url).join(',') || '', | |||
// 合并所有宠物照片 | |||
petPhoto: JSON.stringify( | |||
petList.value.map((pet, index) => { | |||
return { | |||
id : pet.id, | |||
title : pet.title, | |||
fileList: fileList['pet' + index]?.map(item => item.url).join(',') || '' | |||
}; | |||
}) | |||
), | |||
// 粮碗照片 | |||
grainBowlFront: fileList.foodA?.map(item => item.url).join(',') || '', | |||
grainBowlAfter: fileList.foodB?.map(item => item.url).join(',') || '', | |||
// 水碗照片 | |||
waterBowlFront: fileList.waterA?.map(item => item.url).join(',') || '', | |||
waterBowlAfter: fileList.waterB?.map(item => item.url).join(',') || '', | |||
// 猫砂盆/尿垫照片 | |||
basinFront: fileList.urinalA?.map(item => item.url).join(',') || '', | |||
basinAfter: fileList.urinalB?.map(item => item.url).join(',') || '', | |||
// 定制服务照片 | |||
workDogImage: fileList.testa?.map(item => item.url).join(',') || '', | |||
workPalyImage: fileList.testb?.map(item => item.url).join(',') || '', | |||
// 备注信息 | |||
notes: form.value.notes || '', | |||
} | |||
if(form.value.id) { | |||
params.id = form.value.id | |||
} | |||
if(flag) { | |||
params.submitFlag = 2 | |||
} | |||
orderItemLogAddOrUpdate(params) | |||
.then(res => { | |||
if(res.code === 200) { | |||
uni.showToast({ | |||
title: '提交成功', | |||
icon: 'success' | |||
}) | |||
// 如果是确认提交(非草稿),则返回上一页 | |||
setTimeout(() => { | |||
uni.navigateBack() | |||
}, 1500) | |||
} else { | |||
uni.showToast({ | |||
title: res.msg || '提交失败', | |||
icon: 'none' | |||
}) | |||
} | |||
}) | |||
.catch(err => { | |||
uni.showToast({ | |||
title: '提交失败', | |||
icon: 'none' | |||
}) | |||
}) | |||
} | |||
function msg(content) { | |||
uni.showToast({ | |||
title: content, | |||
icon: 'none' | |||
}) | |||
} | |||
</script> | |||
<style scoped lang="scss"> | |||
@import"index.scss" | |||
</style> |
@ -0,0 +1,636 @@ | |||
<template> | |||
<view class="timeline-container"> | |||
<!-- 日期和状态标签 --> | |||
<view class="date-header"> | |||
<view class="date-box"> | |||
<view class="date-box-color" :style="{'background-color': getTopBgColor()}"></view> | |||
<view class="date-month-day">{{ formatDate(date).month }}-{{ formatDate(date).day }}</view> | |||
</view> | |||
<view class="status-tag" :class="{'status-tag-pending': status}"> | |||
<image src="/static/images/ydd/icon1.png" | |||
mode="aspectFit" | |||
v-if="status" | |||
class="status-icon"></image> | |||
<image src="/static/images/order/success.png" | |||
mode="aspectFit" | |||
v-else | |||
class="status-icon"></image> | |||
{{ status ? '待上门' : '已完成' }} | |||
</view> | |||
</view> | |||
<!-- 空状态显示 --> | |||
<view v-if="!processedList || processedList.length === 0" class="empty-state"> | |||
<text class="empty-text">暂无订单数据</text> | |||
</view> | |||
<!-- 时间线主体 --> | |||
<view v-else class="timeline-body" v-for="(item, index) in processedList" :key="index"> | |||
<view class="timeline-line"></view> | |||
<view class="time-point"> | |||
<view class="time-icon"> | |||
<image src="/static/images/order/address.png" mode="aspectFit" class="time-image"></image> | |||
</view> | |||
<view class="time-text">{{ item.address }}</view> | |||
<view class="collapse-icon" @click="toggleServiceCard(index)"> | |||
{{ serviceCardCollapsed[index] ? '展开' : '收起' }} <text class="arrow" :class="{'arrow-up': !serviceCardCollapsed[index]}">▼</text> | |||
</view> | |||
</view> | |||
<!-- 服务内容卡片 --> | |||
<view v-if="!serviceCardCollapsed[index]" class="service-card"> | |||
<!-- 服务日期 --> | |||
<view class="service-section"> | |||
<view class="section-title"> | |||
<view class="title-indicator"></view> | |||
<text>服务日期</text> | |||
<text style="margin-left: auto;font-weight: 500;font-size: 24rpx;">订单编号:{{ item.orderId }}</text> | |||
</view> | |||
<view class="section-content date-content" :class="{bgSuccessQ : item.status}"> | |||
{{ item.fullDate }} | |||
</view> | |||
</view> | |||
<!-- 陪伴对象 --> | |||
<view class="service-section"> | |||
<view class="section-title"> | |||
<view class="title-indicator"></view> | |||
<text>陪伴对象</text> | |||
<view class="collapse-icon" @click="togglePetList(index)"> | |||
{{ petListCollapsed[index] ? '展开' : '收起' }} <text class="arrow" :class="{'arrow-up': !petListCollapsed[index]}">▼</text> | |||
</view> | |||
</view> | |||
<view class="section-content pet-list" :class="{bgSuccessQ : item.status}" v-if="!petListCollapsed[index]"> | |||
<view v-for="(pet, i) in item.petList" :key="i" class="pet-item"> | |||
<view class="pet-avatar"> | |||
<image :src="pet.avatar" mode="aspectFill" class="avatar-image"></image> | |||
</view> | |||
<view class="pet-info"> | |||
<view class="pet-name"> | |||
{{ pet.name }} | |||
<text class="pet-gender" :class="{'pet-gender-male': pet.gender === 'male', 'pet-gender-female': pet.gender === 'female'}"> | |||
{{ pet.gender === 'male' ? '♂' : '♀' }} | |||
</text> | |||
</view> | |||
<view class="pet-description"> | |||
{{ pet.breed }}{{ pet.bodyType }} | {{ pet.services.join('+') }} | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 上门地址 --> | |||
<view class="service-section"> | |||
<view class="section-title"> | |||
<view class="title-indicator"></view> | |||
<text>上门地址</text> | |||
</view> | |||
<view class="section-content address-content" :class="{bgSuccessQ : item.status}"> | |||
{{ item.addressDetail }} | |||
</view> | |||
</view> | |||
<!-- 操作按钮 --> | |||
<view class="action-buttons"> | |||
<view class="btn btn-clock" :class="{bgSuccess : item.status}" @click="handleClock(item)">{{ item.status ? '打卡记录' : '打卡' }}</view> | |||
<view class="btn btn-clock" :class="{bgSuccess : item.status}" @click="handlePetFile(item)">宠物档案</view> | |||
<view class="btn btn-clock" :class="{bgSuccess : item.status}" @click="handleServiceFile(item)">服务档案</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script setup> | |||
import { ref, computed } from 'vue'; | |||
import { getOrderServiceText, getProductNameText } from '@/utils/serviceTime.js'; | |||
// 定义组件属性 | |||
const props = defineProps({ | |||
date: { | |||
type: String, | |||
default: '2024-12-08' | |||
}, | |||
orderCount: { | |||
type: Number, | |||
default: 2 | |||
}, | |||
status : { | |||
type: Boolean, | |||
default: true | |||
}, | |||
current: { | |||
type: Number, | |||
default: 0 | |||
}, | |||
list: { | |||
type: Array, | |||
default: () => [] | |||
} | |||
}); | |||
// 宠物列表折叠状态 - 使用数组来单独控制每个卡片中的宠物列表 | |||
const petListCollapsed = ref([]); | |||
// 服务卡片折叠状态 - 使用数组来单独控制每个卡片 | |||
const serviceCardCollapsed = ref([]); | |||
// 切换宠物列表显示状态 | |||
const togglePetList = (index) => { | |||
if (petListCollapsed.value[index] === undefined) { | |||
petListCollapsed.value[index] = true; | |||
} else { | |||
petListCollapsed.value[index] = !petListCollapsed.value[index]; | |||
} | |||
}; | |||
// 切换服务卡片显示状态 | |||
const toggleServiceCard = (index) => { | |||
if (serviceCardCollapsed.value[index] === undefined) { | |||
serviceCardCollapsed.value[index] = true; | |||
} else { | |||
serviceCardCollapsed.value[index] = !serviceCardCollapsed.value[index]; | |||
} | |||
}; | |||
// 格式化日期 | |||
const formatDate = (dateString) => { | |||
const date = new Date(dateString); | |||
return { | |||
day: date.getDate().toString().padStart(2, '0'), | |||
month: (date.getMonth() + 1).toString().padStart(2, '0') | |||
}; | |||
}; | |||
// 处理订单数据,转换为组件所需格式 | |||
const processedList = computed(() => { | |||
return props.list.map(order => { | |||
// 获取所有宠物信息 | |||
const petList = []; | |||
let orderId = 0 | |||
let serviceId = 0 | |||
let status = 1 | |||
if (order.appletOrderItemDate && order.appletOrderItemDate.length > 0) { | |||
order.appletOrderItemDate.forEach(item => { | |||
if (item.orderServiceList && item.orderServiceList.petVo) { | |||
const pet = item.orderServiceList.petVo; | |||
const services = []; | |||
// 获取服务名称 | |||
if (item.orderItemList && item.orderItemList.length > 0) { | |||
item.orderItemList.forEach(orderItem => { | |||
services.push(orderItem.productName); | |||
orderId = orderItem.orderId | |||
}); | |||
} | |||
serviceId = item.id | |||
if(item.status == 0){ | |||
status = 0 | |||
} | |||
petList.push({ | |||
name: pet.name, | |||
serviceId : item.id, | |||
gender: pet.gender === '男生' ? 'male' : 'female', | |||
breed: pet.breed, | |||
bodyType: `(${pet.bodyType})`, | |||
services: services, | |||
avatar: pet.photo || (pet.petType === 'dog' ? '/static/images/ydd/dog.png' : '/static/images/ydd/cat.png') | |||
}); | |||
} | |||
}); | |||
} | |||
return { | |||
id: order.orderId, | |||
orderId, | |||
serviceId, | |||
status, | |||
address: order.cityAddress, | |||
addressDetail: order.address, | |||
fullDate: props.date.replace(/-/g, '/'), | |||
petList: petList | |||
}; | |||
}); | |||
}); | |||
// 按钮事件处理函数 | |||
const handleClock = (item) => { | |||
console.log(item); | |||
// 根据订单状态确定跳转路径 | |||
const paths = [ | |||
`/otherPages/myOrdersManage/clock/index?id=${item.orderId}&itemID=${item.id}&serviceId=${item.serviceId}`, | |||
`/otherPages/myOrdersManage/clock/index?isRead=true&id=${item.orderId}&itemID=${item.id}&serviceId=${item.serviceId}`, | |||
]; | |||
uni.navigateTo({ | |||
url: props.status ? paths[0] : paths[1] | |||
}); | |||
}; | |||
const handlePetFile = (item) => { | |||
uni.navigateTo({ | |||
url: "/otherPages/orderTakingManage/pet/index?id=" + item.orderId | |||
}); | |||
}; | |||
const handleServiceFile = (item) => { | |||
uni.navigateTo({ | |||
url: "/otherPages/myOrdersManage/service/index?id=" + item.orderId | |||
}); | |||
}; | |||
function getTopBgColor(){ | |||
return props.status ? '#FFAA48' : '#4CD964'; | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.bgSuccess{ | |||
background-color: #4CD964 !important; | |||
} | |||
.bgSuccessQ{ | |||
background-color: #4CD96422 !important; | |||
} | |||
.timeline-container { | |||
position: relative; | |||
padding: 20rpx; | |||
margin-bottom: 30rpx; | |||
.empty-state { | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
justify-content: center; | |||
padding: 80rpx 40rpx; | |||
.empty-image { | |||
width: 200rpx; | |||
height: 200rpx; | |||
margin-bottom: 20rpx; | |||
} | |||
.empty-text { | |||
color: #999; | |||
font-size: 28rpx; | |||
} | |||
} | |||
.date-header { | |||
display: flex; | |||
align-items: center; | |||
margin-bottom: 20rpx; | |||
.date-box { | |||
width: 80rpx; | |||
background-color: #ffffff; | |||
border: 2px solid #333; | |||
border-radius: 0; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
align-items: center; | |||
margin-right: 20rpx; | |||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05); | |||
border-radius: 14rpx; | |||
.date-box-color{ | |||
height: 20rpx; | |||
width: 100%; | |||
border-top-left-radius: 14rpx; | |||
border-top-right-radius: 14rpx; | |||
position: relative; | |||
&::before{ | |||
content: ''; | |||
display: block; | |||
background-color: #ddd; | |||
width: 100%; | |||
height: 26rpx; | |||
top: 100%; | |||
left: 0; | |||
position: absolute; | |||
} | |||
} | |||
.date-month-day { | |||
position: relative; | |||
font-size: 26rpx; | |||
font-weight: bold; | |||
color: #333; | |||
height: 50rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
} | |||
} | |||
.status-tag { | |||
background-color: #4CD96422; | |||
color: #4CD964; | |||
border: 4rpx solid #4CD964; | |||
padding: 16rpx 26rpx; | |||
border-radius: 14rpx; | |||
font-size: 26rpx; | |||
display: flex; | |||
align-items: center; | |||
position: relative; | |||
margin-left: 20rpx; | |||
.status-icon { | |||
width: 32rpx; | |||
height: 32rpx; | |||
margin-right: 8rpx; | |||
} | |||
&::after{ | |||
content: ''; | |||
display: block; | |||
position: absolute; | |||
width: 0; | |||
height: 0; | |||
top: 50%; | |||
transform: translateY(-50%); | |||
left: -16rpx; | |||
border-top: 16rpx solid transparent; | |||
border-bottom: 16rpx solid transparent; | |||
border-right: 16rpx solid #4CD964; | |||
} | |||
&::before{ | |||
content: ''; | |||
display: block; | |||
position: absolute; | |||
width: 0; | |||
height: 0; | |||
top: 50%; | |||
transform: translateY(-50%); | |||
left: -12rpx; | |||
border-top: 12rpx solid transparent; | |||
border-bottom: 12rpx solid transparent; | |||
border-right: 12rpx solid #4CD96422; | |||
z-index: 1; | |||
} | |||
} | |||
.status-tag-pending { | |||
background-color: #FFAA4822; | |||
color: #FFAA48; | |||
border-color: #FFAA48; | |||
&::after{ | |||
border-right-color: #FFAA48; | |||
} | |||
&::before{ | |||
border-right-color: #FFAA4822; | |||
} | |||
} | |||
} | |||
.timeline-body { | |||
position: relative; | |||
padding-left: 40rpx; | |||
padding-bottom: 40rpx; | |||
.timeline-line { | |||
position: absolute; | |||
left: 40rpx; | |||
top: 0; | |||
height: 100%; | |||
width: 0; | |||
border-left: 2rpx dashed #707070; | |||
border-left-style: dashed; | |||
border-image: repeating-linear-gradient(to bottom, #707070 0, #707070 8rpx, transparent 8rpx, transparent 20rpx) 1; | |||
z-index: 0; | |||
&::after{ | |||
content: ''; | |||
display: block; | |||
position: absolute; | |||
width: 8rpx; | |||
height: 8rpx; | |||
background-color: #000; | |||
border: 2rpx solid #707070; | |||
border-radius: 50%; | |||
left: -7rpx; | |||
top: 30rpx; | |||
} | |||
} | |||
.time-point { | |||
display: flex; | |||
align-items: center; | |||
margin-bottom: 20rpx; | |||
position: relative; | |||
z-index: 1; | |||
.time-icon { | |||
width: 60rpx; | |||
height: 60rpx; | |||
background-color: #fff; | |||
border-radius: 50%; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
margin-right: 20rpx; | |||
position: relative; | |||
left: 20rpx; | |||
.time-image { | |||
width: 40rpx; | |||
height: 40rpx; | |||
} | |||
} | |||
.time-text { | |||
font-size: 28rpx; | |||
color: #333; | |||
margin-left: 20rpx; | |||
flex: 1; | |||
} | |||
.collapse-icon { | |||
font-size: 24rpx; | |||
color: #999; | |||
padding: 0 20rpx; | |||
.arrow { | |||
transition: transform 0.3s; | |||
display: inline-block; | |||
} | |||
.arrow-up { | |||
transform: rotate(180deg); | |||
} | |||
} | |||
} | |||
.service-card { | |||
background-color: #fff; | |||
border-radius: 12rpx; | |||
padding: 30rpx; | |||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); | |||
margin-left: 20rpx; | |||
.service-section { | |||
margin-bottom: 30rpx; | |||
.section-title { | |||
display: flex; | |||
align-items: center; | |||
margin-bottom: 15rpx; | |||
.title-indicator { | |||
width: 6rpx; | |||
height: 30rpx; | |||
background-color: #FFAA48; | |||
margin-right: 15rpx; | |||
} | |||
text { | |||
font-size: 28rpx; | |||
color: #333; | |||
font-weight: bold; | |||
} | |||
.collapse-icon { | |||
margin-left: auto; | |||
font-size: 24rpx; | |||
color: #999; | |||
.arrow { | |||
transition: transform 0.3s; | |||
display: inline-block; | |||
} | |||
.arrow-up { | |||
transform: rotate(180deg); | |||
} | |||
} | |||
} | |||
.section-content { | |||
padding: 0 15rpx; | |||
background-color: #FFF9F0; | |||
} | |||
.date-content { | |||
background-color: #FFF9F0; | |||
padding: 20rpx; | |||
border-radius: 8rpx; | |||
font-size: 28rpx; | |||
color: #333; | |||
} | |||
.pet-list { | |||
padding: 15rpx; | |||
.pet-item { | |||
display: flex; | |||
margin-bottom: 20rpx; | |||
&:last-child { | |||
margin-bottom: 0; | |||
} | |||
.pet-avatar { | |||
width: 80rpx; | |||
height: 80rpx; | |||
border-radius: 50%; | |||
overflow: hidden; | |||
margin-right: 20rpx; | |||
.avatar-image { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
.pet-info { | |||
flex: 1; | |||
.pet-name { | |||
font-size: 28rpx; | |||
color: #333; | |||
margin-bottom: 8rpx; | |||
.pet-gender { | |||
display: inline-block; | |||
width: 32rpx; | |||
height: 32rpx; | |||
line-height: 32rpx; | |||
text-align: center; | |||
border-radius: 50%; | |||
color: #fff; | |||
font-size: 20rpx; | |||
margin-left: 10rpx; | |||
} | |||
.pet-gender-male { | |||
background-color: #4A90E2; | |||
} | |||
.pet-gender-female { | |||
background-color: #FF6B9A; | |||
} | |||
} | |||
.pet-description { | |||
font-size: 24rpx; | |||
color: #7D8196; | |||
} | |||
} | |||
} | |||
} | |||
.address-content { | |||
padding: 20rpx; | |||
border-radius: 8rpx; | |||
font-size: 28rpx; | |||
color: #7D8196; | |||
} | |||
} | |||
.action-buttons { | |||
display: flex; | |||
justify-content: space-between; | |||
.btn { | |||
width: 30%; | |||
height: 80rpx; | |||
line-height: 80rpx; | |||
text-align: center; | |||
border-radius: 40rpx; | |||
font-size: 28rpx; | |||
} | |||
.btn-clock { | |||
background-color: #FFAA48; | |||
color: #fff; | |||
} | |||
.btn-pet-file, .btn-service-file { | |||
background-color: #F6F7FB; | |||
color: #333; | |||
border: 1px solid #E5E6EB; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
</style> |