This commit is contained in:
zpc 2025-12-08 01:08:53 +08:00
parent 316d1e2b5d
commit 05ad1348cf
3 changed files with 570 additions and 520 deletions

View File

@ -6,11 +6,12 @@
// 开发环境配置
const development = {
// API基础URL
// baseUrl: 'https://sqqp.zpc-xy.com',
// baseUrl: 'http://1.15.21.245:2401',
// host: ['https://sqqp.zpc-xy.com'],
baseUrl: 'http://192.168.1.24:2016',
host: ['http://192.168.1.24:2016'],
baseUrl: 'https://sqqp.zpc-xy.com',
host: ['https://sqqp.zpc-xy.com'],
// baseUrl: 'http://192.168.195.15:2401',
// host: ['http://192.168.195.15:2401'],
// baseUrl: 'http://192.168.1.24:2016',
// host: ['http://192.168.1.24:2016'],
imageUrl: 'https://guyu-1308826010.cos.ap-shanghai.myqcloud.com',
};

View File

@ -1131,6 +1131,10 @@ const onCustomDepositInput = (val) => {
maxPlayerCount.value = detail.capacity;
const t = [];
peopleText.value = "请选择游玩人数";
t.push({
value: 1,
text:'无需组局'
});
for (let i = 2; i <= detail.capacity; i++) {
t.push({
value: i,

View File

@ -5,16 +5,16 @@
<view style="flex: 1;"></view>
<text class="page-title">发起预约</text>
<view class="row" style="width: 90%; height: 120rpx; margin: 20rpx auto 0;">
<view class="column center" v-for="(item,index) in dateList" :key="index" :style="setBgColor(index)"
<view class="column center" v-for="(item, index) in dateList" :key="index" :style="setBgColor(index)"
@click="clickTime(index)" style="width: 96rpx; height: 100%;">
<text style="font-size: 26rpx;">{{item.time}}</text>
<text style="font-size: 22rpx;">{{item.weekday}}</text>
<text style="font-size: 26rpx;">{{ item.time }}</text>
<text style="font-size: 22rpx;">{{ item.weekday }}</text>
</view>
</view>
</view>
<text style="margin-top: 20rpx; margin-left: 32rpx; font-size: 24rpx;">营业时间早00点 晚23点</text>
<text style="margin-top: 20rpx; margin-left: 32rpx; font-size: 24rpx;">{{ getBusinessAnnouncement() }}</text>
<view class="row"
style="width: 686rpx; height: 56rpx; background-color: #2ED9BF; border-radius: 5rpx; margin: 20rpx auto 0; align-items: center;">
@ -56,8 +56,8 @@
<text v-if="item.status === 'using'"
style="font-size: 20rpx; position: absolute; top: 10rpx; right: 16rpx; color: #FF9901;">当前使用中</text>
<view class="center" @click.stop="handleReservation(item)"
style="width: 92rpx; height: 46rpx; background-color: #20BBA4; border-radius: 52rpx; font-size: 26rpx; color: white; position: absolute; bottom: 94rpx; right: 10rpx;">
<view class="center reservation-btn" :class="{ 'reservation-btn-disabled': !hasAvailableSlots(item) }"
@click.stop="hasAvailableSlots(item) && handleReservation(item)">
预约
</view>
@ -72,8 +72,10 @@
<view class="row" style="align-items: center; position: absolute; left: 10rpx; bottom: 14rpx;">
<view class="column center" style="margin-right: 20rpx;" v-for="slot in item.time_slots" :key="slot.slot_type">
<view :style="{ width: '70rpx', height: '4rpx', backgroundColor: getSlotColor(slot.status) }"></view>
<view class="column center" style="margin-right: 20rpx;" v-for="slot in item.time_slots"
:key="slot.slot_type">
<view :style="{ width: '70rpx', height: '4rpx', backgroundColor: getSlotColor(slot.status) }">
</view>
<text style="font-size: 12rpx; margin-top: 4rpx;">{{ slot.slot_name }}</text>
</view>
@ -100,19 +102,14 @@
<scroll-view v-else-if="roomDetail" scroll-y class="popup-content" :style="{ maxHeight: '80vh' }">
<!-- 图片轮播 -->
<view class="detail-swiper-container">
<swiper v-if="roomDetailImages && roomDetailImages.length > 0"
class="detail-swiper"
:indicator-dots="roomDetailImages.length > 1"
:autoplay="false"
:circular="true"
indicator-color="rgba(255, 255, 255, 0.5)"
indicator-active-color="#20BBA4">
<swiper v-if="roomDetailImages && roomDetailImages.length > 0" class="detail-swiper"
:indicator-dots="roomDetailImages.length > 1" :autoplay="false" :circular="true"
indicator-color="rgba(255, 255, 255, 0.5)" indicator-active-color="#20BBA4">
<swiper-item v-for="(img, index) in roomDetailImages" :key="index">
<image :src="img" mode="aspectFill" class="detail-swiper-image"></image>
</swiper-item>
</swiper>
<image v-else :src="roomDetail.image_url || '/static/default_room.jpg'"
mode="aspectFill"
<image v-else :src="roomDetail.image_url || '/static/default_room.jpg'" mode="aspectFill"
class="detail-swiper-image"></image>
</view>
@ -178,8 +175,10 @@
<view class="time-slot-content">
<text class="time-slot-status">{{ getSlotStatusText(slot.status) }}</text>
<view class="time-slot-price">
<text class="time-slot-price-text">标准{{ slot.price_desc_standard || '详询' }}</text>
<text class="time-slot-price-text member">会员{{ slot.price_desc_member || '详询' }}</text>
<text class="time-slot-price-text">标准{{ slot.price_desc_standard || '详询'
}}</text>
<text class="time-slot-price-text member">会员{{ slot.price_desc_member || '详询'
}}</text>
</view>
</view>
</view>
@ -192,7 +191,9 @@
<view class="popup-btn secondary" @click="closeRoomDetail">
<text>关闭</text>
</view>
<view v-if="roomDetail.can_reserve" class="popup-btn primary" @click="handleReservationFromDetail">
<view v-if="roomDetail.can_reserve"
:class="hasAvailableSlots(roomDetail) ? 'popup-btn primary' : 'popup-btn disabled'"
@click="hasAvailableSlots(roomDetail) && handleReservationFromDetail()">
<text>立即预约</text>
</view>
</view>
@ -203,9 +204,9 @@
</template>
<script>
import { getAvailableDates, getRoomListWithSlotsNew, getRoomDetail } from '@/common/server/interface/sq.js';
export default {
import { getAvailableDates, getRoomListWithSlotsNew, getRoomDetail } from '@/common/server/interface/sq.js';
import { getConfigData } from '@/common/server/config';
export default {
data() {
return {
currentTimeIndex: 0,
@ -216,11 +217,15 @@
selectedDate: null, //
roomDetail: null, //
roomDetailLoading: false, //
configData: null,
}
},
onLoad() {
this.loadDates();
getConfigData().then(data => {
this.configData = data;
});
},
methods: {
@ -229,6 +234,9 @@
//
this.loadRoomList();
},
getBusinessAnnouncement() {
return this.configData.config.businessAnnouncement??"营业时间早00点 至 晚23点";
},
/**
* 加载可选日期列表
@ -462,6 +470,19 @@
'using': '使用中'
};
return statusMap[status] || '未知';
},
/**
* 判断房间是否还有可预约的时段
* @param {Object} room 房间对象
* @returns {boolean} true表示还有可预约时段false表示已全部约满
*/
hasAvailableSlots(room) {
if (!room || !room.time_slots || !Array.isArray(room.time_slots)) {
return false;
}
// 'available'
return room.time_slots.some(slot => slot.status === 'available');
}
},
@ -480,34 +501,34 @@
return [];
}
}
}
}
</script>
<style lang="scss">
.content {
.content {
width: 100%;
height: 100vh;
background-color: #F7F7F7;
}
}
/* 页面标题 */
.page-title {
/* 页面标题 */
.page-title {
margin-top: 100rpx;
text-align: center;
margin-bottom: 20rpx;
}
}
/* 房间详情弹窗样式 */
.room-detail-popup {
/* 房间详情弹窗样式 */
.room-detail-popup {
width: 680rpx;
max-height: 80vh;
background-color: #FFFFFF;
border-radius: 20rpx;
position: relative;
overflow: hidden;
}
}
.popup-close {
.popup-close {
position: absolute;
top: 10rpx;
right: 10rpx;
@ -519,208 +540,208 @@
z-index: 10;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 50%;
}
}
.popup-loading {
.popup-loading {
padding: 100rpx 0;
min-height: 400rpx;
}
}
.popup-content {
.popup-content {
width: 100%;
}
}
/* 图片轮播容器 */
.detail-swiper-container {
/* 图片轮播容器 */
.detail-swiper-container {
width: 100%;
height: 400rpx;
background-color: #DEDEDE;
}
}
.detail-swiper {
.detail-swiper {
width: 100%;
height: 100%;
}
}
.detail-swiper-image {
.detail-swiper-image {
width: 100%;
height: 100%;
}
}
/* 详情区域 */
.detail-section {
/* 详情区域 */
.detail-section {
padding: 30rpx;
border-bottom: 1rpx solid #F0F0F0;
}
}
.detail-section:last-child {
.detail-section:last-child {
border-bottom: none;
}
}
.detail-title-row {
.detail-title-row {
display: flex;
align-items: center;
margin-bottom: 10rpx;
}
}
.detail-room-name {
.detail-room-name {
font-size: 36rpx;
font-weight: bold;
color: #262626;
flex: 1;
}
}
.detail-status-tag {
.detail-status-tag {
padding: 4rpx 16rpx;
border-radius: 8rpx;
font-size: 20rpx;
}
}
.detail-status-tag.using {
.detail-status-tag.using {
background-color: #FF9901;
color: #FFFFFF;
}
}
.detail-status-tag.available {
.detail-status-tag.available {
background-color: #52c41a;
color: #FFFFFF;
}
}
.detail-room-type {
.detail-room-type {
font-size: 24rpx;
color: #999999;
margin-bottom: 20rpx;
}
}
.detail-price-row {
.detail-price-row {
display: flex;
align-items: center;
margin-bottom: 10rpx;
}
}
.detail-price-label {
.detail-price-label {
font-size: 24rpx;
color: #666666;
}
}
.detail-price-value {
.detail-price-value {
font-size: 28rpx;
color: #262626;
font-weight: 500;
}
}
.detail-price-member {
.detail-price-member {
font-size: 28rpx;
color: #FF0000;
font-weight: 500;
}
}
.detail-info-row {
.detail-info-row {
display: flex;
align-items: center;
margin-top: 20rpx;
}
}
.detail-info-label {
.detail-info-label {
font-size: 24rpx;
color: #666666;
}
}
.detail-info-value {
.detail-info-value {
font-size: 24rpx;
color: #262626;
}
}
.detail-section-title {
.detail-section-title {
font-size: 28rpx;
font-weight: bold;
color: #262626;
margin-bottom: 20rpx;
display: block;
}
}
.detail-description {
.detail-description {
font-size: 26rpx;
color: #666666;
line-height: 1.6;
}
}
/* 设施标签 */
.amenities-container {
/* 设施标签 */
.amenities-container {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
}
.amenity-tag {
.amenity-tag {
padding: 8rpx 20rpx;
background-color: #F5F5F5;
border-radius: 8rpx;
font-size: 24rpx;
color: #666666;
}
}
/* 时段状态 */
.time-slots-container {
/* 时段状态 */
.time-slots-container {
display: flex;
flex-direction: column;
gap: 20rpx;
}
}
.time-slot-item {
.time-slot-item {
background-color: #F8F8F8;
border-radius: 12rpx;
padding: 20rpx;
}
}
.time-slot-header {
.time-slot-header {
display: flex;
align-items: center;
margin-bottom: 12rpx;
}
}
.time-slot-name {
.time-slot-name {
font-size: 26rpx;
font-weight: 500;
color: #262626;
}
}
.time-slot-content {
.time-slot-content {
display: flex;
flex-direction: column;
gap: 8rpx;
}
}
.time-slot-status {
.time-slot-status {
font-size: 24rpx;
color: #666666;
}
}
.time-slot-price {
.time-slot-price {
display: flex;
align-items: center;
gap: 20rpx;
}
}
.time-slot-price-text {
.time-slot-price-text {
font-size: 22rpx;
color: #666666;
}
}
.time-slot-price-text.member {
.time-slot-price-text.member {
color: #FF0000;
}
}
/* 底部操作按钮 */
.popup-footer {
/* 底部操作按钮 */
.popup-footer {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-top: 1rpx solid #F0F0F0;
gap: 20rpx;
}
}
.popup-btn {
.popup-btn {
flex: 1;
height: 80rpx;
display: flex;
@ -729,15 +750,39 @@
border-radius: 12rpx;
font-size: 28rpx;
font-weight: 500;
}
}
.popup-btn.secondary {
.popup-btn.secondary {
background-color: #F5F5F5;
color: #666666;
}
}
.popup-btn.primary {
.popup-btn.primary {
background-color: #20BBA4;
color: #FFFFFF;
}
}
.popup-btn.disabled {
background-color: #CCCCCC;
color: #FFFFFF;
opacity: 0.6;
}
/* 房间列表预约按钮样式 */
.reservation-btn {
width: 92rpx;
height: 46rpx;
background-color: #20BBA4;
border-radius: 52rpx;
font-size: 26rpx;
color: white;
position: absolute;
bottom: 94rpx;
right: 10rpx;
}
.reservation-btn-disabled {
background-color: #CCCCCC;
opacity: 0.8;
}
</style>