|
|
@ -0,0 +1,504 @@ |
|
|
|
<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 === 'pending'}"> |
|
|
|
<image src="/static/images/ydd/icon1.png" mode="aspectFit" class="status-icon"></image> |
|
|
|
{{ status === 'pending' ? '待上门' : '已完成' }}{{ orderCount }}单 |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 时间线主体 --> |
|
|
|
<view class="timeline-body"> |
|
|
|
<view class="timeline-line" :class="{'timeline-line-completed': status === 'completed'}"></view> |
|
|
|
|
|
|
|
<!-- 服务时间点 --> |
|
|
|
<view class="time-point"> |
|
|
|
<view class="time-icon"> |
|
|
|
<image src="/static/images/ydd/icon1.png" mode="aspectFit" class="time-image"></image> |
|
|
|
</view> |
|
|
|
<view class="time-text">{{ timeOfDay }}</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 服务内容卡片 --> |
|
|
|
<view class="service-card"> |
|
|
|
<!-- 服务日期 --> |
|
|
|
<view class="service-section"> |
|
|
|
<view class="section-title"> |
|
|
|
<view class="title-indicator"></view> |
|
|
|
<text>服务日期</text> |
|
|
|
</view> |
|
|
|
<view class="section-content date-content"> |
|
|
|
{{ fullDate }} |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 陪伴对象 --> |
|
|
|
<view class="service-section"> |
|
|
|
<view class="section-title"> |
|
|
|
<view class="title-indicator"></view> |
|
|
|
<text>陪伴对象</text> |
|
|
|
<view class="collapse-icon" @click="togglePetList"> |
|
|
|
收起 <text class="arrow" :class="{'arrow-up': !petListCollapsed}">▼</text> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<view class="section-content pet-list" v-if="!petListCollapsed"> |
|
|
|
<view v-for="(pet, index) in pets" :key="index" class="pet-item"> |
|
|
|
<view class="pet-avatar"> |
|
|
|
<image :src="pet.avatar || '/static/images/ydd/dog.png'" 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"> |
|
|
|
{{ address }} |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 操作按钮 --> |
|
|
|
<view class="action-buttons"> |
|
|
|
<view class="btn btn-clock" @click="handleClock">打卡</view> |
|
|
|
<view class="btn btn-clock" @click="handlePetFile">宠物档案</view> |
|
|
|
<view class="btn btn-clock" @click="handleServiceFile">服务档案</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' |
|
|
|
}, |
|
|
|
timeOfDay: { |
|
|
|
type: String, |
|
|
|
default: '早上' |
|
|
|
}, |
|
|
|
status: { |
|
|
|
type: String, |
|
|
|
default: 'pending' // 'pending' 或 'completed' |
|
|
|
}, |
|
|
|
orderCount: { |
|
|
|
type: Number, |
|
|
|
default: 2 |
|
|
|
}, |
|
|
|
pets: { |
|
|
|
type: Array, |
|
|
|
default: () => [{ |
|
|
|
name: '小汪', |
|
|
|
gender: 'male', |
|
|
|
breed: '中华田园犬', |
|
|
|
bodyType: '(小型犬)', |
|
|
|
services: ['专业喂养', '提前熟悉', '陪玩'], |
|
|
|
avatar: '/static/images/ydd/dog.png' |
|
|
|
}, { |
|
|
|
name: 'Billion', |
|
|
|
gender: 'female', |
|
|
|
breed: '豹猫', |
|
|
|
bodyType: '(小型猫)', |
|
|
|
services: ['上门喂养', '陪玩'], |
|
|
|
avatar: '/static/images/ydd/cat.png' |
|
|
|
}] |
|
|
|
}, |
|
|
|
address: { |
|
|
|
type: String, |
|
|
|
default: '重庆市南岸区长嘉汇18栋9-2' |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 宠物列表折叠状态 |
|
|
|
const petListCollapsed = ref(false); |
|
|
|
|
|
|
|
// 切换宠物列表显示状态 |
|
|
|
const togglePetList = () => { |
|
|
|
petListCollapsed.value = !petListCollapsed.value; |
|
|
|
}; |
|
|
|
|
|
|
|
// 格式化日期 |
|
|
|
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 fullDate = computed(() => { |
|
|
|
const date = new Date(props.date); |
|
|
|
const year = date.getFullYear(); |
|
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0'); |
|
|
|
const day = date.getDate().toString().padStart(2, '0'); |
|
|
|
return `${year}年${month}月${day}日`; |
|
|
|
}); |
|
|
|
|
|
|
|
// 按钮事件处理函数 |
|
|
|
const handleClock = (id) => { |
|
|
|
// 打卡功能实现 |
|
|
|
const paths = [`/otherPages/orderTakingManage/detail/index?id=${id}`,'/otherPages/myOrdersManage/clock/index','/otherPages/myOrdersManage/clock/detail'] |
|
|
|
uni.navigateTo({ |
|
|
|
url: paths[props.current] |
|
|
|
}) |
|
|
|
}; |
|
|
|
|
|
|
|
const handlePetFile = () => { |
|
|
|
// 宠物档案功能实现 |
|
|
|
uni.navigateTo({ |
|
|
|
url: "/otherPages/orderTakingManage/pet/index" |
|
|
|
}) |
|
|
|
}; |
|
|
|
|
|
|
|
const handleServiceFile = () => { |
|
|
|
uni.navigateTo({ |
|
|
|
url: "/otherPages/myOrdersManage/service/index" |
|
|
|
}) |
|
|
|
}; |
|
|
|
function getTopBgColor(){ |
|
|
|
return '#FFAA48' |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<style lang="scss" scoped> |
|
|
|
.timeline-container { |
|
|
|
position: relative; |
|
|
|
padding: 20rpx; |
|
|
|
margin-bottom: 30rpx; |
|
|
|
|
|
|
|
.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; |
|
|
|
|
|
|
|
.timeline-line { |
|
|
|
position: absolute; |
|
|
|
left: 40rpx; |
|
|
|
top: 0; |
|
|
|
height: 100%; |
|
|
|
width: 2rpx; |
|
|
|
background-color: #FFAA48; |
|
|
|
z-index: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.timeline-line-completed { |
|
|
|
background-color: #4CD964; |
|
|
|
} |
|
|
|
|
|
|
|
.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; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.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> |