419 lines
8.9 KiB
Vue
419 lines
8.9 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="unavailable-time-page">
|
|||
|
|
<!-- 顶部导航栏 -->
|
|||
|
|
<custom-navbar
|
|||
|
|
title="不可服务时间"
|
|||
|
|
:show-back="true"
|
|||
|
|
></custom-navbar>
|
|||
|
|
|
|||
|
|
<!-- 内容区域 -->
|
|||
|
|
<view class="content">
|
|||
|
|
<!-- 已添加的时间段列表 -->
|
|||
|
|
<view class="time-list">
|
|||
|
|
<view
|
|||
|
|
v-for="(item, index) in timeSlots"
|
|||
|
|
:key="item.id"
|
|||
|
|
class="time-item"
|
|||
|
|
>
|
|||
|
|
<view class="time-info">
|
|||
|
|
<text class="date">{{item.date}}</text>
|
|||
|
|
<text class="time">{{item.time_start}}-{{item.time_end}}</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="action-btns">
|
|||
|
|
<text class="delete-btn" @click="deleteTimeSlot(item.id)">删除</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 添加新时间段按钮 -->
|
|||
|
|
<view class="add-btn"
|
|||
|
|
@click="showTimePicker">
|
|||
|
|
<text class="add-icon">+</text>
|
|||
|
|
<text class="add-text">添加不可服务时间</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 时间选择弹窗 -->
|
|||
|
|
<view class="popup"
|
|||
|
|
v-if="showTimePickerFlag"
|
|||
|
|
:class="{ show: showTimePickerFlag }">
|
|||
|
|
<view class="popup-mask" @click="closeTimePicker"></view>
|
|||
|
|
<view class="time-picker">
|
|||
|
|
<view class="picker-header">
|
|||
|
|
<text class="cancel-btn" @click="closeTimePicker">取消</text>
|
|||
|
|
<text class="title">选择时间</text>
|
|||
|
|
<text class="confirm-btn" @click="confirmTime">确定</text>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="picker-content">
|
|||
|
|
<!-- 日期选择 -->
|
|||
|
|
<view class="date-picker">
|
|||
|
|
<text class="label">日期</text>
|
|||
|
|
<picker
|
|||
|
|
mode="date"
|
|||
|
|
:value="currentDate"
|
|||
|
|
:start="minDate"
|
|||
|
|
@change="handleDateChange"
|
|||
|
|
>
|
|||
|
|
<view class="picker-value">{{currentDate}}</view>
|
|||
|
|
</picker>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 开始时间选择 -->
|
|||
|
|
<view class="time-picker-item">
|
|||
|
|
<text class="label">开始时间</text>
|
|||
|
|
<picker
|
|||
|
|
mode="time"
|
|||
|
|
:value="startTime"
|
|||
|
|
@change="handleStartTimeChange"
|
|||
|
|
>
|
|||
|
|
<view class="picker-value">{{startTime}}</view>
|
|||
|
|
</picker>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 结束时间选择 -->
|
|||
|
|
<view class="time-picker-item">
|
|||
|
|
<text class="label">结束时间</text>
|
|||
|
|
<picker
|
|||
|
|
mode="time"
|
|||
|
|
:value="endTime"
|
|||
|
|
:start="minTime"
|
|||
|
|
@change="handleEndTimeChange"
|
|||
|
|
>
|
|||
|
|
<view class="picker-value">{{endTime}}</view>
|
|||
|
|
</picker>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import request from '../../utils/request'
|
|||
|
|
export default {
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
timeSlots: [], // 已添加的时间段列表
|
|||
|
|
currentDate: '', // 当前选择的日期
|
|||
|
|
startTime: '08:00', // 开始时间
|
|||
|
|
endTime: '18:00', // 结束时间
|
|||
|
|
minDate: '09:00', // 最小可选日期(今天)
|
|||
|
|
// maxDate: '', // 最大可选日期(3个月后)
|
|||
|
|
minTime: '', // 最小可选时间
|
|||
|
|
editingIndex: -1 ,// 正在编辑的时间段索引
|
|||
|
|
showTimePickerFlag: false,
|
|||
|
|
id: null,
|
|||
|
|
account: ''
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
created() {
|
|||
|
|
// 初始化日期范围
|
|||
|
|
const today = new Date()
|
|||
|
|
this.currentDate = this.formatDate(today)
|
|||
|
|
this.minDate = this.formatDate(today)
|
|||
|
|
// const threeMonthsLater = new Date()
|
|||
|
|
// threeMonthsLater.setMonth(today.getMonth() + 3)
|
|||
|
|
// this.maxDate = this.formatDate(threeMonthsLater)
|
|||
|
|
this.getUserInfo();
|
|||
|
|
this.getOffserverlist();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
methods: {
|
|||
|
|
getUserInfo() {
|
|||
|
|
request.post('/user/getuser',{type: 2}).then(result=>{
|
|||
|
|
this.account = result.data.account;
|
|||
|
|
this.id = result.data.id;
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
getOffserverlist() {
|
|||
|
|
request.post('/user/offserverlist').then(res=>{
|
|||
|
|
if(res.state == 1) {
|
|||
|
|
this.timeSlots = res.data;
|
|||
|
|
}else {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: res.msg,
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
// 显示时间选择器
|
|||
|
|
showTimePicker() {
|
|||
|
|
// console.log(1111)
|
|||
|
|
//this.editingIndex = -1;
|
|||
|
|
this.showTimePickerFlag = true;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 关闭时间选择器
|
|||
|
|
closeTimePicker() {
|
|||
|
|
this.showTimePickerFlag = false;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 确认选择的时间
|
|||
|
|
confirmTime() {
|
|||
|
|
if (this.validateTime()) {
|
|||
|
|
const data = {
|
|||
|
|
date: this.currentDate,
|
|||
|
|
time_start: `${this.currentDate} ${this.startTime}:00`,
|
|||
|
|
time_end: `${this.currentDate} ${this.endTime}:00`,
|
|||
|
|
user_syr_id: this.id,
|
|||
|
|
phone: this.account
|
|||
|
|
}
|
|||
|
|
// 添加新时间段
|
|||
|
|
request.post('/user/addrelaxtime',data).then(res=>{
|
|||
|
|
if(res.state == 1) {
|
|||
|
|
this.getOffserverlist()
|
|||
|
|
this.closeTimePicker()
|
|||
|
|
}
|
|||
|
|
uni.showToast({
|
|||
|
|
title: res.msg,
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 删除时间段
|
|||
|
|
deleteTimeSlot(id) {
|
|||
|
|
uni.showModal({
|
|||
|
|
title: '提示',
|
|||
|
|
content: '确定要删除这个时间段吗?',
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
request.post('/user/delrelaxtime',{id}).then(res=>{
|
|||
|
|
if(res.state == 1) {
|
|||
|
|
this.getOffserverlist()
|
|||
|
|
}
|
|||
|
|
uni.showToast({
|
|||
|
|
title: res.msg,
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 处理日期变化
|
|||
|
|
handleDateChange(e) {
|
|||
|
|
this.currentDate = e.detail.value
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 处理开始时间变化
|
|||
|
|
handleStartTimeChange(e) {
|
|||
|
|
this.startTime = e.detail.value;
|
|||
|
|
var timeStrs = this.startTime.split(":");
|
|||
|
|
var hour = parseInt(timeStrs[0]) + 1;
|
|||
|
|
this.minTime = hour + ':00';
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 处理结束时间变化
|
|||
|
|
handleEndTimeChange(e) {
|
|||
|
|
this.endTime = e.detail.value
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 验证时间选择是否有效
|
|||
|
|
validateTime() {
|
|||
|
|
const start = new Date(`${this.currentDate} ${this.startTime}`)
|
|||
|
|
const end = new Date(`${this.currentDate} ${this.endTime}`)
|
|||
|
|
|
|||
|
|
if (end <= start) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '结束时间必须晚于开始时间',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 格式化日期为 YYYY-MM-DD
|
|||
|
|
formatDate(date) {
|
|||
|
|
const year = date.getFullYear()
|
|||
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|||
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|||
|
|
return `${year}-${month}-${day}`
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style>
|
|||
|
|
.popup {
|
|||
|
|
position: fixed;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
z-index: 999;
|
|||
|
|
visibility: hidden;
|
|||
|
|
opacity: 0;
|
|||
|
|
transition: all 0.3s ease;
|
|||
|
|
}
|
|||
|
|
.popup.show {
|
|||
|
|
visibility: visible;
|
|||
|
|
opacity: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.popup-mask {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.content {
|
|||
|
|
padding: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.time-list {
|
|||
|
|
margin-bottom: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.time-item {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 24rpx;
|
|||
|
|
background-color: #FFFFFF;
|
|||
|
|
border-radius: 12rpx;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.time-info {
|
|||
|
|
flex: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.date {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
margin-bottom: 8rpx;
|
|||
|
|
display: block;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.time {
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #666666;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.action-btns {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.delete-btn {
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
padding: 8rpx 16rpx;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.delete-btn {
|
|||
|
|
color: #999999;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-btn {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
height: 88rpx;
|
|||
|
|
background-color: #FFFFFF;
|
|||
|
|
border-radius: 12rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-icon {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #E8101E;
|
|||
|
|
margin-right: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-text {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.time-picker {
|
|||
|
|
background-color: #FFFFFF;
|
|||
|
|
border-radius: 24rpx 24rpx 0 0;
|
|||
|
|
transform: translateY(100%);
|
|||
|
|
transition: transform 0.3s ease;
|
|||
|
|
padding-bottom: constant(safe-area-inset-bottom);
|
|||
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.popup.show .time-picker {
|
|||
|
|
transform: translateY(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.picker-header {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 24rpx;
|
|||
|
|
border-bottom: 1rpx solid #F0F0F0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cancel-btn,
|
|||
|
|
.confirm-btn {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
padding: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cancel-btn {
|
|||
|
|
color: #999999;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.confirm-btn {
|
|||
|
|
color: #E8101E;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.title {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.picker-content {
|
|||
|
|
padding: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.date-picker,
|
|||
|
|
.time-picker-item {
|
|||
|
|
margin-bottom: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.label {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
display: block;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.picker-value {
|
|||
|
|
height: 80rpx;
|
|||
|
|
line-height: 80rpx;
|
|||
|
|
background-color: #F5F5F5;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
padding: 0 24rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* APP适配 */
|
|||
|
|
/* #ifdef APP-PLUS */
|
|||
|
|
.time-picker {
|
|||
|
|
padding-bottom: 0;
|
|||
|
|
}
|
|||
|
|
/* #endif */
|
|||
|
|
|
|||
|
|
/* 小程序适配 */
|
|||
|
|
/* #ifdef MP-WEIXIN */
|
|||
|
|
.time-picker {
|
|||
|
|
padding-bottom: constant(safe-area-inset-bottom);
|
|||
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|||
|
|
}
|
|||
|
|
/* #endif */
|
|||
|
|
</style>
|