java-mall-app/components/delivery-time-op/delivery-time-op.vue
2025-11-01 16:07:44 +08:00

324 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<!-- 模态框 -->
<view @tap="Modal" :class="{ mask: model }"></view>
<!-- 弹窗主体 -->
<view
:style="{ height: barHidth + 'rpx' }"
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 {
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>