mrr.sj.front/pages/shop/business-time.vue

596 lines
15 KiB
Vue
Raw Normal View History

2026-03-24 11:45:13 +08:00
<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: 3 // 商家类型
})
console.log('获取用户信息响应:', res)
if (res.state === 1 && res.data) {
// 检查营业时间字段
if (res.data.business_time) {
this.currentTime = res.data.business_time
this.originalTime = res.data.business_time
this.parseTimeString(res.data.business_time)
console.log('成功获取营业时间:', res.data.business_time)
} 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,
business_time: this.tempTime
}
console.log('提交参数:', params) // 调试日志
console.log('请求URL:', '/sj/userSjAuth/apply')
const res = await request.post('/sj/userSjAuth/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;
}
.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;
background: #E5E5E5;
border-radius: 43rpx;
color: #333;
// 彻底移除边框
&::after {
border: none;
border-width: 0;
}
}
.btn-confirm-large {
background: #E8101E;
color: white;
}
</style>