216 lines
5.9 KiB
Vue
216 lines
5.9 KiB
Vue
<script setup lang="ts">
|
|
import { ref, reactive } from "vue"
|
|
import { onLoad } from "@dcloudio/uni-app"
|
|
import { isEmpty, max, min } from "radash"
|
|
import dayjs from "dayjs"
|
|
|
|
import { router } from "@@/index"
|
|
import { boxesApi } from "@@/api"
|
|
|
|
const state = reactive<any>({
|
|
detailType: "add",
|
|
detailId: null,
|
|
detail: null,
|
|
rechargeList: [],
|
|
selectRechargeList: [],
|
|
selectRechargeIdList: [],
|
|
pickerDate: {
|
|
start: "",
|
|
end: "",
|
|
},
|
|
})
|
|
const applyForm = reactive<any>({
|
|
displayTimeRange: "",
|
|
displayTimeRangeStr: "",
|
|
bxDate: null,
|
|
})
|
|
const applyFormRules = reactive<any>({
|
|
bxDate: [{ required: true, message: "预约时间不能为空" }],
|
|
})
|
|
|
|
onLoad((options: any) => {
|
|
const { type, id } = options
|
|
if (!isEmpty(type)) state.detailType = type
|
|
if (!isEmpty(id)) state.detailId = id
|
|
if (type === "view") {
|
|
getDetail()
|
|
}
|
|
const today = dayjs()
|
|
state.pickerDate.start = dayjs().format("YYYY-MM-DD")
|
|
state.pickerDate.end = today.add(2, "month").format("YYYY-MM-DD")
|
|
applyForm.bxDate = state.pickerDate.start
|
|
getDateRange()
|
|
})
|
|
|
|
const getDetail = async () => {
|
|
if (isEmpty(state.detailId)) return
|
|
const _pa = { id: state.detailId }
|
|
const { data } = await boxesApi.detail(_pa)
|
|
if (!isEmpty(data)) {
|
|
state.detail = data
|
|
}
|
|
}
|
|
|
|
const getDateRange = async () => {
|
|
const _pa = { id: state.detailId, currentDate: applyForm.bxDate }
|
|
const { data } = await boxesApi.get(_pa)
|
|
data.avaliabilityRespList.forEach((v) => {
|
|
v.dateTime = `${v.bxDate} ${v.hour}`
|
|
v.timestamp = dayjs(v.dateTime).valueOf()
|
|
})
|
|
state.rechargeList = data.avaliabilityRespList
|
|
}
|
|
|
|
const bxDateConfirm = async (e: any) => {
|
|
getDateRange()
|
|
}
|
|
|
|
const doTimeItem = (v: any) => {
|
|
if (v.status == 1) {
|
|
uni.showToast({ title: "该时间段已被预约", icon: "none" })
|
|
return
|
|
}
|
|
const flag = state.selectRechargeList.some((i) => i.id == v.id)
|
|
if (flag) {
|
|
state.selectRechargeList = state.selectRechargeList.filter((i) => i.id != v.id)
|
|
if (state.selectRechargeList.length >= 2) {
|
|
const { timestamp: targetMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
|
state.rechargeList.forEach((i) => {
|
|
if (i.timestamp <= v.timestamp) {
|
|
state.selectRechargeList = state.selectRechargeList.filter((j) => j.id != i.id)
|
|
}
|
|
})
|
|
}
|
|
} else {
|
|
state.selectRechargeList.push({ ...v })
|
|
if (state.selectRechargeList.length >= 2) {
|
|
const { timestamp: targetMax } = max(state.selectRechargeList, (i: any) => i.timestamp)
|
|
const { timestamp: targetMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
|
state.rechargeList.forEach((i) => {
|
|
if (i.timestamp >= targetMin && i.timestamp <= targetMax) {
|
|
state.selectRechargeList.push({ ...i })
|
|
}
|
|
})
|
|
}
|
|
}
|
|
state.selectRechargeIdList = state.selectRechargeList.map((v) => v.id)
|
|
}
|
|
|
|
const applyFormRef = ref<any>(null)
|
|
const doSubmit = async () => {
|
|
applyFormRef.value.submit()
|
|
const { isPass } = applyFormRef.value.validate()
|
|
if (!isPass) return
|
|
try {
|
|
const { hour: hourMax } = max(state.selectRechargeList, (i: any) => i.timestamp)
|
|
const { hour: hourMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
|
const _pa = {
|
|
boxesId: state.detailId,
|
|
startTime: hourMin,
|
|
endTime: hourMax,
|
|
bxDate: applyForm.bxDate,
|
|
}
|
|
const { data, code }: any = await boxesApi.apply(_pa)
|
|
if (code != 0) throw new Error()
|
|
uni.showLoading({ title: "预定中...", mask: false })
|
|
uni.hideLoading()
|
|
uni.showToast({ title: "申请成功", icon: "none" })
|
|
router.jump("/pages/boxes/apply-list")
|
|
} catch (error) {
|
|
console.error(error)
|
|
uni.hideLoading()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<crud-layout title="预定" mainIsScroll bg="/static/page/blue-bg.png">
|
|
<view class="h-30rpx" />
|
|
<view class="card p-x-30rpx p-y-40rpx">
|
|
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
|
<tm-form-item name="bxDate" label="预约时间" :showBottom="false">
|
|
<tm-picker-date
|
|
v-model="applyForm.bxDate"
|
|
:start="state.pickerDate.start"
|
|
:end="state.pickerDate.end"
|
|
v-model:model-str="applyForm.bxDate"
|
|
format="YYYY-MM-DD"
|
|
@confirm="bxDateConfirm"
|
|
>
|
|
<view :style="{ pointerEvents: state.detailType == 'view' ? 'auto' : 'none' }">
|
|
<tm-input v-model="applyForm.bxDate" disabled placeholder="请选择使用时间..">
|
|
<template v-slot:rightIcon>
|
|
<text v-if="state.detailType != 'view'" class="p-0.5rem color-#b1b1b1 iconfont icon-xiangxiajiantouxiao"></text>
|
|
</template>
|
|
</tm-input>
|
|
</view>
|
|
</tm-picker-date>
|
|
</tm-form-item>
|
|
</tm-form>
|
|
</view>
|
|
<view class="prefix_title m-t-35rpx ml-4">时间段</view>
|
|
<view class="recharge p-30rpx bg-white rounded-20rpx m-t-20rpx shadow-main">
|
|
<view
|
|
:class="[state.selectRechargeIdList.includes(v.id) ? 'recharge_item_active' : '', v.status == 1 ? 'recharge_item_disabled' : '']"
|
|
class="recharge_item"
|
|
v-for="(v, i) in state.rechargeList"
|
|
:key="i"
|
|
@tap="doTimeItem(v)"
|
|
>
|
|
<text class="sub-text-24 text-center">{{ v.bxDate }}</text>
|
|
<text class="sub-text-24 text-center">{{ v.hour }}</text>
|
|
</view>
|
|
</view>
|
|
<template #main-bottom>
|
|
<view
|
|
v-if="state.detailType != 'view'"
|
|
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-y-30rpx sub-text-30 color-white!"
|
|
@tap="doSubmit"
|
|
>
|
|
提交
|
|
</view>
|
|
</template>
|
|
</crud-layout>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
:deep() {
|
|
.tmFormItemLabel {
|
|
padding-bottom: 10rpx !important;
|
|
}
|
|
}
|
|
|
|
.recharge_item_active {
|
|
background: #e9f5fe;
|
|
border: 1px solid #e9f5fe !important;
|
|
|
|
& > text {
|
|
color: #0094ff !important;
|
|
}
|
|
}
|
|
|
|
.recharge_item_disabled {
|
|
background: #999;
|
|
border: 1px solid #999 !important;
|
|
|
|
& > text {
|
|
color: white !important;
|
|
}
|
|
}
|
|
|
|
.recharge {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
grid-gap: 15rpx;
|
|
border-bottom: 1px solid #f9f9f9;
|
|
|
|
&_item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
border: 1px solid #cccccc;
|
|
border-radius: 16rpx;
|
|
padding: 20rpx 0;
|
|
}
|
|
}
|
|
</style>
|