猫妈狗爸伴宠师小程序前端代码
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.
 
 
 
 

504 lines
11 KiB

<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>