333
This commit is contained in:
parent
35ee8ea96c
commit
3648e6247f
|
|
@ -80,7 +80,7 @@ function calculateTimeRange(time1, time2) {
|
|||
* @returns {string} - 返回 '今天' | '明天' | '后天' | '其他'
|
||||
*/
|
||||
function getDayDescription(input) {
|
||||
|
||||
|
||||
|
||||
if (input == null || input == "" || input == 0) {
|
||||
return "请选择时间";
|
||||
|
|
@ -103,4 +103,30 @@ function getDayDescription(input) {
|
|||
return target.format('MM-DD ' + tips + ' HH:mm')
|
||||
}
|
||||
|
||||
export { parseTimeString, formatTime, calculateTimeRange, getDayDescription }
|
||||
|
||||
|
||||
/**
|
||||
* 将传入的时间的分钟数 向上取整到最近的 5 的倍数
|
||||
* 比如:1 → 5,6 → 10,58 → 00(且进位到下一小时),59 → 00(进位)
|
||||
* @param {Date|number|string|dayjs} inputTime - 可以是时间戳、Date 对象、ISO 字符串、dayjs 对象
|
||||
* @returns {dayjs} 返回调整后的 dayjs 对象,分钟是 5 的倍数,且进位正确
|
||||
*/
|
||||
function ceilMinuteToNext5(inputTime) {
|
||||
const t = dayjs(inputTime) // 支持多种时间格式
|
||||
|
||||
const m = t.minute()
|
||||
const s = t.second()
|
||||
|
||||
// 向上取整到最近的 5 的倍数
|
||||
const nextMin = Math.ceil(m / 5) * 5
|
||||
|
||||
if (nextMin === 60) {
|
||||
// 59 → 60 → 变成下一小时的 00 分
|
||||
return t.add(1, 'hour').minute(0).second(0)
|
||||
}
|
||||
|
||||
// 否则正常设置分钟,并清空秒
|
||||
return t.minute(nextMin).second(0)
|
||||
}
|
||||
|
||||
export { parseTimeString, formatTime, calculateTimeRange, getDayDescription, ceilMinuteToNext5 }
|
||||
|
|
|
|||
3
components.d.ts
vendored
3
components.d.ts
vendored
|
|
@ -8,9 +8,11 @@ export {}
|
|||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
CardContainer: typeof import('./components/com/appointment/card-container.vue')['default']
|
||||
Container: typeof import('./components/com/page/container.vue')['default']
|
||||
ContainerBase: typeof import('./components/com/page/container-base.vue')['default']
|
||||
LabelField: typeof import('./components/com/appointment/label-field.vue')['default']
|
||||
LabelSlectField: typeof import('./components/com/appointment/label-slect-field.vue')['default']
|
||||
MahjongCard: typeof import('./components/index/MahjongCard.vue')['default']
|
||||
NoData: typeof import('./components/com/page/no-data.vue')['default']
|
||||
NoEmpty: typeof import('./components/com/index/NoEmpty.vue')['default']
|
||||
|
|
@ -19,6 +21,7 @@ declare module 'vue' {
|
|||
ReservationPopup: typeof import('./components/com/index/ReservationPopup.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
TagSelect: typeof import('./components/com/appointment/tag-select.vue')['default']
|
||||
TimeSelectCell: typeof import('./components/com/appointment/time-select-cell.vue')['default']
|
||||
UniNavBar: typeof import('./components/uni-nav-bar/uni-nav-bar.vue')['default']
|
||||
UniStatusBar: typeof import('./components/uni-nav-bar/uni-status-bar.vue')['default']
|
||||
|
|
|
|||
41
components/com/appointment/card-container.vue
Normal file
41
components/com/appointment/card-container.vue
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<view class="card column" :style="cardStyle">
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
width: { type: String, default: '90%' },
|
||||
bgColor: { type: String, default: '#FFFFFF' },
|
||||
radius: { type: String, default: '10rpx' },
|
||||
marginTop: { type: String, default: '20rpx' },
|
||||
padding: { type: String, default: '20rpx 0rpx 30rpx 0rpx' },
|
||||
boxShadow: { type: Boolean, default: true },
|
||||
justify: { type: String, default: 'center' }
|
||||
})
|
||||
|
||||
const cardStyle = computed(() => {
|
||||
const style = {
|
||||
width: props.width,
|
||||
backgroundColor: props.bgColor,
|
||||
borderRadius: props.radius,
|
||||
margin: `${props.marginTop} auto 0`,
|
||||
display: 'flex',
|
||||
justifyContent: props.justify
|
||||
}
|
||||
if (props.padding) {
|
||||
style.padding = props.padding
|
||||
}
|
||||
if (props.boxShadow) {
|
||||
style.boxShadow = '0 0 10px 3px rgba(0, 0, 0, 0.1)'
|
||||
}
|
||||
return style
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
|
||||
65
components/com/appointment/label-slect-field.vue
Normal file
65
components/com/appointment/label-slect-field.vue
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<view class="label-field">
|
||||
<view class="spacer-20"></view>
|
||||
<view class="label-wrap">
|
||||
<text class="label-text">{{ label }}</text>
|
||||
</view>
|
||||
<view class="flex-1">
|
||||
<view class="label-field__body">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
<view class="spacer-20"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
label: { type: String, default: '' }
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.label-field {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.spacer-20 {
|
||||
width: 20rpx;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.label-wrap {
|
||||
width: 130rpx;
|
||||
line-height: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
|
||||
.label-field__label {
|
||||
font-size: 26rpx;
|
||||
margin-top: 20rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #515151;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.label-text {
|
||||
font-size: 28rpx;
|
||||
color: #515151;
|
||||
font-weight: 500;
|
||||
text-transform: none;
|
||||
font-style: normal;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
}
|
||||
|
||||
.label-field__body {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
54
components/com/appointment/tag-select.vue
Normal file
54
components/com/appointment/tag-select.vue
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<view class="tag-select">
|
||||
<view class="tags-row">
|
||||
<view v-for="opt in options" :key="opt" class="tag" :class="{ selected: isSelected(opt) }"
|
||||
@click="onClick(opt)">
|
||||
{{ opt }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
options: { type: Array, default: () => [] },
|
||||
modelValue: { type: String, default: '' }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'change'])
|
||||
|
||||
const isSelected = (opt) => props.modelValue === opt
|
||||
|
||||
const onClick = (opt) => {
|
||||
if (opt === props.modelValue) return
|
||||
emit('update:modelValue', opt)
|
||||
emit('change', opt)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tags-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
margin-right: 16rpx;
|
||||
margin-bottom: 12rpx;
|
||||
padding: 8rpx 18rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 30rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 8rpx;
|
||||
background-color: #DADADA;
|
||||
color: #5B5B5B;
|
||||
border: 1rpx solid #DADADA;
|
||||
}
|
||||
|
||||
.tag.selected {
|
||||
background-color: #00AC4E;
|
||||
color: #FFFFFF;
|
||||
border-color: #00AC4E;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,22 +1,19 @@
|
|||
<template>
|
||||
<view class="row time-row">
|
||||
<view class="label-wrap">
|
||||
<text class="label-text">{{ label }}</text>
|
||||
</view>
|
||||
<view class="value-wrap">
|
||||
<view class="cell-box" @click="onSelect">
|
||||
<view class="content-flex">
|
||||
<slot />
|
||||
</view>
|
||||
<view class="icon-wrap">
|
||||
<image :src="icon" class="icon-img"></image>
|
||||
</view>
|
||||
<label-slect-field :label="label">
|
||||
<view class="cell-box" @click="onSelect">
|
||||
<view class="content-flex">
|
||||
<slot />
|
||||
</view>
|
||||
<view class="icon-wrap">
|
||||
<image :src="icon" class="icon-img"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</label-slect-field>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { labelSlectField } from '@/components/com/appointment/label-slect-field.vue'
|
||||
const props = defineProps({
|
||||
label: { type: String, default: '' },
|
||||
icon: { type: String, default: '' }
|
||||
|
|
@ -32,7 +29,7 @@ const onSelect = () => emit('select')
|
|||
|
||||
.label-wrap {
|
||||
width: 130rpx;
|
||||
line-height: 50rpx;
|
||||
line-height: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@
|
|||
<reservation-evaluate ref="_baseEvaluatePop" />
|
||||
<!-- 预约信息弹窗组件 -->
|
||||
<ReservationPopup ref="_reservationPopup" />
|
||||
<up-datetime-picker hasInput :show="_upDatesTimePicker.show" :filter="_upDatesTimePicker.filter"
|
||||
<up-datetime-picker :show="_upDatesTimePicker.show" :filter="_upDatesTimePicker.filter"
|
||||
:formatter="_upDatesTimePicker.formatter" v-model="_upDatesTimePicker.value" mode="datetime"
|
||||
:minDate="_upDatesTimePicker.minDate" @cancel="_upDatesTimePicker.onCancel"
|
||||
@confirm="_upDatesTimePicker.onConfirm"></up-datetime-picker>
|
||||
@confirm="_upDatesTimePicker.onConfirm" :title="_upDatesTimePicker.title"
|
||||
:hasInput="false"></up-datetime-picker>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
|
@ -30,6 +31,7 @@ const _upDatesTimePicker = ref({
|
|||
refId: null,
|
||||
show: false,
|
||||
value: Date.now(),
|
||||
title: '',
|
||||
minDate: Date.now(),
|
||||
filter: (mode, options) => {
|
||||
// console.log("filter", mode, options)
|
||||
|
|
@ -73,7 +75,7 @@ const _upDatesTimePicker = ref({
|
|||
onError: null
|
||||
});
|
||||
|
||||
const openUpDatesTimePicker = (value, minDate) => {
|
||||
const openUpDatesTimePicker = (value, minDate, title) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 1. 获取当前时间
|
||||
const now = dayjs();
|
||||
|
|
@ -94,6 +96,11 @@ const openUpDatesTimePicker = (value, minDate) => {
|
|||
} else {
|
||||
_upDatesTimePicker.value.minDate = timestamp;
|
||||
}
|
||||
if (title != null) {
|
||||
_upDatesTimePicker.value.title = title;
|
||||
} else {
|
||||
_upDatesTimePicker.value.title = '';
|
||||
}
|
||||
_upDatesTimePicker.value.show = true;
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,147 +4,127 @@
|
|||
|
||||
<text style="margin-top: 100rpx; text-align: center;">发起预约</text>
|
||||
|
||||
<view class=""
|
||||
style="width: 90%; background-color: #FFFFFF; border-radius: 10rpx; margin: 30rpx auto 0; display: flex; justify-content: center; box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.1);">
|
||||
<view class="column" style="width: 95%; margin-bottom: 20rpx; margin-top: 25rpx;">
|
||||
<time-select-cell label="开始时间" icon="@@:app/static/time_start.png" @select="openUpDatesTimePicker">
|
||||
{{ getDayDescription(startTimeStr) }}
|
||||
</time-select-cell>
|
||||
<view style="height:20rpx;"></view>
|
||||
<time-select-cell label="结束时间" icon="@@:app/static/time_end.png" @select="openUpDatesTimePickerEnd">
|
||||
{{ getDayDescription(endTimeStr) }}
|
||||
</time-select-cell>
|
||||
</view>
|
||||
</view>
|
||||
<card-container marginTop="30rpx">
|
||||
<label-field label="预定时长">
|
||||
<tag-select :options="timeRange" v-model="timeRangeValue" @change="onTimeRangeChange" />
|
||||
</label-field>
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<time-select-cell label="开始时间" icon="@@:app/static/time_start.png" @select="openUpDatesTimePicker">
|
||||
{{ getDayDescription(startTimeStr) }}
|
||||
</time-select-cell>
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<time-select-cell label="结束时间" icon="@@:app/static/time_end.png" @select="openUpDatesTimePickerEnd">
|
||||
{{ getDayDescription(endTimeStr) }}
|
||||
</time-select-cell>
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<time-select-cell label="房间" @select="openUpDatesTimePickerEnd">
|
||||
<up-picker-data v-model="reservationInfo.room_id" title="请选择房间" :options="[]" valueKey="id"
|
||||
labelKey="name">
|
||||
</up-picker-data>
|
||||
</time-select-cell>
|
||||
</card-container>
|
||||
|
||||
|
||||
|
||||
<view class="column"
|
||||
style="width: 90%; border-radius: 10rpx; margin: 40rpx auto 0; background-color: #FFFFFF; box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.1);">
|
||||
<card-container marginTop="30rpx">
|
||||
|
||||
<label-field label="组局名称">
|
||||
<view class="" style="width:100%;margin-top: 10rpx;">
|
||||
<view style="width:100%; ">
|
||||
<input class="uni-input" placeholder="请输入组局名称" style="font-size: 24rpx; width: 89%;" />
|
||||
</view>
|
||||
</label-field>
|
||||
|
||||
<label-field label="房间">
|
||||
<uni-data-select class="custom-select" v-model="roomValue" :localdata="range" @change="change"></uni-data-select>
|
||||
</label-field>
|
||||
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<label-field label="人数">
|
||||
<uni-data-select v-model="peopleValue" :localdata="peopleRange" @change="change"></uni-data-select>
|
||||
<uni-data-select v-model="peopleValue" :localdata="peopleRange"
|
||||
@change="changeLog"></uni-data-select>
|
||||
</label-field>
|
||||
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<label-field label="玩法类型">
|
||||
<uni-data-select v-model="peopleValue" :localdata="peopleRange" @change="change"></uni-data-select>
|
||||
<uni-data-select v-model="peopleValue" :localdata="peopleRange"
|
||||
@change="changeLog"></uni-data-select>
|
||||
</label-field>
|
||||
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<label-field label="具体规则">
|
||||
<uni-data-select v-model="peopleValue" :localdata="peopleRange" @change="change"></uni-data-select>
|
||||
<uni-data-select v-model="peopleValue" :localdata="peopleRange"
|
||||
@change="changeLog"></uni-data-select>
|
||||
</label-field>
|
||||
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<label-field label="其他补充">
|
||||
<view class="" style="width: 89%; background-color: white; border-radius: 10rpx; height: 70rpx; display: flex; align-items: center; padding-left: 20rpx; border: 1rpx solid #515151;">
|
||||
<view
|
||||
style="width: 89%; background-color: white; border-radius: 10rpx; height: 70rpx; display: flex; align-items: center; padding-left: 20rpx; border: 1rpx solid #515151;">
|
||||
<input class="uni-input" placeholder="请输入补充信息" style="font-size: 24rpx; width: 100%;" />
|
||||
</view>
|
||||
</label-field>
|
||||
|
||||
</view>
|
||||
</card-container>
|
||||
|
||||
<view class="column"
|
||||
style="width: 90%; border-radius: 10rpx; margin: 40rpx auto 0; background-color: #FFFFFF; box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.1);">
|
||||
|
||||
<view class="row" style="margin-top: 20rpx; margin-left: 20rpx;">
|
||||
<view class="" style="width: 120rpx; font-size: 26rpx; align-items: center;">
|
||||
是否禁烟
|
||||
</view>
|
||||
<card-container marginTop="30rpx">
|
||||
|
||||
<radio-group class="" style="margin-left: 50rpx;">
|
||||
<label class="" style="font-size: 24rpx;">
|
||||
<label-slect-field label="是否禁烟">
|
||||
<radio-group @change="() => { }">
|
||||
<label style="font-size: 24rpx;margin-right:16rpx;">
|
||||
<radio value="r1" color="#00AC4E" style="transform:scale(0.7);" :checked="true" />禁烟
|
||||
</label>
|
||||
<label class="" style="font-size: 24rpx; margin-left: 90rpx;">
|
||||
<label style="font-size: 24rpx; margin-right:16rpx;">
|
||||
<radio value="r2" color="#00AC4E" style="transform:scale(0.7);" />不禁烟
|
||||
</label>
|
||||
|
||||
</radio-group>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="row" style="margin-top: 20rpx; margin-left: 20rpx;">
|
||||
<view class="" style="width: 120rpx; font-size: 26rpx; align-items: center;">
|
||||
性别
|
||||
</view>
|
||||
<radio-group class="" style="margin-left: 50rpx;">
|
||||
<label class="" style="font-size: 24rpx;">
|
||||
</label-slect-field>
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<label-slect-field label="性别">
|
||||
<radio-group @change="() => { }">
|
||||
<label style="font-size: 24rpx; margin-right:16rpx;">
|
||||
<radio value="r1" color="#00AC4E" style="transform:scale(0.7);" :checked="true" />不限
|
||||
</label>
|
||||
<label class="" style="font-size: 24rpx; margin-left: 90rpx;">
|
||||
<label style="font-size: 24rpx; margin-right:16rpx;">
|
||||
<radio value="r2" color="#00AC4E" style="transform:scale(0.7);" />男
|
||||
</label>
|
||||
<label class="" style="font-size: 24rpx; margin-left: 90rpx;">
|
||||
<label style="font-size: 24rpx; margin-right:16rpx;">
|
||||
<radio value="r3" color="#00AC4E" style="transform:scale(0.7);" />女
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<view class="row" style="margin-top: 20rpx; margin-left: 20rpx; margin-bottom: 20rpx;">
|
||||
<view class="" style="width: 120rpx; font-size: 26rpx; align-items: center;">
|
||||
信誉
|
||||
</view>
|
||||
|
||||
<text style="font-size: 25.86rpx; margin-left: 55rpx;">大于等于</text>
|
||||
|
||||
<view class="counter-container">
|
||||
<!-- 减号按钮 -->
|
||||
<view class="" @click="decrement" :disabled="currentValue <= 0">
|
||||
<uni-icons type="minus" size="24" color="#00AC4E" />
|
||||
</view>
|
||||
|
||||
<!-- 数值显示 -->
|
||||
<view class="counter-value">
|
||||
{{ currentValue.toFixed(1) }}
|
||||
</view>
|
||||
|
||||
<!-- 加号按钮 -->
|
||||
<view class="" @click="increment" :disabled="currentValue >= 5">
|
||||
<uni-icons type="plus" size="24" color="#00AC4E" />
|
||||
</label-slect-field>
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<label-slect-field label="信誉">
|
||||
<view style="display:flex;align-items:center;">
|
||||
<text style="font-size: 25.86rpx;width: 120rpx;">大于等于</text>
|
||||
<view class="counter-container">
|
||||
<view @click="decrement" :disabled="currentValue <= 0">
|
||||
<uni-icons type="minus" size="24" color="#00AC4E" />
|
||||
</view>
|
||||
<view class="counter-value">
|
||||
{{ currentValue.toFixed(1) }}
|
||||
</view>
|
||||
<view @click="increment" :disabled="currentValue >= 5">
|
||||
<uni-icons type="plus" size="24" color="#00AC4E" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</label-slect-field>
|
||||
</card-container>
|
||||
|
||||
</view>
|
||||
<card-container marginTop="30rpx">
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
<view class="column"
|
||||
style="width: 90%; border-radius: 10rpx; margin: 20rpx auto 0; background-color: #FFFFFF; box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.1);">
|
||||
|
||||
<view class="row" style="margin-top: 20rpx; margin-left: 20rpx;">
|
||||
<view class="" style=" font-size: 26rpx; align-items: center;">
|
||||
鸽子费(保证金)
|
||||
</view>
|
||||
<radio-group class="" style="margin-left: 50rpx;">
|
||||
<label class="" style="font-size: 24rpx;">
|
||||
<label-slect-field label="鸽子费">
|
||||
<radio-group @change="() => { }">
|
||||
<label style="font-size: 24rpx;margin-right:16rpx;">
|
||||
<radio value="r1" color="#00AC4E" style="transform:scale(0.7);" :checked="true" />0元
|
||||
</label>
|
||||
<label class="" style="font-size: 24rpx;">
|
||||
<label style="font-size: 24rpx;margin-right:16rpx;">
|
||||
<radio value="r2" color="#00AC4E" style="transform:scale(0.7);" />5元
|
||||
</label>
|
||||
<label class="" style="font-size: 24rpx;">
|
||||
<label style="font-size: 24rpx;margin-right:16rpx;">
|
||||
<radio value="r3" color="#00AC4E" style="transform:scale(0.7);" />10元
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
</label-slect-field>
|
||||
<view :style="{ height: lineHeight }"></view>
|
||||
<text
|
||||
style="font-size: 24rpx; margin-left: 20rpx; margin-bottom: 20rpx;">除发起者外,其他参与人需缴纳鸽子费。若有参与者在预约后没有赴约,其鸽子费由在场的所有人平分。组局成功或失败后鸽子费将全额返还。</text>
|
||||
</view>
|
||||
style="font-size: 24rpx; margin-left: 20rpx; margin-bottom: 20rpx;">鸽子费(保证金),参与人需缴纳鸽子费。若有参与者在预约后没有赴约,其鸽子费由在场的所有人平分。组局成功或失败后鸽子费将全额返还。</text>
|
||||
</card-container>
|
||||
|
||||
<view class="center"
|
||||
style="width: 90%; border-radius: 10rpx; margin: 20rpx auto 0; background-color: #00AC4E;">
|
||||
style="width: 90%; border-radius: 10rpx; margin: 30rpx auto 0; background-color: #00AC4E;">
|
||||
<text style="margin: 20rpx; color: white;">发起预约</text>
|
||||
</view>
|
||||
|
||||
|
|
@ -160,11 +140,13 @@
|
|||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { getDayDescription } from '@/common/system/timeUtile';
|
||||
import { getDayDescription, ceilMinuteToNext5 } from '@/common/system/timeUtile';
|
||||
import { union } from 'lodash';
|
||||
import TimeSelectCell from '@/components/com/appointment/time-select-cell.vue'
|
||||
import LabelField from '@/components/com/appointment/label-field.vue'
|
||||
|
||||
import LabelSlectField from '@/components/com/appointment/label-slect-field.vue'
|
||||
import CardContainer from '@/components/com/appointment/card-container.vue'
|
||||
import TagSelect from '@/components/com/appointment/tag-select.vue'
|
||||
const _containerBase = ref(null)
|
||||
const startTimeStr = ref(0)
|
||||
const endTimeStr = ref(0)
|
||||
|
|
@ -172,14 +154,54 @@ const hours = ref("")
|
|||
const minutes = ref("")
|
||||
const roomValue = ref("")
|
||||
const peopleValue = ref("")
|
||||
const lineHeight = ref("15rpx")
|
||||
const timeRange = ref(["2小时", "3小时", "4小时", "自定义"])
|
||||
const timeRangeValue = ref("")
|
||||
//提交表单数据
|
||||
const reservationInfo = ref({
|
||||
room_id: 0,//房间id
|
||||
start_time: 0,//开始时间 时间戳
|
||||
end_time: 0,//结束时间 时间戳
|
||||
max_age: 0,//最大年龄
|
||||
min_age: 0,//最小年龄
|
||||
title: '',//组局名称
|
||||
extra_info: '',//其它说明
|
||||
game_rule: '',//具体规则
|
||||
game_type: '',//玩法类型
|
||||
gender_limit: 1,//性别限制
|
||||
is_smoking: 0,//是否禁烟
|
||||
credit_limit: 0,//信誉限制
|
||||
deposit_fee: 0,//鸽子费
|
||||
player_count: 0,//人数
|
||||
});
|
||||
const onTimeRangeChange = async (val) => {
|
||||
timeRangeValue.value = val;
|
||||
console.log('timeRange change:', val)
|
||||
if (val != "") {
|
||||
await openUpDatesTimePicker();
|
||||
if (startTimeStr.value > 0) {
|
||||
var str = val;
|
||||
if (str == "2小时") {
|
||||
endTimeStr.value = startTimeStr.value + 1000 * 60 * 60 * 2;
|
||||
} else if (str == "3小时") {
|
||||
endTimeStr.value = startTimeStr.value + 1000 * 60 * 60 * 3;
|
||||
} else if (str == "4小时") {
|
||||
endTimeStr.value = startTimeStr.value + 1000 * 60 * 60 * 4;
|
||||
} else {
|
||||
await openUpDatesTimePickerEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const openUpDatesTimePicker = async () => {
|
||||
var now = startTimeStr.value;
|
||||
if (startTimeStr.value == 0) {
|
||||
now = Date.now();
|
||||
now += 1000 * 60 * 30;
|
||||
now = ceilMinuteToNext5(now).valueOf();
|
||||
}
|
||||
const startTime = await _containerBase.value.openUpDatesTimePicker(now, now)
|
||||
const startTime = await _containerBase.value.openUpDatesTimePicker(now, now, "预约开始时间")
|
||||
startTimeStr.value = startTime
|
||||
}
|
||||
const openUpDatesTimePickerEnd = async () => {
|
||||
|
|
@ -190,9 +212,12 @@ const openUpDatesTimePickerEnd = async () => {
|
|||
})
|
||||
return;
|
||||
}
|
||||
var now = (startTimeStr.value + 1000 * 60 * 30);
|
||||
var now = endTimeStr.value;
|
||||
if (now == 0) {
|
||||
now = (startTimeStr.value + 1000 * 60 * 30);
|
||||
}
|
||||
//minDate+1000*60*30 最小间隔30分钟
|
||||
const endTime = await _containerBase.value.openUpDatesTimePicker(now, now)
|
||||
const endTime = await _containerBase.value.openUpDatesTimePicker(now, now, "预约结束时间")
|
||||
endTimeStr.value = endTime
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +291,6 @@ const setTime = () => {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 90rpx;
|
||||
}
|
||||
|
||||
.counter-btn {
|
||||
|
|
|
|||
|
|
@ -371,17 +371,22 @@ const myUseReservation = ref([]);
|
|||
|
||||
// 加载当前预约信息 - 未登录状态
|
||||
const loadCurrentAppointment = async () => {
|
||||
var res = await sqInterface.getMyUseReservation();
|
||||
console.log("getMyUseReservation", res);
|
||||
myUseReservation.value = myUseReservation.value.splice(0, myUseReservation.value.length);
|
||||
myUseReservation.value.push(...res);
|
||||
var _isLogin = await isLogin();
|
||||
if (!_isLogin) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 未登录状态,没有预约数据
|
||||
currentAppointment.value = null
|
||||
var res = await sqInterface.getMyUseReservation();
|
||||
console.log("getMyUseReservation", res);
|
||||
if (res != null) {
|
||||
myUseReservation.value = myUseReservation.value.splice(0, myUseReservation.value.length);
|
||||
myUseReservation.value.push(...res);
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载预约信息失败:', error)
|
||||
currentAppointment.value = null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,7 +402,7 @@ onShow(() => {
|
|||
})
|
||||
onLoad(async () => {
|
||||
await loadUserInfo();
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user