325 lines
6.6 KiB
Vue
325 lines
6.6 KiB
Vue
<template>
|
||
<view>
|
||
<!-- 模态框 -->
|
||
<view @tap="Modal" :class="{ mask: model }"></view>
|
||
<!-- 弹窗主体 -->
|
||
<view
|
||
|
||
class="active"
|
||
:class="{ add: model }"
|
||
>
|
||
<view class="title">
|
||
<text class="title-text">{{ title }}</text>
|
||
<text @tap="close" class="close-btn">×</text>
|
||
</view>
|
||
<view class="cont" :style="{ height: barHidth - 80 + 'rpx' }">
|
||
<!-- 天 -->
|
||
<scroll-view class="day" :scroll-y="true">
|
||
<view
|
||
:class="index === isIndex ? 'active_copy' : ''"
|
||
v-for="(item, index) in content"
|
||
:key="item.date"
|
||
@tap="dataCallback(index, item)"
|
||
>
|
||
<view class="date-week">{{ item.date_title }}</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 时 -->
|
||
<scroll-view class="content" :scroll-y="true" :scroll-top="scrollTop">
|
||
<view
|
||
class="appoint"
|
||
:class="index === Indexes ? 'longActive' : ''"
|
||
@tap="timeCallback(index, item)"
|
||
v-for="(item, index) in Days"
|
||
:key="index"
|
||
>
|
||
{{ item.time_title }}
|
||
<text :class="index === Indexes ? 'cuIcon-check' : ''"></text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
props: {
|
||
title: {
|
||
type: String,
|
||
default: "选择预送达时间",
|
||
},
|
||
content: {
|
||
type: Array,
|
||
default: () => [
|
||
{
|
||
date_title: "B-12 (周五)",
|
||
date_str: "B-12",
|
||
date: "2025-10-12",
|
||
items: [
|
||
{
|
||
time_title: "16:35",
|
||
booking_at: 1,
|
||
booking_state: 1,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
date_title: "B-13 (周六)",
|
||
date_str: "B-13",
|
||
date: "2025-10-13",
|
||
items: [
|
||
{
|
||
time_title: "17:05",
|
||
booking_at: 2,
|
||
booking_state: 2,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
date_title: "B-14 (周日)",
|
||
date_str: "B-14",
|
||
date: "2025-10-14",
|
||
items: [
|
||
{
|
||
time_title: "17:35",
|
||
booking_at: 3,
|
||
booking_state: 2,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
date_title: "B-15 (周一)",
|
||
date_str: "B-15",
|
||
date: "2025-10-15",
|
||
items: [
|
||
{
|
||
time_title: "18:05",
|
||
booking_at: 4,
|
||
booking_state: 1,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
date_title: "B-15 (周二)",
|
||
date_str: "B-15",
|
||
date: "2025-10-16",
|
||
items: [
|
||
{
|
||
time_title: "18:35",
|
||
booking_at: 5,
|
||
booking_state: 1,
|
||
},
|
||
],
|
||
},
|
||
],
|
||
},
|
||
barHidth: {
|
||
type: Number,
|
||
default: 500,
|
||
},
|
||
dodge: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
scrollTop: 0,
|
||
isIndex: 0,
|
||
Indexes: 0,
|
||
Days: [],
|
||
model: false,
|
||
};
|
||
},
|
||
watch: {
|
||
content: {
|
||
immediate: true,
|
||
handler(newValue) {
|
||
if (newValue && newValue.length > 0 && newValue[0].items) {
|
||
this.Days = newValue[0].items;
|
||
} else {
|
||
console.warn('content 数据格式不正确', newValue);
|
||
this.Days = [];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
methods: {
|
||
close() {
|
||
this.model = false;
|
||
},
|
||
open() {
|
||
this.model = true;
|
||
},
|
||
Modal() {
|
||
if (this.dodge) {
|
||
this.close();
|
||
}
|
||
},
|
||
gotop() {
|
||
this.scrollTop = 1;
|
||
this.$nextTick(() => {
|
||
this.scrollTop = 0;
|
||
});
|
||
},
|
||
dataCallback(index, item) {
|
||
this.isIndex = index;
|
||
this.Days = this.content[index].items;
|
||
this.Indexes = 0;
|
||
this.gotop();
|
||
this.$emit("dataCallback", item);
|
||
},
|
||
timeCallback(index, item) {
|
||
this.Indexes = index;
|
||
const selectedDate = this.content[this.isIndex]; // 获取当前选中的日期对象
|
||
const selectedTime = item; // 当前选中的时间对象
|
||
this.$emit("timeCallback", {
|
||
date_title: selectedDate.date_title, // 日期标题
|
||
time_title: selectedTime.time_title, // 时间标题
|
||
booking_at: selectedTime.booking_at, // 预约时间戳
|
||
booking_begin_time: selectedTime.booking_begin_time, // 预约开始时间
|
||
booking_end_time: selectedTime.booking_end_time, // 预约结束时间
|
||
});
|
||
this.$emit("close"); // 触发关闭事件
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
z-index: 999;
|
||
}
|
||
|
||
.active {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
z-index: 1000;
|
||
width: 100%;
|
||
background-color: #fff;
|
||
border-top-left-radius: 20rpx;
|
||
border-top-right-radius: 20rpx;
|
||
overflow: hidden;
|
||
transform: translateY(100%);
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.add {
|
||
height: 380px;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.title {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 24rpx 30rpx;
|
||
border-bottom: 2rpx solid #eee;
|
||
background-color: #fff;
|
||
}
|
||
|
||
.title-text {
|
||
font-size: 34rpx;
|
||
font-weight: 500;
|
||
color: #333;
|
||
max-width: 80%;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* 关闭按钮样式 */
|
||
.close-btn {
|
||
font-size: 50rpx;
|
||
color: #999;
|
||
padding: 10rpx; /* 增加点击区域 */
|
||
border-radius: 50%;
|
||
/* 右对齐(通过 flex 布局已实现,无需绝对定位) */
|
||
}
|
||
|
||
.close-btn:active {
|
||
background-color: #f5f5f5; /* 点击时轻微反馈 */
|
||
}
|
||
.cont {
|
||
display: flex;
|
||
height: calc(100% - 80rpx);
|
||
}
|
||
|
||
.day {
|
||
flex: 2;
|
||
background-color: #f5f5f5;
|
||
text-align: center;
|
||
}
|
||
|
||
.day view {
|
||
padding: 28rpx 0;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.date-week {
|
||
font-weight: 500;
|
||
color: #333; /* 日期颜色 */
|
||
}
|
||
|
||
.active_copy {
|
||
background-color: #fff;
|
||
color: #27c866;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.content {
|
||
flex: 3;
|
||
font-size: 28rpx;
|
||
background-color: #fff;
|
||
}
|
||
|
||
.appoint {
|
||
position: relative;
|
||
text-align: left;
|
||
padding: 30rpx 36rpx;
|
||
border-bottom: 2rpx solid #f5f5f5;
|
||
color: #333; /* 时间颜色 */
|
||
}
|
||
|
||
.longActive {
|
||
color: #27c866;
|
||
background-color: #f6fffa;
|
||
}
|
||
|
||
.cuIcon-check {
|
||
position: absolute;
|
||
right: 36rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
background-color: #27c866;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
}
|
||
|
||
.cuIcon-check::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 10rpx;
|
||
top: 16rpx;
|
||
width: 12rpx;
|
||
height: 6rpx;
|
||
border-bottom: 4rpx solid white;
|
||
border-left: 4rpx solid white;
|
||
transform: rotate(-45deg);
|
||
}
|
||
|
||
scroll-view ::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
</style> |