598 lines
15 KiB
Vue
598 lines
15 KiB
Vue
<template>
|
||
<view class="service-time-page">
|
||
<!-- 顶部导航栏 -->
|
||
<custom-navbar title="服务时间" :showBack="true"></custom-navbar>
|
||
|
||
<!-- 内容区域 -->
|
||
<view class="content">
|
||
<!-- 服务时间卡片 -->
|
||
<view class="section-card">
|
||
<view class="section-header">
|
||
<view class="title-bar"></view>
|
||
<text class="section-title">服务时间</text>
|
||
</view>
|
||
|
||
<!-- 时间显示 -->
|
||
<view class="time-display-section">
|
||
<view class="time-value-box">
|
||
<text class="time-value">服务时间</text>
|
||
<text class="time-value2">{{ currentTime }}</text>
|
||
</view>
|
||
<view class="change-button" @click="showTimePicker" v-if="!showBottomActions && !showTimePickerFlag">
|
||
<text class="change-text">信息变更 </text>
|
||
<image class="arrow-right" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/b87d4918-4282-4f51-931c-292435ba5d36" mode="aspectFit"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 服务时间选择器(五列选择器) -->
|
||
<view class="popup" :class="{ show: showTimePickerFlag }">
|
||
<view class="popup-mask" @click="hideTimePicker"></view>
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<text class="cancel-text" @click="hideTimePicker">取消</text>
|
||
<text class="title">选择服务时间</text>
|
||
<text class="confirm-text" @click="confirmTime">确定</text>
|
||
</view>
|
||
<view class="time-range">
|
||
<view class="time-block" :class="{ active: timeType === 'start' }"
|
||
@click="switchTimeType('start')">
|
||
<text class="time-value-picker">{{formatTime(startTime)}}</text>
|
||
<text class="time-label">开始时间</text>
|
||
</view>
|
||
<text class="time-separator">至</text>
|
||
<view class="time-block" :class="{ active: timeType === 'end' }"
|
||
@click="switchTimeType('end')">
|
||
<text class="time-value-picker">{{formatTime(endTime)}}</text>
|
||
<text class="time-label">结束时间</text>
|
||
</view>
|
||
</view>
|
||
<view class="region-body">
|
||
<picker-view :value="pickerValue" @change="handleTimeChange" class="picker-scroll"
|
||
:indicator-style="indicatorStyle">
|
||
<picker-view-column>
|
||
<view class="picker-item" v-for="(hour, index) in hours" :key="index">
|
||
{{hour}}
|
||
</view>
|
||
</picker-view-column>
|
||
<picker-view-column>
|
||
<view class="picker-item" v-for="(minute, index) in minutes" :key="index">
|
||
{{minute}}
|
||
</view>
|
||
</picker-view-column>
|
||
<picker-view-column>
|
||
<view class="picker-item">-</view>
|
||
</picker-view-column>
|
||
<picker-view-column>
|
||
<view class="picker-item" v-for="(hour, index) in hours" :key="index">
|
||
{{hour}}
|
||
</view>
|
||
</picker-view-column>
|
||
<picker-view-column>
|
||
<view class="picker-item" v-for="(minute, index) in minutes" :key="index">
|
||
{{minute}}
|
||
</view>
|
||
</picker-view-column>
|
||
</picker-view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部操作按钮(在选择时间后显示) -->
|
||
<view class="bottom-actions" v-if="showBottomActions">
|
||
<view class="action-buttons">
|
||
<button class="btn-cancel-large" @click="cancelChange">取消</button>
|
||
<button class="btn-confirm-large" @click="submitChange">提交</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import request from '@/utils/request.js';
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
currentTime: '09:00-21:00', // 当前服务时间
|
||
originalTime: '09:00-21:00', // 保存原始时间,用于取消时恢复
|
||
tempTime: '', // 临时存储选择的时间
|
||
showTimePickerFlag: false,
|
||
showBottomActions: false, // 控制底部按钮显示
|
||
|
||
// 五列选择器相关数据
|
||
pickerValue: [8, 0, 0, 18, 0],
|
||
hours: Array.from({ length: 24 }, (_, i) => i < 10 ? `0${i}` : `${i}`),
|
||
minutes: Array.from({ length: 60 }, (_, i) => i < 10 ? `0${i}` : `${i}`),
|
||
timeType: 'start',
|
||
indicatorStyle: 'height: 68rpx;',
|
||
|
||
startTime: {
|
||
hour: '09',
|
||
minute: '00'
|
||
},
|
||
endTime: {
|
||
hour: '21',
|
||
minute: '00'
|
||
}
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.loadCurrentTime();
|
||
},
|
||
methods: {
|
||
// 加载当前服务时间
|
||
async loadCurrentTime() {
|
||
try {
|
||
const res = await request.post('/user/getuser', {
|
||
type: 2 // 手艺人类型
|
||
})
|
||
console.log('获取用户信息响应:', res)
|
||
|
||
// 服务时间 default_times
|
||
if (res.state === 1 && res.data) {
|
||
// 检查服务时间字段
|
||
if (res.data.default_times) {
|
||
this.currentTime = res.data.default_times
|
||
this.originalTime = res.data.default_times
|
||
this.parseTimeString(res.data.default_times)
|
||
console.log('成功获取服务时间:', res.data.default_times)
|
||
} else {
|
||
// 如果没有服务时间字段,使用默认值
|
||
console.log('未找到服务时间字段,使用默认值')
|
||
this.currentTime = '09:00-21:00'
|
||
this.originalTime = '09:00-21:00'
|
||
this.parseTimeString('09:00-21:00')
|
||
}
|
||
} else {
|
||
throw new Error(res.msg || '获取用户信息失败')
|
||
}
|
||
} catch (error) {
|
||
console.error('加载服务时间失败:', error)
|
||
// 设置默认值,确保页面能正常操作
|
||
this.currentTime = '09:00-21:00'
|
||
this.originalTime = '09:00-21:00'
|
||
this.parseTimeString('09:00-21:00')
|
||
|
||
// uni.showToast({
|
||
// title: '加载服务时间失败,使用默认时间',
|
||
// icon: 'none'
|
||
// })
|
||
}
|
||
},
|
||
|
||
// 解析时间字符串到开始和结束时间
|
||
parseTimeString(timeStr) {
|
||
const times = timeStr.split('-')
|
||
if (times.length === 2) {
|
||
const startParts = times[0].split(':')
|
||
const endParts = times[1].split(':')
|
||
|
||
if (startParts.length === 2) {
|
||
this.startTime.hour = startParts[0]
|
||
this.startTime.minute = startParts[1]
|
||
}
|
||
if (endParts.length === 2) {
|
||
this.endTime.hour = endParts[0]
|
||
this.endTime.minute = endParts[1]
|
||
}
|
||
|
||
this.updatePickerValue()
|
||
}
|
||
},
|
||
|
||
// 更新picker值
|
||
updatePickerValue() {
|
||
const startHourIndex = this.hours.indexOf(this.startTime.hour)
|
||
const startMinuteIndex = this.minutes.indexOf(this.startTime.minute)
|
||
const endHourIndex = this.hours.indexOf(this.endTime.hour)
|
||
const endMinuteIndex = this.minutes.indexOf(this.endTime.minute)
|
||
|
||
this.pickerValue = [
|
||
startHourIndex >= 0 ? startHourIndex : 8,
|
||
startMinuteIndex >= 0 ? startMinuteIndex : 0,
|
||
0, // 分隔符固定位置
|
||
endHourIndex >= 0 ? endHourIndex : 18,
|
||
endMinuteIndex >= 0 ? endMinuteIndex : 0
|
||
]
|
||
},
|
||
|
||
// 显示时间选择器
|
||
showTimePicker() {
|
||
// 保存原始时间,用于取消时恢复
|
||
this.originalTime = this.currentTime
|
||
this.showTimePickerFlag = true;
|
||
},
|
||
|
||
// 隐藏时间选择器
|
||
hideTimePicker() {
|
||
this.showTimePickerFlag = false;
|
||
},
|
||
|
||
// 切换时间类型(开始/结束)
|
||
switchTimeType(type) {
|
||
this.timeType = type;
|
||
},
|
||
|
||
// 处理时间变化
|
||
handleTimeChange(e) {
|
||
const values = e.detail.value;
|
||
this.pickerValue = values;
|
||
|
||
// 更新开始时间
|
||
this.startTime.hour = this.hours[values[0]]
|
||
this.startTime.minute = this.minutes[values[1]]
|
||
|
||
// 更新结束时间
|
||
this.endTime.hour = this.hours[values[3]]
|
||
this.endTime.minute = this.minutes[values[4]]
|
||
},
|
||
|
||
// 格式化时间显示
|
||
formatTime(time) {
|
||
return `${time.hour}:${time.minute}`
|
||
},
|
||
|
||
// 确认时间选择
|
||
confirmTime() {
|
||
const newTime = `${this.formatTime(this.startTime)}-${this.formatTime(this.endTime)}`
|
||
|
||
console.log('选择的时间:', newTime) // 调试日志
|
||
|
||
// 验证时间合理性
|
||
if (!this.validateTime(this.startTime, this.endTime)) {
|
||
uni.showToast({
|
||
title: '结束时间必须晚于开始时间',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
this.tempTime = newTime
|
||
this.showBottomActions = true
|
||
this.hideTimePicker()
|
||
|
||
// 立即更新页面显示
|
||
this.currentTime = newTime
|
||
console.log('临时存储的时间:', this.tempTime) // 调试日志
|
||
},
|
||
|
||
// 取消变更
|
||
cancelChange() {
|
||
// 恢复原来的时间
|
||
this.currentTime = this.originalTime
|
||
this.showBottomActions = false
|
||
this.tempTime = ''
|
||
},
|
||
|
||
// 提交变更
|
||
async submitChange() {
|
||
if (!this.tempTime) {
|
||
uni.showToast({
|
||
title: '请先选择服务时间',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
try {
|
||
// uni.showLoading({
|
||
// title: '提交中...'
|
||
// })
|
||
|
||
const params = {
|
||
apply_type: 1,
|
||
default_times: this.tempTime
|
||
}
|
||
console.log('提交参数:', params) // 调试日志
|
||
console.log('请求URL:', '/syr/userSyrAuth/apply')
|
||
|
||
const res = await request.post('/syr/userSyrAuth/apply', params)
|
||
|
||
uni.hideLoading()
|
||
console.log('提交接口响应:', res)
|
||
|
||
// 根据接口文档,使用 code 判断成功
|
||
if (res.code === 200) {
|
||
this.showBottomActions = false
|
||
this.tempTime = ''
|
||
this.originalTime = this.currentTime // 更新原始时间
|
||
|
||
uni.showToast({
|
||
title: '服务时间更新成功',
|
||
icon: 'none'
|
||
})
|
||
|
||
setTimeout(() => {
|
||
uni.navigateBack()
|
||
}, 1500)
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg || '提交失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading()
|
||
console.error('提交服务时间变更失败:', error)
|
||
uni.showToast({
|
||
title: '提交失败,请重试',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
|
||
|
||
// 验证时间合理性
|
||
validateTime(startTime, endTime) {
|
||
const start = new Date(`2000/01/01 ${startTime.hour}:${startTime.minute}`)
|
||
const end = new Date(`2000/01/01 ${endTime.hour}:${endTime.minute}`)
|
||
return end > start
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.service-time-page {
|
||
min-height: 100vh;
|
||
background-color: #f5f5f5;
|
||
padding-bottom: 140rpx;
|
||
}
|
||
|
||
.content {
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.section-card {
|
||
background: white;
|
||
border-radius: 20rpx;
|
||
padding: 22rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.section-header {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 500;
|
||
font-size: 32rpx;
|
||
color: #1D2129;
|
||
line-height: 48rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.title-bar {
|
||
width: 6rpx;
|
||
height: 30rpx;
|
||
background-color: #E8101E;
|
||
margin-right: 10rpx;
|
||
border-radius: 5rpx;
|
||
}
|
||
|
||
.time-display-section {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 20rpx 0 10rpx 0 ;
|
||
}
|
||
|
||
.time-value-box {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
line-height: 40rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
margin-left: 16rpx;
|
||
}
|
||
|
||
.time-value {
|
||
margin-right: 15rpx;
|
||
}
|
||
.time-value2 {
|
||
font-weight: 500;
|
||
}
|
||
|
||
.change-button {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.change-text {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 28rpx;
|
||
color: #E8101E;
|
||
line-height: 40rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.arrow-right {
|
||
margin-left: 10rpx;
|
||
width: 11rpx;
|
||
height: 22rpx;
|
||
}
|
||
|
||
/* 五列选择器样式 */
|
||
.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);
|
||
}
|
||
|
||
.popup-content {
|
||
position: relative;
|
||
background-color: #FFFFFF;
|
||
border-radius: 24rpx 24rpx 0 0;
|
||
padding: 32rpx;
|
||
transform: translateY(100%);
|
||
transition: transform 0.3s ease;
|
||
max-height: 70vh;
|
||
}
|
||
|
||
.popup.show .popup-content {
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.popup-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.cancel-text {
|
||
font-size: 32rpx;
|
||
color: #666666;
|
||
}
|
||
|
||
.confirm-text {
|
||
font-size: 32rpx;
|
||
color: #E8101E;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.title {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 服务时间选择器样式 */
|
||
.time-range {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 32rpx;
|
||
background: #F8F9FC;
|
||
border-radius: 12rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.time-block {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
background: #FFFFFF;
|
||
border-radius: 12rpx;
|
||
padding: 24rpx 0;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.time-block.active {
|
||
background: #ECF2FF;
|
||
}
|
||
|
||
.time-label {
|
||
font-size: 26rpx;
|
||
color: #999999;
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
/* 修复样式冲突 - 使用不同的类名 */
|
||
.time-value-picker {
|
||
font-size: 40rpx;
|
||
color: #333333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.time-block.active .time-value-picker {
|
||
color: #E8101E;
|
||
}
|
||
|
||
.time-separator {
|
||
font-size: 28rpx;
|
||
color: #999999;
|
||
margin: 0 24rpx;
|
||
}
|
||
|
||
.region-body {
|
||
height: 400rpx;
|
||
}
|
||
|
||
.picker-scroll {
|
||
height: 400rpx;
|
||
}
|
||
|
||
.picker-item {
|
||
height: 68rpx;
|
||
line-height: 68rpx;
|
||
text-align: center;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
/* 底部操作按钮样式 */
|
||
.bottom-actions {
|
||
margin-top: 80rpx;
|
||
background: transparent;
|
||
padding: 0 45rpx;
|
||
}
|
||
|
||
.action-buttons {
|
||
display: flex;
|
||
gap: 50rpx;
|
||
}
|
||
|
||
.btn-cancel-large, .btn-confirm-large {
|
||
font-size: 34rpx;
|
||
flex: 1;
|
||
font-weight: 400;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border: none;
|
||
width: 290rpx;
|
||
height: 86rpx;
|
||
background: linear-gradient( 180deg, #F52540 0%, #E8101E 100%, #E8101E 100%);
|
||
border-radius: 43rpx;
|
||
}
|
||
|
||
.btn-cancel-large {
|
||
font-size: 34rpx;
|
||
border: none !important;
|
||
border-width: 0; // 确保边框宽度为0
|
||
background: #E5E5E5;
|
||
border-radius: 43rpx;
|
||
color: #333;
|
||
|
||
// 彻底移除边框
|
||
&::after {
|
||
border: none;
|
||
border-width: 0;
|
||
}
|
||
}
|
||
|
||
.btn-confirm-large {
|
||
background: #E8101E;
|
||
color: white;
|
||
}
|
||
</style> |