Files
mgm-daylight-mcrm-mobile-ios/booking/submitBooking/submitBooking.vue
T
2026-09-22 16:37:00 +08:00

1994 lines
76 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view>
<view class="hz-page">
<u-navbar
:safeAreaInsetTop="true"
:placeholder="true"
:title="title"
:fixed="true"
:autoBack="true"
leftIconColor="#000000"
titleStyle="font-weight:bold;"
>
<view
style="margin-top:2px;margin-right:3px;"
slot="right"
>
<view style="border:1rpx solid #ccc;border-radius: 14px;padding:4px 12px;" class="hz-flex-row hz-flex-vertical-mid">
<image @click="navTo('/pages/findPlayer/findPlayer',1,false)" src="../../static/images/ico_find_player.png" class="hz-nav-btn"></image>
<view style="height:20px;border-left:1px solid #ccc;margin-left:8px;margin-right:8px;"></view>
<image @click="navTo('/booking/bookingRecord/bookingRecord?from=booking',0,false)" src="../../static/images/ico_list.png" class="hz-nav-btn"></image>
</view>
</view>
</u-navbar>
<view class="hz-spacing hz-bg-white" style="margin-top:8px;">
<view class="hz-card-profile" style="margin-bottom:6px;">
<view class="hz-flex-row">
<view style="width:60%">
<view class="hz-font-color-light hz-font-sm">{{$t("common.playerId")}}</view>
<view class="hz-font-bolder hz-font-lg" >{{ playerData.playerId }}</view>
</view>
<view style="width:40%">
<view class="hz-font-color-light hz-font-sm">{{$t("common.tier")}}</view>
<view class="hz-font-bolder hz-font-lg" >{{ playerData.tierName }}</view>
</view>
</view>
<view class="hz-flex-row hz-mr-t-30">
<view style="width:100%">
<view class="hz-font-color-light hz-font-sm">{{$t("common.name")}}</view>
<view class="hz-font-bolder hz-font-lg" >{{playerData.salutation + " " + playerData.name }}</view>
</view>
</view>
</view>
<u-checkbox-group
v-model="checkList"
placement="column"
@change="selectBooking"
>
<view v-for="(item,index) in (bookingData.bookType==1)?bookingData.extendDate:bookingData.dateList" :key="'date'+index" class="hz-pd-30 hz-font-bold hz-font-sm " :class="item.bookingStatus=='PN'? 'hz-card-booking':'hz-card-extend'" style="margin-top:10px;align-items: center;">
<view class="hz-flex-row " style="width:100%;">
<view style="width:100%;">
<view class="hz-flex-row" style="align-items: center;">
<span class="hz-font-md hz-font-bolder">{{dateFormat(item.date[0])}}&nbsp; {{$t("common.to")}}&nbsp; {{dateFormat(item.date[item.date.length-1])}}</span>
</view>
<view class="hz-flex-row" style="margin-top:8px;">
<view class="hz-flex-row" style="width:33%;align-items: center;">
<image src="../../static/images/ico_night.png" style="width:16px;height:16px;"></image>
<span class="hz-font-md hz-font-bolder" style="margin-left:4px;">{{getNight(item.numOfNight)}}</span>
</view>
<view class="hz-flex-row" style="width:33%;align-items: center;">
<image src="../../static/images/ico_room.png" style="width:16px;height:16px;"></image>
<span class="hz-font-md hz-font-bolder" style="margin-left:4px;">{{getRoom(item.numOfRoom)}}</span>
</view>
<view class="hz-flex-row" style="width:34%;align-items: center;justify-content: flex-end;">
<view v-if="item.status==0 && item.bookingStatus!='PN'" class="hz-status-duein hz-btn-status hz-font-min hz-text-center" style="margin-top:4px;width:100%;height:14px;line-height:14px;">Qualified</view>
<view v-if="item.status==0 && item.bookingStatus=='PN'" class="hz-status-pending hz-btn-status hz-font-min hz-text-center" style="margin-top:4px;width:100%;height:14px;line-height:14px;">Pending</view>
<view v-if="item.status==1" class="hz-status-waitlist hz-btn-status hz-font-min hz-text-center" style="margin-top:4px;width:100%;height:14px;line-height:14px;">UnQualified</view>
<view style="padding-top:3px;">
<u-checkbox
labelColor="#C39A4B"
activeColor="#C39A4B"
customStyle="margin-left:8px;"
labelSize="11"
size="24"
shape="circle"
:name="index"
v-if="(item.bookingStatus!='PN'&&item.status==0) || (item.status==1 && bookingData.bookingTypeName.toUpperCase()=='MASS')"
:checked="getIsCheck(index)"
>
</u-checkbox>
</view>
</view>
</view>
</view>
</view>
<view class="hz-split-primary" style="margin-top:8px;margin-bottom:4px;" v-if="item.status!=0"></view>
<view class="hz-flex-col hz-font-color-danger hz-font-sm hz-font-bolder" v-if="item.status!=0">
<view class="hz-flex-row" style="align-items: center;">
<view style="width:66%;align-items: center;" v-if="item.isWaitlist!=1">
{{$t("submitBooking.roomCriteriaNotQualified")}}
</view>
<view style="width:66%;align-items: center;" v-else>
{{$t("submitBooking.underWaitlist")}}
</view>
</view>
</view>
</view>
</u-checkbox-group>
<view class="hz-spacing hz-mr-t-30" style="margin-bottom:30px;">
<view class="hz-flex-row">
<view style="width:65%">
<view class="hz-font-color-black hz-font-sm">{{$t("common.property")}}</view>
<view class="hz-font-bolder hz-font-lg" >{{bookingData.propertyName}}</view>
</view>
<view style="width:35%">
<view class="hz-font-color-black hz-font-sm">{{$t("newBooking.roomType")}}</view>
<view class="hz-font-bolder hz-font-lg" >{{bookingData.room}}</view>
</view>
</view>
<view v-if="(bookingData.specialName!=null && bookingData.specialName!='') || (bookingData.bedTypeName!=null && bookingData.bedTypeName!='')" class="hz-flex-row hz-mr-t-30">
<view style="width:100%">
<view class="hz-font-color-black hz-font-sm">{{$t("newBooking.specialPreference")}}</view>
<view class="hz-font-bolder hz-font-lg" >{{getSpecial(bookingData.specialName,bookingData.bedTypeName)}}</view>
</view>
</view>
<view v-if="bookingData.sharerList!=null && bookingData.sharerList.length>0" class="hz-flex-row hz-mr-t-30">
<view style="width:100%">
<view class="hz-font-color-black hz-font-sm">{{$t("bookingRecord.sharer")}}</view>
<view v-for="(item,index) in bookingData.sharerList" :key="'sharer'+index" class="hz-font-bolder hz-font-lg" >{{getSharer(item.playerId,item.name)}}</view>
</view>
</view>
<view class="hz-flex-row hz-mr-t-30">
<view style="width:65%">
<view class="hz-font-color-black hz-font-sm">{{$t("bookingConfirm.createdOn")}}</view>
<view class="hz-font-bolder hz-font-lg" >{{bookingData.createdOn}}</view>
</view>
<view style="width:35%">
<view class="hz-font-color-black hz-font-sm">{{$t("bookingConfirm.createdBy")}}</view>
<view class="hz-font-bolder hz-font-lg">{{userData.userName}}</view>
</view>
</view>
<view class="hz-flex-row hz-mr-t-30">
<view v-if="bookingData.etaTime!=null" class="hz-flex-row" style="width: 65%;">
<view style="width:100%">
<view class="hz-font-color-black hz-font-sm">{{ $t("common.etaTime") }}</view>
<view class="hz-font-bolder hz-font-lg" >{{ bookingData.etaTime || "-" }}</view>
<!-- <view class="hz-font-bolder hz-font-lg" >{{ handleShowWhenScreenshot(bookingData.eta) }}</view> -->
</view>
</view>
<view v-if="bookingData.mischarge!=null" class="hz-flex-row">
<view style="width:100%">
<view class="hz-font-color-black hz-font-sm">{{ $t("common.misCharge") }}</view>
<view class="hz-font-bolder hz-font-lg">{{ bookingData.mischarge || "-" }}</view>
</view>
</view>
</view>
</view>
<view :style="'height:'+footFuncHei+'rpx;'"></view>
</view>
<u-tabbar
:fixed="true"
:placeholder="true"
:safeAreaInsetBottom="true"
customStyle="z-index:100;height:58px;"
>
<view class="book hz-spacing" :class="[checkList.length > 0 ? '' : 'hz-disabled', submitLoading ? 'hz-disabled' : '']">
<view @click="checkHasUnqualified()" class="hz-btn-danger hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >{{$t("bookingConfirm.submitBooking")}}</view>
</view>
</u-tabbar>
</view>
<u-popup
:safeAreaInsetBottom="true"
:safeAreaInsetTop="true"
:mode="'center'"
:round="12"
:show="showMsgBox"
>
<view
:style="'width:'+ windowWidth + 'px;'"
style="padding:20px;"
>
<view class="hz-flex-row" style="justify-content: center;">
<image :src="iconPath" style="width:64px;height:64px;"></image>
</view>
<view class="hz-font-md hz-font-bold hz-text-center" style="margin-top:20px;">
<rich-text v-html="msgStr" style="line-height:26px;"></rich-text>
</view>
<view v-if="bookingData.bookType==0 && showDateList" v-for="(item,index) in bookingData.dateList" :key="'date'+index" class="hz-pd-30 hz-font-bold hz-font-sm hz-card-extend" style="margin-top:6px;align-items: center;">
<view class="hz-flex-row" style="align-items: center;">
<span class="hz-font-md hz-font-bolder" style="margin-left:4px;">{{dateFormat(item.date[0])}}&nbsp; {{$t("common.to")}}&nbsp; {{dateFormat(item.date[item.date.length-1])}}</span>
</view>
<view class="hz-flex-row" style="margin-top:8px;">
<view class="hz-flex-row" style="width:40%;align-items: center;">
<image src="../../static/images/ico_night.png" style="width:16px;height:16px;"></image>
<span class="hz-font-md hz-font-bolder" style="margin-left:4px;">{{getNight(item.numOfNight)}}</span>
</view>
<view class="hz-flex-row" style="width:40%;align-items: center;">
<image src="../../static/images/ico_room.png" style="width:16px;height:16px;"></image>
<span class="hz-font-md hz-font-bolder" style="margin-left:4px;">{{getRoom(item.numOfRoom)}}</span>
</view>
<view class="hz-flex-row" style="width:20%;align-items: center;">
<view v-if="item.status==0" class="hz-status-pending hz-btn-status hz-font-min hz-text-center" style="margin-top:4px;width:100%;height:14px;line-height:14px;">Pending</view>
<view v-if="item.status==1" class="hz-status-waitlist hz-btn-status hz-font-min hz-text-center" style="margin-top:4px;width:100%;height:14px;line-height:14px;">WaitList</view>
</view>
</view>
</view>
<view @click="navToDetail(url)" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" style="margin-top:20px;">
{{buttonStr}}
</view>
</view>
</u-popup>
<u-popup :safeAreaInsetBottom="true" :safeAreaInsetTop="true" :mode="'center'" :round="12" :show="showSubmitMsg">
<view :style="'width:'+ windowWidth + 'px;'" style="padding:20px;">
<view class="hz-flex-row" style="justify-content: center;">
<image :src="iconPath" style="width:64px;height:64px;"></image>
</view>
<view class="hz-font-md hz-font-bold hz-text-center" style="margin-top:20px;">
<rich-text v-html="msgStr" style="line-height:26px;"></rich-text>
</view>
<view style="margin-top:10px;">
<view class="hz-flex-col" style="justify-content: center;align-items: center;margin-top:18px;">
<view v-show="showModalBtn" @click="submitApproval()"
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center confirmButton">
{{$t("bookingConfirm.urgentApproval").toUpperCase()}}
</view>
<view v-show="showModalBtn" @click="showWaitlistPop()"
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center confirmButton">
{{$t("bookingConfirm.putInWaitlist").toUpperCase()}}
</view>
<view @click="navTo('/booking/bookingRecord/bookingRecord?from=booking',0,false)"
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center confirmButton">
{{$t("bookingConfirm.backToRecords").toUpperCase()}}
</view>
</view>
</view>
</view>
</u-popup>
<!-- 审批模态框 -->
<u-popup :safeAreaInsetBottom="true" :safeAreaInsetTop="true" :mode="'center'" :round="12"
:show="showApprovalModal" @close="closeApprovalPop()">
<view :style="'width:'+ windowWidth + 'px;'" style="padding:20px;">
<view class="hz-flex-row" style="align-items: center; margin-bottom: 10px;">
<view style="width: 25px; display: flex; align-items: center;">
<view v-show="currentUnqualifiedIndex > 0" @click="previousUnQualifiedBooking()" class="hz-font-xl hz-font-bolder" style="display: flex; align-items: center; pointer-events: auto; position: relative; z-index: 1;">
<image src="/static/images/arrow_previous.png" style="width: 25px;height: 25px; pointer-events: none;" />
</view>
</view>
<view class="hz-flex-row" style="flex: 1; justify-content: center;">
<text class="approvalHeader">Approval Request</text>
</view>
<view style="width: 25px;" @click="closeApprovalPop()">
<image src="/static/images/close.png" style="width: 25px;height: 25px; pointer-events: none;" />
</view>
</view>
<view>
<view>C/I:{{getCheckInDate()}}</view>
<view>C/O:{{getCheckOutDate()}}</view>
</view>
<!-- Remark -->
<view style="margin-bottom: 16px;margin-top: 16px;">
<view style="text-align: left;">{{$t("bookingConfirm.approvalRemark")}}</view>
<u-checkbox-group placement="row" @change="changeOtherRemark"
v-model="unqualifiedDateCheckboxStates[currentUnqualifiedIndex]"
style="flex-direction: unset;display: block;">
<view style="width:50%;display: inline-flex;">
<u-checkbox activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="Extend" name="Extend"
:value="unqualifiedDateCheckboxStates[currentUnqualifiedIndex] && unqualifiedDateCheckboxStates[currentUnqualifiedIndex].includes('Extend')"></u-checkbox>
</view>
<view style="width:50%;display: inline-flex;position: relative;left:10%;">
<u-checkbox activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="Remark" name="Remark"
:value="unqualifiedDateCheckboxStates[currentUnqualifiedIndex] && unqualifiedDateCheckboxStates[currentUnqualifiedIndex].includes('Remark')"></u-checkbox>
</view>
</u-checkbox-group>
<view style="width:100%;margin-top:16px;" v-show="showRemark">
<view class="hz-font-bolder hz-font-md" style="margin-top:4px;">
<u--textarea v-model="unqualifiedDateRemarks[currentUnqualifiedIndex]" :maxlength="128" :placeholder="inputRemark"></u--textarea>
</view>
</view>
</view>
<!-- Request Reason -->
<view style="margin-bottom:16px;">
<view class="hz-font-md hz-font-bolder" style="margin-bottom:8px;">
{{$t("bookingConfirm.requestReason")}} <text style="color: #ff0000;">*</text>
</view>
<view>
<lu-data-select placeholder="Select Reason" :options="selectReasonData" v-model="unqualifiedDateReasons[currentUnqualifiedIndex]"
:multiple="false" :filterable="true" @change="onReasonChange" style="width: 100%;" :clearable="false"></lu-data-select>
</view>
</view>
<!-- ROUTER TO APPROVAL -->
<view style="margin-bottom:16px;">
<view class="hz-font-md hz-font-bolder" style="margin-bottom:8px;">
{{$t("bookingConfirm.routeToApprover")}} <text style="color: #ff0000;">*</text>
</view>
<view>
<lu-data-select placeholder="Select Approver" :options="selectApproverData" v-model="unqualifiedDateApprovers[currentUnqualifiedIndex]"
:multiple="true" :filterable="true" @change="onApprovalChange" style="width: 100%;" :clearable="false"></lu-data-select>
</view>
</view>
<view class="hz-flex-col" style="justify-content: center;align-items: center;margin-top:10px;">
<view @click="nextUnQualifiedBooking()"
v-if="currentUnqualifiedIndex < unqualifiedDateList.length - 1"
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center"
style="background-color:#C39A4B;margin-bottom:10px;">
{{ $t("common.nextBooking").toUpperCase()}}
</view>
<view @click="submitApprovalRequest()"
v-else
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center"
style="background-color:#C39A4B;margin-bottom:10px;">
{{$t("bookingConfirm.submitApproval").toUpperCase()}}
</view>
<view @click="navTo('/booking/bookingRecord/bookingRecord?from=booking',0,false)"
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center">
{{$t("bookingConfirm.backToRecords").toUpperCase()}}
</view>
</view>
</view>
</u-popup>
<!-- Waitlist 模态框 -->
<u-popup :safeAreaInsetBottom="true" :safeAreaInsetTop="true" :mode="'center'" :round="12"
:show="showWaitlistModal" @close="showWaitlistModal=false">
<view :style="'width:'+ windowWidth + 'px;'" style="padding:20px;">
<view class="hz-spacing" style="margin-top:10px;margin-left:15px;">
<view class="hz-flex-row" style="justify-content: center;">
<image :src="iconPath" style="width:64px;height:64px;"></image>
</view>
<view class="hz-font-md hz-font-bold hz-text-center" style="margin-top:20px;">
<rich-text v-html="msgStr" style="line-height:26px;"></rich-text>
</view>
<view style="margin-bottom: 10px;text-align: left;"> {{$t("bookingConfirm.approvalRemark")}}</view>
<u-radio-group placement="row" @change="changeRoomRemark" v-if="showRadio"
style="flex-direction: unset;display: block;">
<view style="width:50%;display: inline-flex;">
<u-radio activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="2nd Room" name="2nd Room"></u-radio>
</view>
<view style="width:50%;display: inline-flex;position: relative;left:10%;">
<u-radio activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="3rd Room" name="3rd Room"></u-radio>
</view>
</u-radio-group>
<u-checkbox-group placement="row" v-else style="flex-direction: unset;display: block;">
<view style="width:50%;display: inline-flex;">
<u-checkbox activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="2nd Room" name="2nd Room"></u-checkbox>
</view>
<view style="width:50%;display: inline-flex;position: relative;left:10%;">
<u-checkbox activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="3rd Room" name="3rd Room"></u-checkbox>
</view>
</u-checkbox-group>
<u-checkbox-group placement="row" @change="changeOtherRemark"
style="flex-direction: unset;display: block;">
<view style="width:50%;display: inline-flex;">
<u-checkbox activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="Extend" name="Extend"
:value="unqualifiedDateCheckboxStates[currentUnqualifiedIndex] && unqualifiedDateCheckboxStates[currentUnqualifiedIndex].includes('Extend')"></u-checkbox>
</view>
<view style="width:50%;display: inline-flex;position: relative;left:10%;">
<u-checkbox activeColor="#C39A4B" labelColor="#333333" shape="circle"
customStyle="height:30px;width:100%;" label="Remark" name="Remark"
:value="unqualifiedDateCheckboxStates[currentUnqualifiedIndex] && unqualifiedDateCheckboxStates[currentUnqualifiedIndex].includes('Remark')"></u-checkbox>
</view>
</u-checkbox-group>
<view style="width:100%;margin-top:16px;" v-show="showRemark">
<view class="hz-font-bolder hz-font-md" style="margin-top:4px;">
<u--textarea v-model="freeRemark" :maxlength="128" :placeholder="inputRemark"></u--textarea>
</view>
</view>
</view>
<view class="hz-flex-col" style="justify-content: center;align-items: center;margin-top:18px;">
<view @click="submitBooking()"
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center confirmButton">
{{$t("bookingConfirm.putInWaitlist").toUpperCase()}}
</view>
<view @click="navTo('/booking/bookingRecord/bookingRecord?from=booking',0,false)"
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center confirmButton">
{{$t("bookingConfirm.backToRecords").toUpperCase()}}
</view>
</view>
</view>
</u-popup>
<u-modal :content="msgStr" :show="showMsg" :confirmText="yesText" :showCancelButton="false" closeOnClickOverlay @confirm="showMsg=false" confirmColor="#C39A4B" @close="showMsg=false"></u-modal>
</view>
</template>
<script>
import dayjs from '../../uni_modules/uview-ui/libs/util/dayjs.js';
import {checkTPD,checkSecondTPD} from '../../api/mgmApi.js';
import {saveBooking,editBooking} from '../../api/bookingApi.js';
import {formatDate} from '../../common/stringUtils.js';
import { debounce } from 'lodash';
import {
getApprovalReason,
getApprover
} from '../../api/approvalApi.js';
export default {
data() {
return {
//数据变量
siteData:null,
playerData:null,
userData:null,
bookingData:null,
oldDateList:[],
checkList:[],
// 界面变量
showMsgBox:false,
showDateList:false,
buttonStr:'',
url:'',
iconPath:'',
msgStr:'',
title:'',
type:'',
inputRemark:this.$t("common.inputRemark"),
windowWidth:0,
footFuncHei:100,
showMsg:false,
showModalBtn:false,
showSubmitMsg:false,
yesText:this.$t("common.ok"),
submitLoading:false,
freeRemark:'',
showApprovalModal:false,
showRemark:false,
showDirBtn:false,
selectReasonData:[],
canSubmit:true,
selectedReason:'',
selectApproverData:[],
selectedApprover:'',
showRemark: false,
showWaitlistModal:false,
showRadio:false,
unqualifiedDateList: [],
currentUnqualifiedIndex: 0,
unqualifiedDateRemarks: [],
unqualifiedDateReasons: [],
unqualifiedDateApprovers: [],
unqualifiedDateOtherRemarks: [],
unqualifiedDateCheckboxStates: []
}
},
onLoad(opt) {
// 初始化界面
this.siteData = uni.getStorageSync("siteData");
this.userData = uni.getStorageSync("userData");
this.initUI();
this.playerData = uni.getStorageSync("playerData");
this.getBooking();
},
async onShow() {
// 检查是否登录
// this.isLogin();
},
methods: {
// 數據方法
getBooking(){
this.bookingData = uni.getStorageSync("bookingData");
if(this.bookingData!==null && this.bookingData!==undefined && this.bookingData!==''){
this.oldDateList = this.bookingData.dateList;
this.checkList = [];
let dList = (this.bookingData.bookType==1)?this.bookingData.extendDate:this.bookingData.dateList;
for(let i in dList){
let item = dList[i];
if((item.bookingStatus!='PN'&&item.status==0) ||
(item.status==1 && this.bookingData.bookingTypeName.toUpperCase()=='MASS')){
this.checkList.push(i)
}
}
}else{
// 报错
}
},
checkHasUnqualified(){
//判断提交Booking是否含有UnQualified的Booking
var hasUnqualified = false;
for(let i=0;i<this.bookingData.dateList.length;i++){
for(let j=0;j<this.checkList.length;j++){
//判断如果有 UnqualifiedBooking 直接变量设置为true 直接break
if(this.bookingData.dateList[this.checkList[j]].status === 1) {
hasUnqualified = true;
break;
}
}
}
if(hasUnqualified){
//如果有 调用showSubmitModel
this.showSubmitModel()
}else{
//如果没有 调用CreateBooking方法
this.submitBooking();
}
},
submitApproval() {
// 显示审批模态框
this.getApprovalReason();
this.showApprovalModal = true;
this.showModalBtn = true;
this.currentUnqualifiedIndex = 0;
this.unqualifiedDateList = [];
this.unqualifiedDateRemarks = [];
this.unqualifiedDateReasons = [];
this.unqualifiedDateApprovers = [];
this.unqualifiedDateOtherRemarks = [];
this.unqualifiedDateCheckboxStates = [];
if(this.checkList!=null && this.checkList.length>0){
if(this.bookingData.bookType==1){
// 把extendDate中的状态都设置成不够分
for(let i=0;i<this.bookingData.extendDate.length;i++){
for(let j=0;j<this.checkList.length;j++){
if(i == this.checkList[j] && this.bookingData.extendDate[i].status==1){
console.log(this.bookingData.extendDate[i]);
this.unqualifiedDateList.push(this.bookingData.extendDate[i]);
this.unqualifiedDateRemarks.push(this.bookingData.extendDate[i].remark || null);
this.unqualifiedDateReasons.push('');
// 多选 Approver:为每个 index 初始化为数组
this.unqualifiedDateApprovers.push([]);
this.unqualifiedDateOtherRemarks.push('');
this.unqualifiedDateCheckboxStates.push([]);
}
}
}
}else{
// 把dateList中的状态都设置成不够分
for(let i=0;i<this.bookingData.dateList.length;i++){
for(let j=0;j<this.checkList.length;j++){
if(i == this.checkList[j] && this.bookingData.dateList[i].status==1){
// console.log(this.bookingData.dateList[i]);
this.unqualifiedDateList.push(this.bookingData.dateList[i]);
this.unqualifiedDateRemarks.push(this.bookingData.dateList[i].remark || '');
this.unqualifiedDateReasons.push('');
// 多选 Approver:为每个 index 初始化为数组
this.unqualifiedDateApprovers.push([]);
this.unqualifiedDateOtherRemarks.push('');
this.unqualifiedDateCheckboxStates.push([]);
}
}
}
}
}else{
return false;
}
},
onApprovalChange(value){
this.selectedApprover = value;
// 多选:value 为数组,需要拼接 approverName
if (Array.isArray(value)) {
if (value.length === 0) {
this.selectedApproverName = '';
return;
}
const names = value.map((id) => {
const item = this.selectApproverData.find(opt => String(opt.value) === String(id));
return item ? (item.approverName || item.label || '') : '';
}).filter(Boolean);
this.selectedApproverName = names.join(', ');
return;
}
// 单选兼容
const selectedApproverItem = this.selectApproverData.find(item => String(item.value) === String(value));
this.selectedApproverName = selectedApproverItem
? (selectedApproverItem.approverName || selectedApproverItem.label || '')
: '';
},
onReasonChange(value){
this.selectedReason = value;
},
async getApprovalReason(){
try {
let params = {};
const res = await getApprovalReason(params);
if (res.success === true) {
// 转换数据格式为 lu-data-select 需要的格式
this.selectReasonData = res.data.map(item => ({
label: item.code,
value: item.id,
...item
}));
}
} catch (e) {
console.error(e);
uni.$u.toast(e.errMsg, 5000);
var request = e.config != undefined ? JSON.stringify(e.config) : "";
var response = e.data != undefined ? JSON.stringify(e.data) : "";
await this.writeLog(this.userData.userId, "bookingConfirm", "",
"[APP][bookingConfirm.vue][getApprovalReason][Catch Exception]" + e.errMsg, request, response, 1,
false);
}finally{
this.getApprover();
}
},
async getApprover(){
try {
this.selectApproverData = [];
let currentCIDay = this.getCheckInDate();
let currentCODay = this.getCheckOutDate();
let params = {playerId:this.bookingData.playerId,bookingType:this.bookingData.bookingTypeName,
propertyName:this.bookingData.propertyName,roomCategory:this.bookingData.room,checkInDate:currentCIDay,checkOutDate:currentCODay};
const res = await getApprover(params);
if (res.success === true) {
const record = res.data && Array.isArray(res.data.records)
? res.data.records[0]
: null;
const approverList = record && Array.isArray(record.approverList)
? record.approverList
: [];
this.selectApproverData = approverList.map(item => ({
label: item.employeeName,
value: item.employeeId,
...item
}));
this.routingResaon = record ? (record.approvalRoutingMessage || '') : '';
console.log(this.routingResaon);
}
} catch (e) {
console.error(e);
uni.$u.toast(e.errMsg, 5000);
var request = e.config != undefined ? JSON.stringify(e.config) : "";
var response = e.data != undefined ? JSON.stringify(e.data) : "";
await this.writeLog(this.userData.userId, "bookingConfirm", "",
"[APP][bookingConfirm.vue][getApprovalReason][Catch Exception]" + e.errMsg, request, response, 1,
false);
}
},
closeApprovalPop(){
this.showApprovalModal = false;
},
showSubmitModel(){
this.showSubmitMsg = true;
this.showDirBtn = true;
this.showModalBtn = true;
this.iconPath = '../../static/images/warn.png';
this.msgStr = 'Booking Criteria is not qualified';
},
async checkBooking(type){
uni.showLoading({
title: this.$t("common.loading")
});
try{
// 模拟一次状态对不上
// this.siteData.mockTPD = true;
let checkTPDCount = 0;
if(this.siteData.mockTPD==true){
checkTPDCount = uni.getStorageSync("checkTPDCount");
if(checkTPDCount===undefined || checkTPDCount==null || checkTPDCount===''){
checkTPDCount = 0;
}
if(checkTPDCount>0){
return {"status":2,"sameStatus":1};
}
}
let params = {};
//let dates = ''; 看到时候MGM最后确定是传字符串还是数组给他们,后端接口也要相应调整一下
let dates = [];
if(type==1){
for(let b=0;b<this.bookingData.extendDate.length;b++){
let dateObj = this.bookingData.extendDate[b];
let date = dateObj.date;
for(let j=0;j<date.length-1;j++){
dates.push(date[j]);
}
}
}else{
for(let b=0;b<this.bookingData.dateList.length;b++){
let dateObj = this.bookingData.dateList[b];
let date = dateObj.date;
for(let j=0;j<date.length-1;j++){
dates.push(date[j]);
}
}
// for(let i=0;i<this.checkList.length;i++){
// var index = this.checkList[i];
// if(this.bookingData.dateList[index]!=undefined){
// let date = this.bookingData.dateList[index].date;
// for(let j=0;j<date.length-1;j++){
// dates.push(date[j]);
// }
// }
// }
}
// 創建GroupId,代表這些拆分的booking都是同一次提交的
if(this.checkList.length>1){
this.bookingData.groupId = this.generateUniqueId();
}
var criteriaCount = this.bookingData.criteriaList.length;
var dateRange = [];
var rangeStartDate = this.bookingData.checkInDate;
var bookingType = this.bookingData.bookingTypeName;
var roomCat = this.bookingData.roomCategory;
var isSecondRoom = false;
var currentRoomNum = 0;
var lastRangeDate = null;
let lastEndDate = null;
for(let i=0;i<criteriaCount;i++){
let criteria = this.bookingData.criteriaList[i];
let numOfRoom = 0;
let firstDate = criteria.bookDate == this.bookingData.checkInDate;
let lastDate = (i==criteriaCount-1);
if(bookingType=="Mass"){
if(criteria.massStandard!=undefined){
if(roomCat=="Standard Room"){
numOfRoom = criteria.massStandard
}else if(roomCat=="Suite"){
numOfRoom = criteria.massStandard
}
}else if(criteria.massSuite!=undefined){
numOfRoom = criteria.massSuite
}
}else if(bookingType=="IM"){
if(criteria.im!=undefined){
numOfRoom = criteria.im
}
}
numOfRoom = (numOfRoom+1);
if(firstDate) {
currentRoomNum = numOfRoom;
}
if(rangeStartDate==null) rangeStartDate = lastEndDate;
if(currentRoomNum==null) currentRoomNum = numOfRoom;
if(numOfRoom!=currentRoomNum||lastDate){
if(rangeStartDate==this.bookingData.checkOutDate) continue;
let nowRoomNum = numOfRoom;
numOfRoom = currentRoomNum;
let endDate = lastEndDate;
let rangeObj = {
"StartDate":rangeStartDate,
"EndDate":lastEndDate,
"RoomBookingOrdinalNumber":numOfRoom,
}
dateRange.push(rangeObj)
rangeStartDate = null;
currentRoomNum = nowRoomNum;
if(numOfRoom>1) isSecondRoom=true;
}
lastEndDate = criteria.bookDate;
}
console.log(dateRange)
uni.setStorageSync("bookingData",this.bookingData);
params.playerId = this.playerData.playerId;
params.roomCat = this.bookingData.room;
params.bookingType = this.bookingData.bookingTypeName;
params.property = this.bookingData.propertyName
params.dates = dates;
let res = {};
if(isSecondRoom){
params.dateRange = dateRange;
res = await checkSecondTPD(params);
}else{
res = await checkTPD(params);
}
if(res.success === true){
// 這裡用於模擬TPD的情況,只模擬一次狀態不同,避免一直停留在該畫面
if(this.siteData.mockTPD==true){
checkTPDCount++;
uni.setStorageSync("checkTPDCount",checkTPDCount);
}
var waitlistRes = this.checkWaitlist();
var changeWaitlist = false;
// 把waitlist日期与够不够分日期合并,changeWaitlist为true时则原来够分改为waitlist
if(waitlistRes.status==1||waitlistRes.status==2){
if(res.data.status==0){
if(waitlistRes.status==2)
res.data.status=1; // 改TPD返回的状态为不够分
else
res.data.status=2; // 改TPD返回的状态为部分够分
res.data.dates = waitlistRes.dates;
changeWaitlist = true;
}else if(res.data.status==2){
if(waitlistRes.status==2)
res.data.status=1; // 改TPD返回的状态为不够分
var resdates = res.data.dates;
var waitDates = waitlistRes.dates;
var count = 0;
// 把TPD返回的datelist结果跟Room allotment的waitlist结果匹配一次
for(var i in resdates){
if(waitDates[i].status==1) {
resdates[i].status=1;
resdates[i].isWaitlist=1;
}
if(resdates[i].status==1) count++;
}
// 这种情况是如果TPD返回部分够分,经过检查Room allotment的waitlist后,全部都变成不够分的场景
if(count == resdates.length) res.data.status=1;
res.data.dates = resdates;
}
}
// 够分
if(res.data.status==0){
//disabled extend waitlist
// if(type==1){
// // 把extendDate中的状态都设置成够分
// for(let i=0;i<this.bookingData.extendDate.length;i++){
// this.bookingData.extendDate[i].checked = false;
// for(let j=0;j<this.extendDate.length;j++){
// if(i === this.extendDate[j]){
// this.bookingData.extendDate[i].checked = true;
// this.bookingData.extendDate[i].status = 0;
// break;
// }
// }
// }
// }else{
// // 把dateList中的状态都设置成够分
// for(let i=0;i<this.bookingData.dateList.length;i++){
// this.bookingData.dateList[i].checked = false;
// for(let j=0;j<this.checkList.length;j++){
// if(i === this.checkList[j]){
// this.bookingData.dateList[i].checked = true;
// this.bookingData.dateList[i].status = 0;
// break;
// }
// }
// }
// }
// 不合成
// 因为来到这个页面就是一部分够分,一部分不够分的,所以进入到这里肯定就是状态发生了变化
// 需要把dateList合并成一条
// let tempDates = [];
// for(let i=0;i<this.bookingData.dateList.length;i++){
// const date = this.bookingData.dateList[i];
// if(date.date.length>0){
// for(let j=0;j<date.date.length-1;j++){
// tempDates.push(date.date[j]);
// }
// }
// }
var getDateList = [];
for(let i=0;i<this.checkList.length;i++){
var index = this.checkList[i];
if(this.bookingData.dateList[index]!=undefined){
let date = this.bookingData.dateList[index];
date.status = 0;
date.checked = true;
date.numOfNight = date.date.length-1;
date.numOfRoom = 1;
date.remark = "";
date.bookingStatus = "";
date.submit = true;
getDateList.push(date)
}
}
this.bookingData.dateList = getDateList;
// this.bookingData.dateList.push({
// date:tempDates,
// status:0,
// checked:true,
// numOfNight:tempDates.length-1,
// numOfRoom:1,
// remark:"",
// bookingStatus:""
// });
uni.setStorageSync("bookingData",this.bookingData);
return {"status":1,"sameStatus":0}; // status=1全够分,sameStatus=0状态发生了变化
}else if(res.data.status==1){ // 不够分
if(type==1){
// 把extendDate中的状态都设置成不够分
for(let i=0;i<this.bookingData.extendDate.length;i++){
this.bookingData.extendDate[i].checked = false;
for(let j=0;j<this.checkList.length;j++){
if(i === this.checkList[j]){
this.bookingData.extendDate[i].checked = true;
this.bookingData.extendDate[i].status = 1;
break;
}
}
}
}else{
// 把dateList中的状态都设置成不够分
for(let i=0;i<this.bookingData.dateList.length;i++){
this.bookingData.dateList[i].checked = false;
for(let j=0;j<this.checkList.length;j++){
if(i === this.checkList[j]){
this.bookingData.dateList[i].checked = true;
this.bookingData.dateList[i].status = 1;
break;
}
}
}
}
// 因为来到这个页面就是一部分够分,一部分不够分的,所以进入到这里肯定就是状态发生了变化
// 需要把dateList合并成一条
let tempDates = [];
for(let i=0;i<this.bookingData.dateList.length;i++){
const date = this.bookingData.dateList[i];
if(date.date.length>0){
for(let j=0;j<date.date.length-1;j++){
tempDates.push(date.date[j]);
}
}
}
this.bookingData.dateList = [];
this.bookingData.dateList.push({
date:tempDates,
status:1,
checked:true,
numOfNight:tempDates.length-1,
numOfRoom:1,
remark:"",
bookingStatus:""
});
uni.setStorageSync("bookingData",this.bookingData);
return {"status":3,"sameStatus":0}; // status=3 不够分,sameStatus=0状态发生了变化
}
else if(res.data.status==2){ // 部分够分
const originalArray = res.data.dates;
if(originalArray!=null){
// 初始化结果数组和临时日期数组
let resultArray = [];
let tpdArray = [];
let tempDates = [];
let prevStatus = null;
let prevDate = null;
let sameTPDStatus = 1;
// 遍历原始数组
for (let i = 0; i < originalArray.length; i++) {
const currentObject = originalArray[i];
tpdArray.push(currentObject);
const currentDate = currentObject.date;
const nextDate = new Date(currentDate);
nextDate.setDate(nextDate.getDate()+1);
const currentStatus = currentObject.status;
const currentWaitlist = currentObject.isWaitlist;
// 新拿回来的TPD结果跟旧的做对比,检查是否一样,0表示不一样
for (let a = 0; a < this.bookingData.tpdList.length; a++) {
const tpd = this.bookingData.tpdList[a];
if(currentDate == tpd.date && currentStatus!=tpd.status){
sameTPDStatus = 0;
break;
}
}
// 如果当前status与前一个不同,或者tempDates为空,则添加新的status对象到结果数组
if (prevStatus === null || currentStatus !== prevStatus) {
if (tempDates.length > 0) { // 如果tempDates有数据,则添加到结果数组
// 在添加之前,尝试将tempDates中最大的日期加一天
const lastDate = new Date(tempDates[tempDates.length - 1]);
lastDate.setDate(lastDate.getDate() + 1); // 增加一天
tempDates.push(dayjs(lastDate).format("YYYY-MM-DD"));
resultArray.push({ date: tempDates, status: prevStatus,isWaitlist:currentWaitlist });
tempDates = []; // 重置tempDates
}
prevStatus = currentStatus; // 更新prevStatus
prevDate = dayjs(nextDate).format("YYYY-MM-DD");
}
// 将当前日期添加到tempDates
tempDates.push(currentDate);
// 如果这是最后一个元素,或者下一个元素的status不同,则添加当前status对象到结果数组
if (i === originalArray.length - 1 || (i < originalArray.length - 1 && (currentStatus !== originalArray[i + 1].status || dayjs(nextDate).format("YYYY-MM-DD") !== originalArray[i + 1].date))) {
// 在添加之前,尝试将tempDates中最大的日期加一天
const lastDate = new Date(tempDates[tempDates.length - 1]);
lastDate.setDate(lastDate.getDate() + 1); // 增加一天
tempDates.push(dayjs(lastDate).format("YYYY-MM-DD"));
resultArray.push({ date: tempDates, status: currentStatus,isWaitlist:currentWaitlist });
tempDates = []; // 重置tempDates,为下一个可能的status做准备
}
}
//console.log(resultArray);
this.bookingData.tpdList = tpdArray;
let tempList = [];
if(type==1){
// 重新构建extendDate
tempList = this.bookingData.extendDate;
this.bookingData.extendDate = [];
}else{
// 重新构建dateList
tempList = this.bookingData.dateList;
this.bookingData.dateList = [];
}
for(let i=0;i<resultArray.length;i++){
let objDate = {};
let tpdResult = resultArray[i];
if(tempList[i]!=undefined){
let originList = tempList[i];
let allCheck = false;
let tpdDate = tpdResult.date;
let originDate = originList.date;
if(tempList[i].status===originList.status){
if(tpdDate.length==originDate.length){
let checkNum = 0
for(let g=0;g<tpdDate.length;g++){
if(originDate[g]!=undefined){
if(originDate[g]==tpdDate[g]) checkNum++
}else{
break;
}
}
if(checkNum == tpdDate.length) allCheck=true;
}
}
if(allCheck) objDate = originList;
}
if(objDate.status==undefined){
objDate ={
date:tpdResult.date,
status:tpdResult.status,
checked:false,
remark:'',
numOfNight:tpdResult.date.length-1,
numOfRoom:1,
submit:false,
bookingStatus:'',
isWaitlist:tpdResult.isWaitlist,
roomRemark:'',
showRadio:false,
freeRemark:'',
otherRemark:'',
showRemark:false,
};
objDate.status = objDate.status==1?0:1;
setTimeout(()=>{objDate.status = tpdResult.status;this.$forceUpdate()},1)
}
if(type==1){
this.bookingData.extendDate.push(objDate);
}else{
this.bookingData.dateList.push(objDate);
}
}
this.$forceUpdate();
uni.setStorageSync("bookingData",this.bookingData);
return {"status":2,"sameStatus":sameTPDStatus};
}
else{
return {"status":-1,"sameStatus":-1};
}
}
return {"status":-1,"sameStatus":-1};
}else{
this.showMsg = true;
this.msgStr = res.message;
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][checkBooking][ErrorMessage]"+res.message,"[RequestData]" + JSON.stringify(params),"",1,false);
}
}catch(e){
console.error(e);
this.showMsg = true;
this.msgStr = e.errMsg;
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][checkBooking][Catch Exception]"+e.errMsg,"[RequestData]" + JSON.stringify(params),"",1,false);
}finally{
uni.hideLoading();
}
},
async submitApprovalRequest() {
uni.$u.throttle(this.toNext, 200)
console.log(this.submitLoading);
if(this.submitLoading) return;
this.submitLoading = true;
// 验证当前索引的Reason和Approver是否已选择
if (!this.unqualifiedDateReasons[this.currentUnqualifiedIndex]) {
uni.showToast({
title: 'Please Select Reason',
icon: 'none',
duration: 2000
});
return;
}
const currentApprovers = this.unqualifiedDateApprovers[this.currentUnqualifiedIndex];
if (
(Array.isArray(currentApprovers) && currentApprovers.length === 0) ||
(!Array.isArray(currentApprovers) && !currentApprovers)
) {
uni.showToast({
title: 'Please Select Approver',
icon: 'none',
duration: 2000
});
return;
}
uni.showLoading({
title: this.$t("common.loading")
});
this.showApprovalModal = false;
try {
// 检查选中的记录中是否有waitlist,有的话提示要输入remark
// console.log(this.checkList);
if(this.checkList!=null && this.checkList.length>0){
if(this.bookingData.bookType==1){
// 把extendDate中的状态都设置成不够分
for(let i=0;i<this.bookingData.extendDate.length;i++){
for(let j=0;j<this.checkList.length;j++){
if(i == this.checkList[j]){
// 找到对应的unqualifiedDate索引
const unqualifiedIndex = this.unqualifiedDateList.findIndex(item => item === this.bookingData.extendDate[i]);
if (unqualifiedIndex !== -1) {
if (this.bookingData.extendDate[i].status == 1) {
// remarkText只保存remark输入的内容,不加Extend前缀
this.bookingData.extendData[i].remarkText = this.unqualifiedDateRemarks[unqualifiedIndex] || '';
// 添加approvalReason字段
this.bookingData.extendDate[i].approvalReason = this.unqualifiedDateReasons[unqualifiedIndex] || null;
// 添加approver字段(多选时保存逗号字符串,避免写入 [])
{
const approverIds = this.unqualifiedDateApprovers[unqualifiedIndex] || [];
this.bookingData.extendDate[i].approver = Array.isArray(approverIds) ? approverIds.map(String).join(',') : approverIds;
}
// 添加otherRemark字段
this.bookingData.extendDate[i].otherRemark = this.unqualifiedDateOtherRemarks[unqualifiedIndex] || null;
// 更新request reason
if (this.unqualifiedDateReasons[unqualifiedIndex]) {
this.bookingData.extendDate[i].requestReasonId = this.unqualifiedDateReasons[unqualifiedIndex];
}
// 更新审批人(多选:routerToApproverId 用逗号字符串,routerToApproverName 用姓名列表)
{
const approverIds = this.unqualifiedDateApprovers[unqualifiedIndex] || [];
const hasApprover = Array.isArray(approverIds) ? approverIds.length > 0 : !!approverIds;
if (hasApprover) {
this.bookingData.extendDate[i].routerToApproverId = Array.isArray(approverIds) ? approverIds.map(String).join(',') : approverIds;
const names = (Array.isArray(approverIds) ? approverIds : [approverIds]).map((id) => {
const item = this.selectApproverData.find(opt => String(opt.value) === String(id));
return item ? (item.approverName || item.label || '') : '';
}).filter(Boolean);
this.bookingData.extendDate[i].routerToApproverName = names.join(', ');
}
}
}
}
this.getWaitlistRemark(2,i)
if(this.bookingData.extendDate[i].status==1 && !this.bookingData.remark){
}
}
}
}
}else{
// 把dateList中的状态都设置成不够分
for(let i=0;i<this.bookingData.dateList.length;i++){
for(let j=0;j<this.checkList.length;j++){
if(i == this.checkList[j]){
// 找到对应的unqualifiedDate索引
const unqualifiedIndex = this.unqualifiedDateList.findIndex(item => item === this.bookingData.dateList[i]);
if (unqualifiedIndex !== -1) {
if (this.bookingData.dateList[i].status == 1) {
// remarkText只保存remark输入的内容,不加Extend前缀
this.bookingData.dateList[i].remarkText = this.unqualifiedDateRemarks[unqualifiedIndex] || '';
// 添加approvalReason字段
this.bookingData.dateList[i].approvalReason = this.unqualifiedDateReasons[unqualifiedIndex] || null;
// 添加approver字段(多选时保存逗号字符串,避免写入 [])
{
const approverIds = this.unqualifiedDateApprovers[unqualifiedIndex] || [];
this.bookingData.dateList[i].approver = Array.isArray(approverIds) ? approverIds.map(String).join(',') : approverIds;
}
// 添加otherRemark字段
this.bookingData.dateList[i].otherRemark = this.unqualifiedDateOtherRemarks[unqualifiedIndex] || null;
// 更新request reason
if (this.unqualifiedDateReasons[unqualifiedIndex]) {
this.bookingData.dateList[i].requestReasonId = this.unqualifiedDateReasons[unqualifiedIndex];
}
// 更新审批人(多选:routerToApproverId 用逗号字符串;routerToApproverName 用姓名列表)
{
const approverIds = this.unqualifiedDateApprovers[unqualifiedIndex] || [];
const hasApprover = Array.isArray(approverIds) ? approverIds.length > 0 : !!approverIds;
if (hasApprover) {
this.bookingData.dateList[i].routerToApproverId = Array.isArray(approverIds) ? approverIds.map(String).join(',') : approverIds;
const names = (Array.isArray(approverIds) ? approverIds : [approverIds]).map((id) => {
const item = this.selectApproverData.find(opt => String(opt.value) === String(id));
return item ? (item.approverName || item.label || '') : '';
}).filter(Boolean);
this.bookingData.dateList[i].routerToApproverName = names.join(', ');
}
}
}
}
this.getWaitlistRemark(1,i);
if(this.bookingData.dateList[i].status==1 && !this.bookingData.remark && !this.bookingData.dateList[i].remark){
}
}
}
}
}
}else{
return false;
}
// 更新被选中的dateList的submit状态
if(this.bookingData.bookType!=1){
for(let i=0;i<this.bookingData.dateList.length;i++){
for(let j=0;j<this.checkList.length;j++){
if(i == this.checkList[j]){
this.bookingData.dateList[i].submit = true;
}
}
}
}
this.bookingData.requestReasonId = this.selectedReason;
this.bookingData.routerToApproverId = Array.isArray(this.selectedApprover)
? this.selectedApprover.map(String).join(',')
: this.selectedApprover;
this.bookingData.routerToApproverName = this.selectedApproverName;
this.bookingData.isApproval = 1;
console.log(this.bookingData);
// 保存waitlist
const res = await saveBooking(this.bookingData);
// 如果成功
if (res.success === true) {
//this.url = '/booking/bookingDetail/bookingDetail?id='+resultBookings[0].id+'&conf='+resultBookings[0].confirmationNo+'&from=booking';
this.url = "/booking/bookingRecord/bookingRecord?from=booking";
this.buttonStr = this.$t(
"bookingConfirm.backToRecords"); //this.$t("newWailist.viewSubmitedWaitlist");
this.msgStr = this.$t("bookingConfirm.alert1_1") + "<br /><span class='hz-font-xl'>" + this
.playerData.playerId + "</span><br />" + this.$t(
"bookingConfirm.alert2"); //this.$t("newWaitlist.savesuccessful");
this.iconPath = '../../static/images/ico_suc.png';
this.showDirBtn = true;
this.showMsgBox = true;
} else {
var message = res.errorCode != "" ? res.errorCode : res.message;
this.buttonStr = this.$t("common.ok");
this.iconPath = '../../static/images/ico_err.png';
this.msgStr = this.$t("common.saveFail") + ". " + this.$t("common.errorMsg") + ": " +
message; // 具體的錯誤信息,errorCode要做一个mapping,对应一些什么错误
this.url = '';
this.showMsgBox = true;
await this.writeLog(this.userData.userId, "save_booking", "",
"[APP][bookingConfirm.vue][submitApprovalRequest][ErrorMessage]" + res.message,
"[RequestData]" + JSON.stringify(this.bookingData), "", 1, false);
}
} catch (e) {
console.error(e);
uni.$u.toast(e.errMsg, 5000);
var request = e.config != undefined ? JSON.stringify(e.config) : "";
var response = e.data != undefined ? JSON.stringify(e.data) : "";
await this.writeLog(this.userData.userId, "save_booking", "",
"[APP][bookingConfirm.vue][submitWaitlist][Catch Exception]" + e.errMsg, request, response,
1, false);
} finally {
this.submitLoading = false;
this.showModalBtn = false;
uni.hideLoading();
}
},
async submitBooking(){
uni.$u.throttle(this.toNext, 200)
if(this.submitLoading) return;
this.submitLoading = true;
// 如果dateList里面有bookingStatus!=''的证明已经提交过,回退回来的
/*const isBack = this.checkBack();
if(isBack){
this.navTo('/booking/submitBooking/submitBooking',0,false);
}*/
// 检查选中的记录中是否有waitlist,有的话提示要输入remark
if(this.checkList!=null && this.checkList.length>0){
if(this.bookingData.bookType==1){
// 把extendDate中的状态都设置成不够分
for(let i=0;i<this.bookingData.extendDate.length;i++){
for(let j=0;j<this.checkList.length;j++){
if(i == this.checkList[j]){
this.getWaitlistRemark(2,i)
if(this.bookingData.extendDate[i].status==1 && !this.bookingData.remark){
// uni.$u.toast(this.inputRemark);
// return;
}
}
}
}
}else{
// 把dateList中的状态都设置成不够分
for(let i=0;i<this.bookingData.dateList.length;i++){
for(let j=0;j<this.checkList.length;j++){
if(i == this.checkList[j]){
this.getWaitlistRemark(1,i)
if(this.bookingData.dateList[i].status==1 && !this.bookingData.remark && !this.bookingData.dateList[i].remark){
// uni.$u.toast(this.inputRemark);
// return;
}
}
}
}
}
}else{
return false;
}
try{
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][Begin]","","",0,true);
// 檢查是否状态发生了变化
var resCheck = await this.checkBooking(this.bookingData.bookType);
// 如果有waitlist的情况必须输入remark
/*if((resCheck.status===2 || resCheck.status===3) && !this.bookingData.remark){
uni.$u.toast(this.inputRemark);
return;
}*/
uni.showLoading({
title: this.$t("common.loading")
});
if(resCheck.status ===-1){
// 出错
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][CheckBooking Result]0","","",0,false);
return;
}
if(resCheck.status===1 || (resCheck.status===2 && resCheck.sameStatus===1)) // 狀態是全部够分,全部不够分,部分够分并且状态没发生变化的,提交记录
{
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][CheckBooking Result]status="+resCheck.status+", sameStatus="+resCheck.sameStatus,"","",0,false);
for(let b=0;b<this.bookingData.dateList.length;b++){
let dateObj = this.bookingData.dateList[b];
this.bookingData.dateList[b].submit = false;
for(let i=0;i<this.checkList.length;i++){
if(b==this.checkList[i]){
this.bookingData.dateList[b].submit = true;
break;
}
}
}
let resBook = null;
if(this.bookingData.bookType=='1'){
resBook = await editBooking(this.bookingData);
}else{
resBook = await saveBooking(this.bookingData);
}
// 保存數據成功,彈出對話框,點View Booking去到bookingDetail
if(resBook.success==true){
console.log('createSucce');
this.buttonStr = this.$t("bookingConfirm.backToRecords");
this.iconPath = '../../static/images/ico_suc.png';
if(this.bookingData.bookType == '0'){
this.msgStr = this.$t("submitBooking.submitedSuccessful");
}
else
{
if(resBook.errorCode=="EMAIL"){
this.msgStr = this.$t("bookingConfirm.extensionEmail");
}else if(resBook.errorCode=="OWS_ERROR"){
this.msgStr = resBook.message;
}else{
this.msgStr = this.$t("bookingConfirm.extensionProccessing");
}
}
uni.setStorageSync("bookingData",this.bookingData);
const resultBookings = resBook.data;
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][Success][Pending Result Count]"+resultBookings.length,"","",0,false);
if(resultBookings.length==1){
this.showDateList = false;
}else if(resultBookings.length>1){
this.showDateList = true;
}
this.url = "/booking/bookingRecord/bookingRecord?from=booking";
this.showMsgBox = true;
this.showWaitlistModal = false;
}
// 保存失敗彈出錯誤提示框
else
{
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][ErrorMessage]"+resBook.message,"[RequestData]" + JSON.stringify(this.bookingData),"",1,false);
this.buttonStr = this.$t("common.ok");
this.iconPath = '../../static/images/ico_err.png';
this.msgStr = this.$t("common.saveFail") + ". "+this.$t("common.errorMsg")+": "+ resBook.errorCode; // 具體的錯誤信息
this.url = '';
this.showMsgBox = true;
}
}
else // 如果狀態不一樣,重新回到當前頁面重新勾選
{
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][CheckBooking Result]2=TPD status change","","",0,false);
this.buttonStr = this.$t("bookingConfirm.viewBooking");
this.iconPath = '../../static/images/ico_warn.png';
this.msgStr = this.$t("submitBooking.alert1");
this.url = "/booking/submitBooking/submitBooking"
this.showMsgBox = true;
}
}catch(e){
uni.hideLoading();
console.error(e);
// 把錯誤信息寫入log
uni.$u.toast(e.errMsg,5000);
var request = e.config!=undefined?JSON.stringify(e.config):"";
var response = e.data!=undefined?JSON.stringify(e.data):"";
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][Catch Exception]"+e.errMsg,request,response,1,false);
}finally{
this.showModalBtn = false;
this.submitLoading = false;
this.showSubmitMsg = false;
uni.hideLoading();
await this.writeLog(this.userData.userId,"save_booking","","[APP][submitBooking.vue][submitBooking][End]","","",0,false);
}
},
checkWaitlist(){
var dates = [];
let isWaitlist = false;
var waitlistCount = 0;
var criteriaCount = this.bookingData.criteriaList.length;
var lastDate = 0;
for(let i=0;i<criteriaCount;i++){
let criteria = this.bookingData.criteriaList[i];
if(criteria.bookDate == this.bookingData.checkOutDate){
lastDate = 1; //不计算checkoutDate
continue;
}
var obj = { "date": criteria.bookDate, "status": 0 };
if(criteria.isWaitlist == 1) {
obj.status = 1;
obj.isWaitlist = 1;
isWaitlist = true;
waitlistCount++;
}
dates.push(obj);
}
criteriaCount = criteriaCount-lastDate;
if(isWaitlist&&waitlistCount<criteriaCount){ //部分日期waitlist
return {'status':1,'dates':dates}
}else if(isWaitlist&&waitlistCount==criteriaCount){//全部日期waitlist
return {'status':2,'dates':dates}
}else{//没waitlist
return {'status':0}
}
},
getWaitlistRemark(type,index){
let item = (type==2?this.bookingData.extendDate[index]:this.bookingData.dateList[index]);
let remarkArr = [];
let roomRemark = this.bookingData.roomRemark;
let otherRemark = this.bookingData.otherRemark;
if(roomRemark!=''&&roomRemark!=undefined) remarkArr.push(roomRemark);
if(otherRemark!=''&&otherRemark!=undefined) remarkArr.push(otherRemark);
// 找到对应的unqualifiedDate索引
const unqualifiedIndex = this.unqualifiedDateList.findIndex(uItem => uItem === item);
let extendStr = '';
if (unqualifiedIndex !== -1) {
const checkboxState = this.unqualifiedDateCheckboxStates[unqualifiedIndex] || [];
if (checkboxState.includes('Extend')) {
extendStr = 'Extend';
}
}
if (item.status == 1 &&
item.remarkText != '' &&
item.remarkText != undefined) {
if (extendStr) {
remarkArr.push(extendStr + '; ' + item.remarkText);
} else {
remarkArr.push(item.remarkText);
}
} else if (item.status == 1 && extendStr) {
remarkArr.push(extendStr);
}
if(this.showRemark&&this.freeRemark!=''&&item.status==1) remarkArr.push(this.freeRemark);
if(remarkArr.length>0) {
this.bookingData.remark = remarkArr.join('; ');
item.remark = remarkArr.join('; ');
}else{
this.bookingData.remark = "";
item.remark = "";
}
if(type==2){
this.bookingData.extendDate[index] = item;
}else{
this.bookingData.dateList[index] = item
}
},
getCheckInDate() {
if (this.unqualifiedDateList.length > 0 && this.unqualifiedDateList[this.currentUnqualifiedIndex].date && this.unqualifiedDateList[this.currentUnqualifiedIndex].date.length > 0) {
return this.unqualifiedDateList[this.currentUnqualifiedIndex].date[0];
}
return 'No data';
},
getCheckOutDate() {
if (this.unqualifiedDateList.length > 0 && this.unqualifiedDateList[this.currentUnqualifiedIndex].date && this.unqualifiedDateList[this.currentUnqualifiedIndex].date.length > 0) {
return this.unqualifiedDateList[this.currentUnqualifiedIndex].date[this.unqualifiedDateList[this.currentUnqualifiedIndex].date.length - 1];
}
return 'No data';
},
// 切换到上一个 UnQualified 的 booking
previousUnQualifiedBooking() {
if (this.currentUnqualifiedIndex > 0) {
// 切换到上一个booking
this.currentUnqualifiedIndex--;
// 恢复上一个booking的状态
this.restoreBookingState(this.currentUnqualifiedIndex);
}
this.getApprover();
},
// 切换到下一个 UnQualified 的 booking
nextUnQualifiedBooking() {
// 验证当前索引的Reason和Approver是否已选择
if (!this.unqualifiedDateReasons[this.currentUnqualifiedIndex]) {
uni.showToast({
title: 'Please Select Reason',
icon: 'none',
duration: 2000
});
return;
}
const currentApprovers = this.unqualifiedDateApprovers[this.currentUnqualifiedIndex];
const hasApprover = Array.isArray(currentApprovers) ? currentApprovers.length > 0 : !!currentApprovers;
if (!hasApprover) {
uni.showToast({
title: 'Please Select Approver',
icon: 'none',
duration: 2000
});
return;
}
if (this.currentUnqualifiedIndex < this.unqualifiedDateList.length - 1) {
// 切换到下一个booking
this.currentUnqualifiedIndex++;
// 恢复下一个booking的状态
this.restoreBookingState(this.currentUnqualifiedIndex);
}
this.getApprover();
},
// 恢复booking状态
restoreBookingState(index) {
// 恢复otherRemark
const otherRemark = this.unqualifiedDateOtherRemarks[index];
// 恢复checkbox状态
const checkboxState = this.unqualifiedDateCheckboxStates[index] || [];
// 恢复showRemark状态
this.showRemark = checkboxState.includes('Remark');
// 触发changeOtherRemark方法来更新状态
this.changeOtherRemark(checkboxState);
},
// 获取 UnQualified 的 booking 日期
getUnQualifiedBookingDate() {
// 打印两种日期数据
if (this.bookingData.extendDate != null) {
tempDateList = this.bookingData.extendDate;
} else {
tempDateList = this.bookingData.dateList;
}
// dateFormat(item.date[0])}}&nbsp; {{$t("common.to")}}&nbsp; {{dateFormat(item.date[item.date.length-1])
// let item = type == 2 ? this.bookingData.extendDate[index] : this.bookingData.dateList[index];
// console.log(item);
},
showWaitlistPop() {
this.showWaitlistModal = true;
this.showMsgBox = false;
},
// 界面方法
generateUniqueId() {
// 获取当前时间戳(毫秒)
let timestamp = Date.now();
// 生成一个随机的数字(0-9999)
let randomNumber = Math.floor(Math.random() * 10000);
// 将时间戳和随机数组合成一个字符串
let id = timestamp + '-' + randomNumber;
return id;
},
selectBooking(e){
this.checkList = e;
},
checkBack(){
let dateList = this.bookingData.dateList;
for(let i=0;i<dateList.length;i++){
if(dateList[i].bookingStatus!=''){
return true;
}
}
return false;
},
navToDetail(url){
if(url!=null && url!==undefined && url!==''){
this.navTo(url,0,false);
}else{
this.showMsgBox = false;
}
},
copyText(text) {
uni.setClipboardData({
data: text,
success: () => {
uni.$u.toast("copied",3000);
},
fail: (err) => {
console.log('copy failed:', err);
}
});
},
changeRoomRemark(e,item) {
if (e) {
if(e==item.roomRemark){
item.roomRemark=""
item.showRadio = true;
setTimeout(()=>{item.showRadio = false;this.$forceUpdate()},1)
}else{
item.roomRemark=e
}
}
this.$forceUpdate()
},
// changeOtherRemark(e,item) {
// if (e) {
// let str = '';
// let show = false;
// for (let i = 0; i < e.length; i++) {
// if(e[i]=='Remark'){
// show = true;
// }else{
// str=e[i];
// }
// }
// console.log(item);
// item.showRemark = show;
// item.otherRemark = str;
// this.$forceUpdate()
// }
// },
changeOtherRemark(e) {
if (e) {
let str = '';
let show = false;
for (let i = 0; i < e.length; i++) {
if (e[i] == 'Remark') {
show = true;
} else {
str = e[i];
}
}
this.showRemark = show;
// 存储到当前索引的otherRemark
this.unqualifiedDateOtherRemarks[this.currentUnqualifiedIndex] = str;
// 存储checkbox状态
this.unqualifiedDateCheckboxStates[this.currentUnqualifiedIndex] = e;
} else {
this.showRemark = false;
this.unqualifiedDateOtherRemarks[this.currentUnqualifiedIndex] = '';
this.unqualifiedDateCheckboxStates[this.currentUnqualifiedIndex] = [];
}
},
initUI() {
this.deviceData = uni.getStorageSync("deviceData");
this.title = this.$t("submitBooking.title");
this.windowWidth = this.deviceData.windowWidth-70;
// 判斷iphone下方安全區域
const area = this.deviceData.saveArea;
if(area){
this.footFuncHei = 0;
}
},
},
computed:{
getStatusColor(){
return function (booking) {
let operaStatus = null;
if(booking==null){
return '';
}
if(booking.lastOperaStatus!=null){
operaStatus = booking.lastOperaStatus;
}
let approveStatus = null;
if(booking.approveStatus!=null){
approveStatus = booking.approveStatus;
}
// Opera和Approve Status都不为空的情况
if((operaStatus!=null && operaStatus!=undefined) || (approveStatus!=null && approveStatus!=undefined))
{
if(approveStatus.toUpperCase()==='PN'){
return 'hz-status-pending';
}else if(approveStatus.toUpperCase()==='N'){
if(operaStatus!==null && operaStatus!==undefined && operaStatus!=='' && operaStatus!=='null'){
if(operaStatus.toUpperCase()==='DUE_IN'){
return 'hz-status-duein';
}
else if(operaStatus.toUpperCase()==='CHECKED_IN'){
return 'hz-status-checkedin';
}
else if(operaStatus.toUpperCase()==='CHECKED_OUT'){
return 'hz-status-waitlist';
}
else if(operaStatus.toUpperCase()==='DUE_OUT'){
return 'hz-status-dueout';
}
else if(operaStatus.toUpperCase()==='RESERVED'){
return 'hz-status-reserved';
}
else
{
return '';
}
}
}else if(approveStatus.toUpperCase()==='W'){
return 'hz-status-waitlist';
}
else
{
if(operaStatus==null) return '';
if(operaStatus.toUpperCase()==='DUE_IN'){
return 'hz-status-duein';
}
else if(operaStatus.toUpperCase()==='CHECKED_IN'){
return 'hz-status-checkedin';
}
else if(operaStatus.toUpperCase()==='CHECKED_OUT'){
return 'hz-status-waitlist';
}
else if(operaStatus.toUpperCase()==='DUE_OUT'){
return 'hz-status-dueout';
}
else if(operaStatus.toUpperCase()==='RESERVED'){
return 'hz-status-reserved';
}
else
{
return '';
}
}
}
// Opera status为空,Approve Status不为空的情况
else if((operaStatus==null || operaStatus==undefined) && (approveStatus!=null && approveStatus!=undefined))
{
if(approveStatus.toUpperCase()==='PN'){
return 'hz-status-font-pending';
}else if(approveStatus.toUpperCase()==='W'){
return 'hz-status-font-waitlist';
}else{
return '';
}
}
}
},
getStatusTextColor(){
return function (booking) {
let operaStatus = null;
if(booking==null){
return '';
}
if(booking.lastOperaStatus!=null){
operaStatus = booking.lastOperaStatus;
}
let approveStatus = null;
if(booking.approveStatus!=null){
approveStatus = booking.approveStatus;
}
// Opera和Approve Status都不为空的情况
if((operaStatus!=null && operaStatus!=undefined) || (approveStatus!=null && approveStatus!=undefined))
{
if(approveStatus.toUpperCase()==='PN'){
return 'hz-status-font-pending';
}else if(approveStatus.toUpperCase()==='N'){
if(operaStatus!==null && operaStatus!==undefined && operaStatus!=='' && operaStatus!=='null'){
if(operaStatus.toUpperCase()==='DUE_IN'){
return 'hz-status-font-duein';
}
else if(operaStatus.toUpperCase()==='CHECKED_IN'){
return 'hz-status-font-checkedin';
}
else if(operaStatus.toUpperCase()==='CHECKED_OUT'){
return 'hz-status-font-waitlist';
}
else if(operaStatus.toUpperCase()==='DUE_OUT'){
return 'hz-status-font-dueout';
}
else if(operaStatus.toUpperCase()==='RESERVED'){
return 'hz-status-font-reserved';
}
else
{
return '';
}
}
}else if(approveStatus.toUpperCase()==='W'){
return 'hz-status-font-waitlist';
}
else
{
if(operaStatus==null) return '';
if(operaStatus.toUpperCase()==='DUE_IN'){
return 'hz-status-font-duein';
}
else if(operaStatus.toUpperCase()==='CHECKED_IN'){
return 'hz-status-font-checkedin';
}
else if(operaStatus.toUpperCase()==='CHECKED_OUT'){
return 'hz-status-font-waitlist';
}
else if(operaStatus.toUpperCase()==='DUE_OUT'){
return 'hz-status-font-dueout';
}
else if(operaStatus.toUpperCase()==='RESERVED'){
return 'hz-status-font-reserved';
}
else
{
return '';
}
}
}
// Opera status为空,Approve Status不为空的情况
else if((operaStatus==null || operaStatus==undefined) && (approveStatus!=null && approveStatus!=undefined))
{
if(approveStatus.toUpperCase()==='PN'){
return 'hz-status-font-pending';
}else if(approveStatus.toUpperCase()==='W'){
return 'hz-status-font-waitlist';
}
else{
return '';
}
}
}
},
getStatusText(){
return function (booking) {
let operaStatus = null;
if(booking==null){
return;
}
if(booking.lastOperaStatus!=null){
operaStatus = booking.lastOperaStatus;
}
let approveStatus = null;
if(booking.approveStatus!=null){
approveStatus = booking.approveStatus;
}
if((operaStatus!=null && operaStatus!=undefined) || (approveStatus!=null && approveStatus!=undefined))
{
if(approveStatus.toUpperCase()==='PN' || approveStatus.toUpperCase()==='W'){
if(approveStatus!==null && approveStatus!==undefined && approveStatus!=='' && approveStatus!=='null')
return mapApproveStatus(approveStatus.toUpperCase());
}else if( approveStatus.toUpperCase()==='N'){
if(operaStatus!==null && operaStatus!==undefined && operaStatus!=='' && operaStatus!=='null')
return mapOperaStatus(operaStatus.toUpperCase());
}
}
else if((operaStatus==null || operaStatus==undefined) && (approveStatus!=null && approveStatus!=undefined))
{
return mapApproveStatus(approveStatus.toUpperCase());
}
}
},
getSpecial(){
return function (specialName,bedTypeName) {
let str = ''
if(bedTypeName!=null && bedTypeName!=''){
str = bedTypeName;
}
if(specialName!=null && specialName!=''){
if(str == ''){
str = specialName;
}else{
str = str+", "+ specialName;
}
}
return str;
}
},
getSharer(){
return function (playerId,name) {
let id = null;
if(playerId!==null && playerId!==undefined && playerId!=='' && playerId!=='null'){
id = playerId;
}
let na = null;
if(name!==null && name!==undefined && name!=='' && name!=='null'){
na = name;
}
let res = '';
if(id!=null){
res = id;
}
if(na!=null){
if(res!==''){
res = res + ' ('+na+')';
}else{
res = na;
}
}
return res;
}
},
dateFormat() {
return function (date) {
if (date != undefined) {
let weekNum = dayjs(date).day();
let week = '';
switch(weekNum){
case 1:
week='Mon'
break;
case 2:
week='Tue';
break;
case 3:
week='Wed';
break;
case 4:
week='Thu';
break;
case 5:
week='Fri';
break;
case 6:
week='Sat';
break;
case 0:
week='Sun';
break;
}
return '('+week+') ' + dayjs(date).format("YYYY-MM-DD");
}
}
},
getNight(){
return function (num) {
if(num!==null && num!==undefined && num!=='null')
{
if(num>1){
return num + " " + this.$t("common.nights");
}else{
return num + " " + this.$t("common.night");
}
}
else
return '';
}
},
getRoom(){
return function (num) {
if(num!==null && num!==undefined && num!=='null')
{
if(num>1){
return num + " " + this.$t("common.rooms");
}else{
return num + " " + this.$t("common.room");
}
}
else
return '';
}
},
getIsCheck(){
return function (index) {
let res = false
for(let i of this.checkList){
if(i==(index+"")){
res = true;
break;
}
}
return res
}
},
}
}
</script>
<style lang="scss" scoped>
.u-border {
border-width: 0.5px !important;
border-color: #ccc !important;
border-style: solid;
}
.approvalHeader {
font-size: 25px;
font-weight: bold;
text-align: center;
display: block;
color: #C39A4B;
margin-bottom: 15px;
}
</style>