mrr.sj.front/components/select-time-page/select-time-page.vue

452 lines
11 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>
<uni-popup ref="popup" type="bottom" border-radius="20rpx">
<view class="time-popup">
<view class="popup-header">
<text class="popup-title">请选择服务时间</text>
<text class="popup-close" @click="closeTime">取消</text>
</view>
<view class="time-picker-content">
<!-- 日期选择 -->
<view class="time-picker-content__datas">
<view
class="time-picker-content__datas__date__item"
v-for="(date, index) in dateList"
:key="index"
@click="selectDate(index)"
>
<view class="time-picker-content__datas__date__item__box">
<image
src="/static/images/dataBox.png"
class="time-picker-content__datas__date__item__box__img"
v-if="selectedDateIndex == index"
></image>
</view>
<text
class="time-picker-content__datas__date__item__text"
:class="selectedDateIndex === index ? 'active' : ''"
>{{ date }}</text
>
</view>
</view>
<!-- 时间选择 -->
<scroll-view scroll-y="true" style="height: 600rpx; width: 690rpx">
<view class="time-picker-content__time__list" v-if="timeOptions[selectedDateIndex] && timeOptions[selectedDateIndex].length">
<view
class="time-picker-content__time__list__item"
v-for="(time, index) in timeOptions[selectedDateIndex]"
:key="index"
:class="[getItemClass(time.state || 0),{
lastActive:selectedTimeIndex + serviceTimeNum==index,
firstActive:selectedTimeIndex==index,
isActive:
index >= selectedTimeIndex && index <= selectedTimeIndex + serviceTimeNum &&
sureTimeDataIndex === selectedDateIndex &&
selectedTimeIndex !== null,
}]"
@click="selectTime(time, index)"
>
<text class="time-picker-content__time__list__item__text">{{
time.show_time
}}</text>
<!-- <text class="time-picker-content__time__list__item__state">{{
time.stateName || getStateText(time.state)
}}</text> -->
</view>
</view>
</scroll-view>
<view class="time-picker-content__time__sure">
<view class="time-picker-content__time__sure__box" @click="sureTime">
<text class="time-picker-content__time__sure__box__text">确认</text>
</view>
</view>
</view>
</view>
</uni-popup>
</template>
<script>
/**
* sureTime 确认时间触发事件
* openTime 打开时间选择弹框
* closeTime 关闭时间选择弹框
* selectDate 选择日期
* selectTime 选择时间
* getItemClass 获取列表项的class
* handelGetTimeArr 获取时间段,
*/
import request from "@/utils/request";
export default {
data() {
return {
isFirstOPen: true,
sureTimeObj: {}, // 确认时间对象
dateList: ["今天", "明天", "后天"],
selectedTimeIndex: "", // 选中的时间索引
serviceTimeNum: 1, // 服务时间段数量
sureTimeDataIndex: null, // 确认的时间索引
selectedDateIndex: 0, // 选中的日期索引
startTimeObj: {
serviceTimeNum: "", // 服务时间段数量
sureTimeDataIndex: 0, // 确认的时间索引
selectedDateIndex: 0, // 选中的日期索引
}, // 开始时间对象
// 状态映射配置
stateConfig: {
1: {
class: "state-available",
text: "可约",
},
2: {
class: "state-full",
text: "约满",
},
3: {
class: "state-rest",
text: "休息",
},
4: {
class: "state-locked",
text: "锁定",
},
5: {
class: "state-unavailable",
text: "不可用",
},
},
};
},
props: {
// 时间选项数组
timeOptions: {
type: Array,
default: () => [],
},
// 初始时间索引
firstTimeIndex: {
type: Number,
default: 0,
},
// 初始日期索引
firstDataIndex: {
type: Number,
default: 1,
},
// 服务信息
service: {
type: Object,
default: () => ({}),
},
publish_user_id: {
type: Number,
default: 0,
},
server_type: {
type: Number,
default: 0,
},
},
watch: {
service: {
handler(newValue) {
this.serviceTimeNum = Math.max(1, Math.ceil((newValue.server_time || 0) / 10));
},
deep: true,
immediate: true,
},
},
created() {},
mounted() {},
methods: {
openTime() {
console.log("打开时间选择弹框", this.selectedDateIndex);
this.isFirstOPen = false;
this.startTimeObj = {
selectedTimeIndex: this.selectedTimeIndex,
sureTimeDataIndex: this.sureTimeDataIndex,
selectedDateIndex: this.selectedDateIndex,
};
this.$refs.popup.open("bottom");
},
// 获取状态文本
getStateText(state) {
return this.stateConfig[state]?.text || "未知";
},
// 列表项的class获取方法
getItemClass(state) {
const _state = state || 0;
return this.stateConfig[_state]?.class || "state-unknown";
},
// 选择日期
selectDate(index) {
this.selectedDateIndex = index;
},
selectTime(time, index) {
if (time.state === 1) {
// 可约状态
let parms = {
user_syr_id: this.publish_user_id || this.service.publish_user_id,
reserve_time: this.timeOptions[this.selectedDateIndex][index].time,
server_id: this.service.id,
server_type: this.server_type,
};
request
.post("/user/reserve/timeCheck", parms)
.then((res) => {
if (res.code == 200) {
this.selectedTimeIndex = index;
this.sureTimeDataIndex = this.selectedDateIndex; // 更新确认时间索引
this.sureTimeObj = {
selectedDateIndex: this.selectedDateIndex,
selectedTimeIndex: this.selectedTimeIndex,
time: this.timeOptions[this.selectedDateIndex][
this.selectedTimeIndex
],
res: res,
};
this.$emit("selectTime", this.sureTimeObj);
} else {
uni.showToast({
title: "当前时间不可预约",
icon: "none",
duration: 1000,
});
}
})
.catch((err) => {
console.log("报错", err);
});
}
},
sureTime() {
this.$refs.popup.close();
this.$emit("sureTime", this.sureTimeObj);
},
handelGetTimeArr(time = null) {
// 获取时间段
let date = {
selectedDateIndex: this.selectedDateIndex,
selectedTimeIndex: this.selectedTimeIndex,
time: this.timeOptions[this.selectedDateIndex][this.selectedTimeIndex],
};
this.$emit("getTimeArr", date);
},
closeTime() {
// 关闭时间选择弹框
this.selectedTimeIndex = this.startTimeObj.selectedTimeIndex;
this.sureTimeDataIndex = this.startTimeObj.sureTimeDataIndex;
this.selectedDateIndex = this.startTimeObj.selectedDateIndex;
this.$refs.popup.close();
this.$emit("closeTime");
},
},
};
</script>
<style>
/* 全局样式nvue不支持scoped和less需使用普通css */
/* 时间选择弹框 */
.time-popup {
background-color: #ffffff;
border-radius: 24rpx 24rpx 0 0;
overflow: hidden;
transform: translateY(0);
transition: transform 0.3s;
z-index: 999;
}
.popup-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 30rpx 30rpx 36rpx 30rpx;
}
.popup-close {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 26rpx;
color: #999999;
line-height: 37rpx;
text-align: left;
font-style: normal;
}
.popup-title {
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 42rpx;
text-align: left;
font-style: normal;
}
.time-picker-content {
padding: 32rpx 32rpx;
display: flex;
flex-wrap: wrap;
flex-direction: row;
width: 750rpx;
}
.time-picker-content__datas {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
width: 690rpx;
justify-content: space-between;
margin-bottom: 30rpx;
}
.time-picker-content__datas__date__item {
width: 214rpx;
height: 70rpx;
background: #f7f8fa;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.time-picker-content__datas__date__item__text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 26rpx;
color: #333333;
line-height: 37rpx;
text-align: left;
font-style: normal;
z-index: 2;
position: relative;
}
.time-picker-content__datas__date__item__text.active {
color: #ffffff;
}
.time-picker-content__datas__date__item__box {
width: 214rpx;
height: 74rpx;
position: absolute;
z-index: 1;
margin-bottom: 8rpx;
}
.time-picker-content__datas__date__item__box__img {
width: 214rpx;
height: 74rpx;
}
.time-picker-content__time__list {
width: 690rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.time-picker-content__time__list__item {
width: 114rpx;
height: 66rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 26rpx;
}
.time-picker-content__time__list__item__text {
font-weight: 400;
font-size: 30rpx;
color: #333333;
line-height: 66rpx;
text-align: center;
font-style: normal;
}
.time-picker-content__time__list__item__state {
font-size: 20rpx;
}
/* 状态样式 */
.state-available {
color: #3c3638;
/* background: #f7f8fa; */
}
.state-full {
color: #3c3638;
background: #e4e9f0;
}
.state-rest {
color: #cdcdcd;
background: #f7f8f9;
}
.state-locked {
color: #3c3638;
background: #e4e9f0;
}
.state-unavailable {
color: #ffffff;
background: #e4e9f0;
}
.state-unknown {
color: #999999;
background: #f7f8fa;
}
.isActive {
background: rgba(252, 67, 124, 0.08);
color: #FF4767 !important;
}
.isActive .time-picker-content__time__list__item__text {
color: #FF4767 !important;
}
/* 选中样式前后弧度 */
.firstActive {
border-radius: 51rpx 0rpx 0rpx 51rpx;
}
.lastActive {
border-radius: 0rpx 51rpx 51rpx 0rpx}
.time-picker-content__time__sure {
padding: 39rpx 0;
display: flex;
flex-direction: row;
width: 690rpx;
justify-content: center;
}
.time-picker-content__time__sure__box {
width: 648rpx;
height: 94rpx;
background: #FF4767;
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
}
.time-picker-content__time__sure__box__text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 30rpx;
color: #ffffff;
line-height: 42rpx;
text-align: center;
font-style: normal;
}
</style>