fix bugs
This commit is contained in:
@@ -18,7 +18,8 @@
|
||||
<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="getDataByPage" src="../../static/images/ico_list.png" class="hz-nav-btn"></image>
|
||||
<image v-if="userData && userData.canViewCalendar === true" @click="navToPlayerRoomCalendar" src="../../static/images/calendar-line.png" class="hz-nav-btn"></image>
|
||||
<image v-else @click="getDataByPage" src="../../static/images/ico_list.png" class="hz-nav-btn"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-navbar>
|
||||
@@ -152,6 +153,11 @@
|
||||
this.pullDownRefresh();
|
||||
},
|
||||
methods: {
|
||||
navToPlayerRoomCalendar(){
|
||||
const userData = uni.getStorageSync("userData");
|
||||
if (!userData || userData.canViewCalendar !== true) return;
|
||||
this.navTo('/booking/playerRoomCalendar/playerRoomCalendar',0,false);
|
||||
},
|
||||
// 數據方法
|
||||
async getDataByPage(){
|
||||
if(this.userData.canViewBooking==false) return;
|
||||
@@ -549,10 +555,10 @@
|
||||
return function (booking) {
|
||||
if(booking.approveStatus==='W'|| booking.approveStatus==='WA'){
|
||||
return 'hz-card-waitlist'
|
||||
}else if((booking.lastOperaStatus==='DUE_OUT' || booking.lastOperaStatus==='CHECKED_IN') && booking.confirmationNo!=null && (booking.sharer==null || booking.sharer==='[]' || booking.sharer==='')){
|
||||
return 'hz-card-booking'
|
||||
}else if(booking.approveStatus==='AP'){
|
||||
return 'hz-card-approval'
|
||||
}else if((booking.lastOperaStatus==='DUE_OUT' || booking.lastOperaStatus==='CHECKED_IN') && booking.confirmationNo!=null && (booking.sharer==null || booking.sharer==='[]' || booking.sharer==='')){
|
||||
return 'hz-card-booking'
|
||||
}else{
|
||||
return 'hz-card-booking'
|
||||
}
|
||||
@@ -576,4 +582,4 @@
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -460,6 +460,7 @@
|
||||
this.modelBooking.propertyId = this.userData.propertyId;
|
||||
|
||||
this.modelBooking.teamId = this.userData.teamStructureId;
|
||||
this.modelBooking.sectionName = this.userData.section;
|
||||
this.modelBooking.sectionId = this.userData.sectionId;
|
||||
this.modelBooking.createdBy = this.userData.userId;
|
||||
this.modelBooking.createdByName = this.userData.userName;
|
||||
@@ -806,10 +807,10 @@
|
||||
let item = this.modelBooking.sharerList[index];
|
||||
let book = uni.getStorageSync("bookingData")
|
||||
let oldItem = book.sharerList[index];
|
||||
//清空plaerId
|
||||
// if (item.name != oldItem.name && item.playerId.length == 8) {
|
||||
// item.playerId = "";
|
||||
// }
|
||||
// 姓名被手动修改后,清除不再匹配的玩家 ID。
|
||||
if (item.name != oldItem.name && item.playerId.length > 4) {
|
||||
item.playerId = "";
|
||||
}
|
||||
},
|
||||
async buildCalendar() {
|
||||
uni.showLoading({
|
||||
|
||||
@@ -0,0 +1,867 @@
|
||||
<template>
|
||||
<view class="player-room-calendar-page">
|
||||
<u-navbar
|
||||
:safeAreaInsetTop="true"
|
||||
:placeholder="true"
|
||||
:title="title"
|
||||
:fixed="true"
|
||||
:autoBack="false"
|
||||
leftIconColor="#000000"
|
||||
titleStyle="font-weight:bold;"
|
||||
@leftClick="back"
|
||||
>
|
||||
<view slot="right" class="calendar-refresh-btn" @click.stop="refreshCalendar">
|
||||
<u-icon name="reload" size="24" color="#000000"></u-icon>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<!-- <view class="player-summary"> -->
|
||||
<view class="hz-card-profile mb-[40]" style="margin:9px 9px 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" >{{ safePlayerData.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" >{{ safePlayerData.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" >{{ playerName }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- </view> -->
|
||||
|
||||
<view class="calendar-panel">
|
||||
<view class="property-tabs">
|
||||
<u-tabs
|
||||
:current="selectedPropertyIndex"
|
||||
:scrollable="true"
|
||||
:list="propertyTabList"
|
||||
lineColor="#C39A4B"
|
||||
:itemStyle="propertyTabItemStyle"
|
||||
:activeStyle="propertyTabActiveStyle"
|
||||
:inactiveStyle="propertyTabInactiveStyle"
|
||||
@change="changePropertyTab"
|
||||
></u-tabs>
|
||||
</view>
|
||||
|
||||
<view class="room-type-grid">
|
||||
<view
|
||||
v-for="option in currentSelectorList"
|
||||
:key="option.code"
|
||||
class="room-type-btn"
|
||||
:class="{ active: selectedSelectorCodes.indexOf(option.code) !== -1 }"
|
||||
@click="toggleSelectorOption(option.code)"
|
||||
>
|
||||
{{ option.label }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="calendarNoPermission" class="calendar-empty-state">
|
||||
<view class="hz-flex-row calendar-empty-image-row">
|
||||
<image src="/static/images/datanull.png" class="calendar-empty-image"></image>
|
||||
</view>
|
||||
<view class="hz-flex-row hz-font-bolder hz-font-md calendar-empty-text">
|
||||
{{$t("todo.noPermission")}}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<room-calendar-grid
|
||||
v-else-if="calendarReady"
|
||||
:key="calendarRenderKey"
|
||||
mode="qualification"
|
||||
:months="calendarMonths"
|
||||
:weekday-labels="weekdayLabels"
|
||||
:room-types="selectedRoomTypes"
|
||||
:data-map="qualificationMap"
|
||||
:initial-week-id="todayWeekId"
|
||||
:center-content="true"
|
||||
:show-leader="false"
|
||||
></room-calendar-grid>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from '../../uni_modules/uview-ui/libs/util/dayjs.js';
|
||||
import {
|
||||
buildCalendarDateRange,
|
||||
getTodayWeekId,
|
||||
mapRoomCalendarQualificationRecords,
|
||||
} from '../../common/roomCalendarUi.js';
|
||||
import { getPlayerRoomQualification, getPropertiesRoomTypes } from '../../api/roomCalendarApi.js';
|
||||
import { getCalendarSetting as requestCalendarSetting } from '../../api/configApi.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: this.$t("roomCalendar.playerTitle"),
|
||||
userData: null,
|
||||
playerData: null,
|
||||
selectedPropertyCode: '',
|
||||
selectedRoomTypeCodes: [],
|
||||
selectedOtherPropertyCodes: [],
|
||||
qualificationMap: {},
|
||||
calendarPreviousDays: 0,
|
||||
calendarVisibleDays: 90,
|
||||
calendarYesterdayStart: '',
|
||||
calendarYesterdayEnd: '',
|
||||
maxSelectedRoomTypes: 0,
|
||||
calendarToday: dayjs().format('YYYY-MM-DD'),
|
||||
calendarStartDate: '',
|
||||
calendarEndDate: '',
|
||||
calendarMonths: [],
|
||||
calendarReady: false,
|
||||
calendarNoPermission: false,
|
||||
calendarRenderKey: 0,
|
||||
calendarRequestTask: null,
|
||||
calendarRequestId: 0,
|
||||
weekdayLabels: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
propertyList: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
safePlayerData() {
|
||||
return this.playerData || {};
|
||||
},
|
||||
playerName() {
|
||||
const salutation = this.safePlayerData.salutation || '';
|
||||
const name = this.safePlayerData.name || '';
|
||||
const text = `${salutation} ${name}`.trim();
|
||||
return text || '-';
|
||||
},
|
||||
currentProperty() {
|
||||
return this.propertyList.find(item => item.code === this.selectedPropertyCode) || this.propertyList[0] || {
|
||||
defaultRoomTypes: [],
|
||||
roomTypes: [],
|
||||
};
|
||||
},
|
||||
isOtherProperty() {
|
||||
return this.selectedPropertyCode === 'OTHER';
|
||||
},
|
||||
currentRoomTypes() {
|
||||
return this.currentProperty.roomTypes || [];
|
||||
},
|
||||
currentOtherProperties() {
|
||||
return this.currentProperty.otherProperties || [];
|
||||
},
|
||||
currentSelectorList() {
|
||||
if (this.isOtherProperty) {
|
||||
return this.currentOtherProperties.map(item => ({
|
||||
code: item.code,
|
||||
label: item.code,
|
||||
}));
|
||||
}
|
||||
return this.currentRoomTypes;
|
||||
},
|
||||
selectedSelectorCodes() {
|
||||
return this.isOtherProperty ? this.selectedOtherPropertyCodes : this.selectedRoomTypeCodes;
|
||||
},
|
||||
selectedOtherProperties() {
|
||||
return this.currentOtherProperties.filter(item => this.selectedOtherPropertyCodes.indexOf(item.code) !== -1);
|
||||
},
|
||||
selectedRoomTypes() {
|
||||
if (this.isOtherProperty) {
|
||||
return this.selectedOtherProperties.reduce((list, property) => {
|
||||
(property.roomTypes || []).forEach(roomType => {
|
||||
list.push({
|
||||
...roomType,
|
||||
code: this.getOtherPropertyRoomTypeCode(property.code, roomType.code),
|
||||
displayName: roomType.label,
|
||||
parentCode: property.code,
|
||||
propertyCode: property.code,
|
||||
requestRoomTypeCode: roomType.code,
|
||||
});
|
||||
});
|
||||
return list;
|
||||
}, []);
|
||||
}
|
||||
const selected = this.currentRoomTypes.filter(item => this.selectedRoomTypeCodes.indexOf(item.code) !== -1);
|
||||
return selected;
|
||||
},
|
||||
selectedPropertyIndex() {
|
||||
const index = this.propertyList.findIndex(item => item.code === this.selectedPropertyCode);
|
||||
return index === -1 ? 0 : index;
|
||||
},
|
||||
propertyTabList() {
|
||||
return this.propertyList.map(item => ({
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
}));
|
||||
},
|
||||
propertyTabItemStyle() {
|
||||
return {
|
||||
height: '70rpx',
|
||||
padding: '0 24rpx',
|
||||
flexShrink: 0,
|
||||
};
|
||||
},
|
||||
propertyTabActiveStyle() {
|
||||
return {
|
||||
whiteSpace: 'nowrap',
|
||||
color: '#C39A4B',
|
||||
fontFamily: 'Inter-Bold',
|
||||
fontSize: '30rpx',
|
||||
fontWeight: 'bold',
|
||||
};
|
||||
},
|
||||
propertyTabInactiveStyle() {
|
||||
return {
|
||||
whiteSpace: 'nowrap',
|
||||
color: '#111111',
|
||||
fontFamily: 'Inter-Bold',
|
||||
fontSize: '30rpx',
|
||||
fontWeight: 'bold',
|
||||
};
|
||||
},
|
||||
todayWeekId() {
|
||||
return getTodayWeekId(this.calendarMonths);
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.playerData = uni.getStorageSync("playerData");
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
this.loadPropertiesRoomTypes();
|
||||
},
|
||||
onShow() {
|
||||
this.$i18n.locale = uni.getLocale();
|
||||
this.title = this.$t("roomCalendar.playerTitle");
|
||||
},
|
||||
onUnload() {
|
||||
this.calendarRequestId += 1;
|
||||
this.abortCalendarRequest();
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
this.navBack();
|
||||
},
|
||||
async loadPropertiesRoomTypes() {
|
||||
if (!this.canLoadPlayerCalendar()) return;
|
||||
try {
|
||||
this.calendarReady = false;
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading"),
|
||||
});
|
||||
await this.loadCalendarSetting();
|
||||
const res = await getPropertiesRoomTypes({});
|
||||
if (this.isNoPermissionResponse(res)) {
|
||||
this.showCalendarNoPermission();
|
||||
return;
|
||||
}
|
||||
this.propertyList = Array.isArray(res && res.propertyList) ? res.propertyList : [];
|
||||
if (!this.propertyList.length) throw new Error('No calendar properties configured');
|
||||
this.selectedPropertyCode = this.getDefaultPropertyCode();
|
||||
this.selectDefaultOptions();
|
||||
this.buildCalendar();
|
||||
await this.loadQualificationData();
|
||||
this.calendarRenderKey += 1;
|
||||
this.$nextTick(() => {
|
||||
this.calendarReady = !this.calendarNoPermission;
|
||||
});
|
||||
} catch (e) {
|
||||
uni.$u.toast(e.message || e.errMsg || 'Load property room types failed');
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
async loadCalendarSetting() {
|
||||
try {
|
||||
const res = await requestCalendarSetting({});
|
||||
if (res && res.data) {
|
||||
this.applyCalendarSettings(res.data);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
applyCalendarSettings(settings) {
|
||||
const settingMap = settings.reduce((map, item) => {
|
||||
map[item.keys] = item.keyValues;
|
||||
return map;
|
||||
}, {});
|
||||
this.calendarPreviousDays = this.getNumberSetting(settingMap.CALENDAR_VIEW_PREVIOUS_DAYS, this.calendarPreviousDays);
|
||||
this.calendarVisibleDays = this.getNumberSetting(settingMap.CALENDAR_VIEW_VISIBLE_DAYS, this.calendarVisibleDays);
|
||||
this.calendarYesterdayStart = settingMap.CALENDAR_VIEW_YESTERDAY_START || this.calendarYesterdayStart;
|
||||
this.calendarYesterdayEnd = settingMap.CALENDAR_VIEW_YESTERDAY_END || this.calendarYesterdayEnd;
|
||||
this.maxSelectedRoomTypes = this.getPositiveIntegerSetting(settingMap.MAX_SELECTED_ROOM_TYPES, this.maxSelectedRoomTypes);
|
||||
},
|
||||
getNumberSetting(value, defaultValue) {
|
||||
if (value === undefined || value === null || value === '') return defaultValue;
|
||||
const numberValue = Number(value);
|
||||
return Number.isNaN(numberValue) ? defaultValue : numberValue;
|
||||
},
|
||||
getPositiveIntegerSetting(value, defaultValue) {
|
||||
const numberValue = this.getNumberSetting(value, defaultValue);
|
||||
return numberValue > 0 ? Math.floor(numberValue) : 0;
|
||||
},
|
||||
buildCalendar() {
|
||||
const effectiveToday = this.getEffectiveCalendarToday();
|
||||
const startDate = dayjs(effectiveToday).subtract(this.calendarPreviousDays, 'day').format('YYYY-MM-DD');
|
||||
const endDate = dayjs(effectiveToday).add(this.calendarVisibleDays + this.calendarPreviousDays, 'day').format('YYYY-MM-DD');
|
||||
this.calendarToday = effectiveToday;
|
||||
this.calendarStartDate = startDate;
|
||||
this.calendarEndDate = endDate;
|
||||
this.calendarMonths = buildCalendarDateRange({
|
||||
today: effectiveToday,
|
||||
startDate,
|
||||
endDate,
|
||||
weekdayLabels: this.weekdayLabels,
|
||||
});
|
||||
},
|
||||
getEffectiveCalendarToday() {
|
||||
const now = dayjs();
|
||||
if (this.isInYesterdayWindow(now)) {
|
||||
return now.subtract(1, 'day').format('YYYY-MM-DD');
|
||||
}
|
||||
return now.format('YYYY-MM-DD');
|
||||
},
|
||||
isInYesterdayWindow(now) {
|
||||
const startMinutes = this.getTimeMinutes(this.calendarYesterdayStart);
|
||||
const endMinutes = this.getTimeMinutes(this.calendarYesterdayEnd);
|
||||
if (startMinutes === null || endMinutes === null) return false;
|
||||
const currentMinutes = now.hour() * 60 + now.minute();
|
||||
if (startMinutes <= endMinutes) {
|
||||
return currentMinutes >= startMinutes && currentMinutes <= endMinutes;
|
||||
}
|
||||
return currentMinutes >= startMinutes || currentMinutes <= endMinutes;
|
||||
},
|
||||
getTimeMinutes(value) {
|
||||
if (!value) return null;
|
||||
const parts = String(value).split(':').map(Number);
|
||||
if (parts.length < 2 || Number.isNaN(parts[0]) || Number.isNaN(parts[1])) return null;
|
||||
return parts[0] * 60 + parts[1];
|
||||
},
|
||||
changePropertyTab(tab) {
|
||||
const property = this.propertyList[tab.index];
|
||||
if (!property) return;
|
||||
this.selectProperty(property.code);
|
||||
},
|
||||
selectProperty(code) {
|
||||
const isSameProperty = code === this.selectedPropertyCode;
|
||||
this.selectedPropertyCode = code;
|
||||
this.ensureSelectedOptionsForRefresh(isSameProperty);
|
||||
this.loadQualificationData();
|
||||
},
|
||||
selectDefaultOptions() {
|
||||
if (this.isOtherProperty) {
|
||||
this.selectedOtherPropertyCodes = this.getDefaultOtherPropertyCodes();
|
||||
} else {
|
||||
this.selectedRoomTypeCodes = this.getDefaultRoomTypeCodes();
|
||||
}
|
||||
},
|
||||
ensureSelectedOptionsForRefresh(isSameProperty = false) {
|
||||
if (this.isOtherProperty) {
|
||||
if (!isSameProperty) {
|
||||
this.selectedOtherPropertyCodes = this.getValidOtherPropertyCodes(this.selectedOtherPropertyCodes);
|
||||
}
|
||||
if (!this.selectedOtherPropertyCodes.length) {
|
||||
this.selectedOtherPropertyCodes = this.getDefaultOtherPropertyCodes();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!isSameProperty) {
|
||||
this.selectedRoomTypeCodes = this.getValidRoomTypeCodes(this.selectedRoomTypeCodes);
|
||||
}
|
||||
if (!this.selectedRoomTypeCodes.length) {
|
||||
this.selectedRoomTypeCodes = this.getDefaultRoomTypeCodes();
|
||||
}
|
||||
},
|
||||
getValidRoomTypeCodes(codes) {
|
||||
const validCodes = this.currentRoomTypes.map(item => this.getRoomTypeCode(item));
|
||||
return (codes || []).filter(code => validCodes.indexOf(code) !== -1);
|
||||
},
|
||||
getValidOtherPropertyCodes(codes) {
|
||||
const validCodes = this.currentOtherProperties.map(item => this.getPropertyCode(item));
|
||||
return (codes || []).filter(code => validCodes.indexOf(code) !== -1);
|
||||
},
|
||||
toggleSelectorOption(code) {
|
||||
if (this.isOtherProperty) {
|
||||
this.toggleOtherProperty(code);
|
||||
return;
|
||||
}
|
||||
this.toggleRoomType(code);
|
||||
},
|
||||
toggleRoomType(code) {
|
||||
const index = this.selectedRoomTypeCodes.indexOf(code);
|
||||
if (index === -1) {
|
||||
if (this.isMaxSelectedRoomTypesReached(this.selectedRoomTypeCodes.length)) {
|
||||
this.showMaxSelectedRoomTypesToast();
|
||||
return;
|
||||
}
|
||||
this.selectedRoomTypeCodes.push(code);
|
||||
this.loadQualificationData();
|
||||
return;
|
||||
}
|
||||
if (this.selectedRoomTypeCodes.length === 1) {
|
||||
uni.$u.toast('At least one room type is required');
|
||||
return;
|
||||
}
|
||||
this.selectedRoomTypeCodes.splice(index, 1);
|
||||
this.loadQualificationData();
|
||||
},
|
||||
toggleOtherProperty(code) {
|
||||
const index = this.selectedOtherPropertyCodes.indexOf(code);
|
||||
if (index === -1) {
|
||||
if (this.isMaxSelectedRoomTypesReached(this.selectedOtherPropertyCodes.length)) {
|
||||
this.showMaxSelectedRoomTypesToast();
|
||||
return;
|
||||
}
|
||||
this.selectedOtherPropertyCodes.push(code);
|
||||
this.loadQualificationData();
|
||||
return;
|
||||
}
|
||||
if (this.selectedOtherPropertyCodes.length === 1) {
|
||||
uni.$u.toast('At least one property is required');
|
||||
return;
|
||||
}
|
||||
this.selectedOtherPropertyCodes.splice(index, 1);
|
||||
this.loadQualificationData();
|
||||
},
|
||||
limitRoomTypeCodes(codes) {
|
||||
if (!this.maxSelectedRoomTypes) return codes;
|
||||
return codes.slice(0, this.maxSelectedRoomTypes);
|
||||
},
|
||||
getDefaultRoomTypeCodes() {
|
||||
const defaultRoomTypes = this.normalizeRoomTypeCodes(
|
||||
this.currentProperty.defaultRoomTypes || this.currentProperty.DefaultRoomTypes
|
||||
);
|
||||
const firstRoomTypeCode = this.getRoomTypeCode(this.currentRoomTypes[0]);
|
||||
const roomTypeCodes = defaultRoomTypes.length
|
||||
? defaultRoomTypes
|
||||
: (firstRoomTypeCode ? [firstRoomTypeCode] : []);
|
||||
return this.limitRoomTypeCodes(roomTypeCodes);
|
||||
},
|
||||
normalizeRoomTypeCodes(roomTypes) {
|
||||
if (!roomTypes) return [];
|
||||
if (Array.isArray(roomTypes)) {
|
||||
return roomTypes.reduce((list, item) => list.concat(this.normalizeRoomTypeCodes(item)), []);
|
||||
}
|
||||
if (typeof roomTypes === 'string') {
|
||||
return roomTypes
|
||||
.split(',')
|
||||
.map(code => code.trim())
|
||||
.filter(code => code);
|
||||
}
|
||||
const code = this.getRoomTypeCode(roomTypes);
|
||||
return code ? [code] : [];
|
||||
},
|
||||
getRoomTypeCode(roomType) {
|
||||
if (!roomType) return '';
|
||||
if (typeof roomType === 'string') return roomType;
|
||||
return roomType.code || roomType.Code || roomType.roomType || roomType.RoomType || roomType.roomTypeCode || roomType.RoomTypeCode || '';
|
||||
},
|
||||
isMaxSelectedRoomTypesReached(selectedCount) {
|
||||
return this.maxSelectedRoomTypes > 0 && selectedCount >= this.maxSelectedRoomTypes;
|
||||
},
|
||||
showMaxSelectedRoomTypesToast() {
|
||||
uni.$u.toast(this.$t("roomCalendar.maxSelectedRoomTypes", {
|
||||
count: this.maxSelectedRoomTypes,
|
||||
}));
|
||||
},
|
||||
refreshCalendar() {
|
||||
if (!this.canLoadPlayerCalendar()) return;
|
||||
this.ensureSelectedOptionsForRefresh(true);
|
||||
this.loadQualificationData();
|
||||
},
|
||||
async loadQualificationData() {
|
||||
if (!this.canLoadPlayerCalendar()) return;
|
||||
const records = [];
|
||||
const dateRange = this.getCalendarDateRange();
|
||||
const requestId = this.startCalendarRequest();
|
||||
this.hideCalendarForLoading();
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading"),
|
||||
});
|
||||
const params = this.buildQualificationParams(dateRange);
|
||||
if (!params.RoomType) {
|
||||
this.qualificationMap = {};
|
||||
return;
|
||||
}
|
||||
console.log('[PlayerRoomCalendar] request Property:', params.Property, 'RoomType:', params.RoomType);
|
||||
const res = await getPlayerRoomQualification(params, this.getCalendarRequestConfig(requestId));
|
||||
if (!this.isLatestCalendarRequest(requestId)) return;
|
||||
if (this.isNoPermissionResponse(res)) {
|
||||
this.showCalendarNoPermission();
|
||||
return;
|
||||
}
|
||||
if (res.success !== true) {
|
||||
throw new Error(res.message || 'Load room calendar failed');
|
||||
}
|
||||
if (this.isOtherProperty) {
|
||||
records.push(...this.buildOtherPropertyRecords(res.data || []));
|
||||
} else {
|
||||
records.push(...(res.data || []));
|
||||
}
|
||||
this.qualificationMap = mapRoomCalendarQualificationRecords(records);
|
||||
} catch (e) {
|
||||
if (!this.isLatestCalendarRequest(requestId) || this.isRequestAbortError(e)) return;
|
||||
this.qualificationMap = {};
|
||||
uni.$u.toast(e.message || e.errMsg || 'Load room calendar failed');
|
||||
} finally {
|
||||
if (this.isLatestCalendarRequest(requestId)) {
|
||||
this.calendarRequestTask = null;
|
||||
uni.hideLoading();
|
||||
this.showCalendarAfterLoading(requestId);
|
||||
}
|
||||
}
|
||||
},
|
||||
hideCalendarForLoading() {
|
||||
this.calendarReady = false;
|
||||
this.calendarNoPermission = false;
|
||||
},
|
||||
showCalendarAfterLoading(requestId) {
|
||||
this.$nextTick(() => {
|
||||
if (this.isLatestCalendarRequest(requestId) && !this.calendarNoPermission) {
|
||||
this.calendarReady = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
isNoPermissionResponse(res) {
|
||||
return res && res.success === false && (res.errorCode || res.code) === 'NO_PERMISSION';
|
||||
},
|
||||
canLoadPlayerCalendar() {
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
if (!this.userData || this.userData.canViewCalendar !== true) {
|
||||
this.showCalendarNoPermission();
|
||||
return false;
|
||||
}
|
||||
if (!this.safePlayerData.playerId) {
|
||||
this.calendarReady = false;
|
||||
uni.$u.toast(this.$t("common.dataNotFound"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
showCalendarNoPermission() {
|
||||
this.qualificationMap = {};
|
||||
this.calendarReady = false;
|
||||
this.calendarNoPermission = true;
|
||||
},
|
||||
startCalendarRequest() {
|
||||
this.calendarRequestId += 1;
|
||||
this.abortCalendarRequest();
|
||||
this.calendarRequestTask = null;
|
||||
return this.calendarRequestId;
|
||||
},
|
||||
abortCalendarRequest() {
|
||||
if (this.calendarRequestTask && typeof this.calendarRequestTask.abort === 'function') {
|
||||
this.calendarRequestTask.abort();
|
||||
}
|
||||
this.calendarRequestTask = null;
|
||||
},
|
||||
getCalendarRequestConfig(requestId) {
|
||||
return {
|
||||
getTask: task => {
|
||||
if (this.isLatestCalendarRequest(requestId)) {
|
||||
this.calendarRequestTask = task;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
isLatestCalendarRequest(requestId) {
|
||||
return requestId === this.calendarRequestId;
|
||||
},
|
||||
isRequestAbortError(error) {
|
||||
const errMsg = error && error.errMsg ? String(error.errMsg) : '';
|
||||
return errMsg.indexOf('abort') !== -1;
|
||||
},
|
||||
buildQualificationParams(dateRange) {
|
||||
const allProperty = this.isOtherProperty
|
||||
? this.selectedOtherPropertyCodes.join(',')
|
||||
: this.selectedPropertyCode;
|
||||
const allRoomType = this.getUniqueCodes(this.selectedRoomTypes.map(roomType => {
|
||||
return roomType.requestRoomTypeCode || roomType.parentCode || roomType.code;
|
||||
})).join(',');
|
||||
return {
|
||||
PlayerId: this.safePlayerData.playerId,
|
||||
Property: allProperty,
|
||||
RoomType: allRoomType,
|
||||
StartDate: dateRange.startDate,
|
||||
EndDate: dateRange.endDate,
|
||||
};
|
||||
},
|
||||
getUniqueCodes(codes) {
|
||||
return [...new Set(codes.filter(code => code))];
|
||||
},
|
||||
getOtherPropertyRoomTypeCode(propertyCode, roomTypeCode) {
|
||||
return `${propertyCode}_${roomTypeCode}`;
|
||||
},
|
||||
getDefaultOtherPropertyCodes() {
|
||||
const defaultPropertySource =
|
||||
this.currentProperty.defaultProperty ||
|
||||
this.currentProperty.DefaultProperty ||
|
||||
this.currentProperty.defaultProperties ||
|
||||
this.currentProperty.DefaultProperties ||
|
||||
this.currentProperty.defaultOtherProperty ||
|
||||
this.currentProperty.DefaultOtherProperty ||
|
||||
this.currentProperty.defaultOtherProperties ||
|
||||
this.currentProperty.DefaultOtherProperties ||
|
||||
this.currentProperty.defaultPropertyList ||
|
||||
this.currentProperty.DefaultPropertyList ||
|
||||
this.currentProperty.defaultPropertyCodes ||
|
||||
this.currentProperty.DefaultPropertyCodes ||
|
||||
this.currentProperty.defaultRoomTypes;
|
||||
const defaultProperties = this.normalizeDefaultProperties(defaultPropertySource);
|
||||
const defaultCodes = defaultProperties
|
||||
.map(item => this.getPropertyCode(item))
|
||||
.filter(code => this.currentOtherProperties.some(property => property.code === code));
|
||||
const uniqueDefaultCodes = [...new Set(defaultCodes)];
|
||||
if (uniqueDefaultCodes.length) {
|
||||
return this.limitRoomTypeCodes(uniqueDefaultCodes);
|
||||
}
|
||||
const propertiesWithDefaultRoomTypes = [...new Set(this.currentOtherProperties
|
||||
.filter(property => (property.defaultRoomTypes || property.DefaultRoomTypes || []).length)
|
||||
.map(property => property.code))];
|
||||
if (propertiesWithDefaultRoomTypes.length) {
|
||||
return this.limitRoomTypeCodes(propertiesWithDefaultRoomTypes);
|
||||
}
|
||||
const firstOtherPropertyCode = this.getPropertyCode(this.currentOtherProperties[0]);
|
||||
return firstOtherPropertyCode ? [firstOtherPropertyCode] : [];
|
||||
},
|
||||
normalizeDefaultProperties(defaultProperties) {
|
||||
if (!defaultProperties) return [];
|
||||
if (Array.isArray(defaultProperties)) {
|
||||
return defaultProperties.reduce((list, item) => list.concat(this.normalizeDefaultProperties(item)), []);
|
||||
}
|
||||
if (typeof defaultProperties === 'string') {
|
||||
return defaultProperties
|
||||
.split(',')
|
||||
.map(code => code.trim())
|
||||
.filter(code => code);
|
||||
}
|
||||
return [defaultProperties];
|
||||
},
|
||||
getPropertyCode(property) {
|
||||
if (typeof property === 'string') return property;
|
||||
return property.code || property.Code || property.propertyCode || property.PropertyCode || property.Property || property.property || '';
|
||||
},
|
||||
getRecordRoomType(record) {
|
||||
return record.roomType !== undefined ? record.roomType : record.RoomType;
|
||||
},
|
||||
getRecordProperty(record) {
|
||||
return record.property !== undefined
|
||||
? record.property
|
||||
: record.Property || record.propertyCode || record.PropertyCode || '';
|
||||
},
|
||||
buildOtherPropertyRecords(records) {
|
||||
return records.reduce((list, record) => {
|
||||
this.getOtherPropertyRecordRoomTypeCodes(record).forEach(roomTypeCode => {
|
||||
list.push({
|
||||
...record,
|
||||
roomType: roomTypeCode,
|
||||
RoomType: roomTypeCode,
|
||||
});
|
||||
});
|
||||
return list;
|
||||
}, []);
|
||||
},
|
||||
getOtherPropertyRecordRoomTypeCodes(record) {
|
||||
const recordRoomType = this.getRecordRoomType(record);
|
||||
if (!recordRoomType) return [];
|
||||
if (this.selectedRoomTypes.some(roomType => roomType.code === recordRoomType)) {
|
||||
return [recordRoomType];
|
||||
}
|
||||
const recordPropertyCode = this.getSelectedOtherPropertyCode(this.getRecordProperty(record));
|
||||
if (recordPropertyCode) {
|
||||
return [this.getOtherPropertyRoomTypeCode(recordPropertyCode, recordRoomType)];
|
||||
}
|
||||
const matchedRoomTypes = this.selectedRoomTypes.filter(roomType => roomType.requestRoomTypeCode === recordRoomType);
|
||||
return matchedRoomTypes.length ? matchedRoomTypes.map(roomType => roomType.code) : [recordRoomType];
|
||||
},
|
||||
getSelectedOtherPropertyCode(propertyValue) {
|
||||
const normalizedValue = this.normalizeText(propertyValue);
|
||||
if (!normalizedValue) return '';
|
||||
const property = this.selectedOtherProperties.find(item => {
|
||||
return this.getOtherPropertyAliases(item).some(value => this.normalizeText(value) === normalizedValue);
|
||||
});
|
||||
return property ? property.code : '';
|
||||
},
|
||||
getOtherPropertyAliases(property) {
|
||||
const aliases = [
|
||||
property.code,
|
||||
property.name,
|
||||
property.displayName,
|
||||
property.propertyName,
|
||||
property.hotelName,
|
||||
];
|
||||
if (property.code === 'MO') {
|
||||
aliases.push('MGM Macau', 'Macau', 'MOGR');
|
||||
}
|
||||
return aliases;
|
||||
},
|
||||
normalizeText(value) {
|
||||
return String(value || '').trim().toUpperCase();
|
||||
},
|
||||
getCalendarDateRange() {
|
||||
const dates = [];
|
||||
this.calendarMonths.forEach(month => {
|
||||
month.weeks.forEach(week => {
|
||||
week.days.forEach(day => {
|
||||
if (!day.isOutsideMonth) {
|
||||
dates.push(day.date);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
return {
|
||||
startDate: dates[0],
|
||||
endDate: dates[dates.length - 1],
|
||||
};
|
||||
},
|
||||
getDefaultPropertyCode() {
|
||||
const userText = JSON.stringify(this.userData || {}).toUpperCase();
|
||||
const property = this.propertyList.find(item => {
|
||||
const name = String(item.name || '').toUpperCase();
|
||||
return userText.indexOf(name) !== -1 || (item.code === 'OTHER' && userText.indexOf('OTHER') !== -1);
|
||||
});
|
||||
return (property || this.propertyList[0]).code;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.player-room-calendar-page {
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.player-summary {
|
||||
background-color: #c39a4b;
|
||||
border-radius: 24rpx;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
margin: 16rpx 16rpx 12rpx;
|
||||
padding: 26rpx 28rpx;
|
||||
}
|
||||
|
||||
.summary-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.summary-name-row {
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
|
||||
.summary-item {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.summary-player {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.summary-tier {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
color: #fff8e8;
|
||||
font-family: "Inter-Bold";
|
||||
font-size: 26rpx;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
|
||||
.summary-value {
|
||||
color: #ffffff;
|
||||
font-family: "Inter-Bold";
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
line-height: 42rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.calendar-panel {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding: 2rpx 8rpx 0;
|
||||
}
|
||||
|
||||
.property-tabs {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
padding: 4rpx 0 2rpx;
|
||||
}
|
||||
|
||||
.room-type-grid {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
padding: 6rpx 0 2rpx;
|
||||
}
|
||||
|
||||
.room-type-btn {
|
||||
background-color: #ffffff;
|
||||
border: 1rpx solid #d8d8d8;
|
||||
border-radius: 8rpx;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.12);
|
||||
color: #111111;
|
||||
font-family: "Inter-Bold";
|
||||
font-size: 28rpx;
|
||||
height: 58rpx;
|
||||
line-height: 58rpx;
|
||||
margin: 5rpx 6rpx;
|
||||
text-align: center;
|
||||
width: calc(16.6666% - 12rpx);
|
||||
}
|
||||
|
||||
.room-type-btn.active {
|
||||
background-color: #c39a4b;
|
||||
border-color: #c39a4b;
|
||||
box-shadow: none;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.calendar-refresh-btn {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 88rpx;
|
||||
justify-content: center;
|
||||
margin-right: 5rpx;
|
||||
width: 64rpx;
|
||||
}
|
||||
|
||||
.calendar-empty-state {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.calendar-empty-image-row {
|
||||
justify-content: center;
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
.calendar-empty-image {
|
||||
height: 160px;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.calendar-empty-text {
|
||||
justify-content: center;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -139,10 +139,10 @@
|
||||
<!-- <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 v-if="bookingData.miscCharge!=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 class="hz-font-bolder hz-font-lg">{{ bookingData.miscCharge || "-" }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -254,19 +254,18 @@
|
||||
<!-- 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]"
|
||||
<u-checkbox-group placement="row"
|
||||
:value="unqualifiedDateCheckboxStates[currentUnqualifiedIndex] || []"
|
||||
@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>
|
||||
customStyle="height:30px;width:100%;" label="Extend" name="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>
|
||||
customStyle="height:30px;width:100%;" label="Remark" name="Remark"></u-checkbox>
|
||||
</view>
|
||||
</u-checkbox-group>
|
||||
<view style="width:100%;margin-top:16px;" v-show="showRemark">
|
||||
@@ -329,41 +328,32 @@
|
||||
<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"
|
||||
<!-- uView:u-checkbox 必须在 u-checkbox-group 内;房型互斥用 group + 受控 :value -->
|
||||
<u-checkbox-group placement="row"
|
||||
:value="waitlistRoomGroupValue"
|
||||
@change="onWaitlistRoomRemarkGroupChange"
|
||||
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"
|
||||
<u-checkbox-group placement="row"
|
||||
:value="waitlistOtherRemarkCheckList"
|
||||
@change="changeWaitlistOtherRemark"
|
||||
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>
|
||||
customStyle="height:30px;width:100%;" label="Extend" name="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>
|
||||
customStyle="height:30px;width:100%;" label="Remark" name="Remark"></u-checkbox>
|
||||
</view>
|
||||
</u-checkbox-group>
|
||||
<view style="width:100%;margin-top:16px;" v-show="showRemark">
|
||||
@@ -437,7 +427,8 @@
|
||||
selectedApprover:'',
|
||||
showRemark: false,
|
||||
showWaitlistModal:false,
|
||||
showRadio:false,
|
||||
// Waitlist 弹窗 Extend/Remark(必须与 u-checkbox-group 的 :value 绑定,勿用子项 :value)
|
||||
waitlistOtherRemarkCheckList: [],
|
||||
unqualifiedDateList: [],
|
||||
currentUnqualifiedIndex: 0,
|
||||
unqualifiedDateRemarks: [],
|
||||
@@ -463,6 +454,17 @@
|
||||
// 數據方法
|
||||
getBooking(){
|
||||
this.bookingData = uni.getStorageSync("bookingData");
|
||||
// 确保 roomRemark 是响应式字段,否则 iOS 上可能出现 u-checkbox 状态未被正确回刷导致“可多选”
|
||||
if (this.bookingData !== null && this.bookingData !== undefined && typeof this.bookingData === 'object') {
|
||||
const hasRoomRemark = Object.prototype.hasOwnProperty.call(this.bookingData, 'roomRemark');
|
||||
if (!hasRoomRemark || this.bookingData.roomRemark === null || this.bookingData.roomRemark === undefined || this.bookingData.roomRemark === 'null') {
|
||||
(this.$set ? this.$set(this.bookingData, 'roomRemark', '') : this.bookingData.roomRemark = '');
|
||||
}
|
||||
const hasOtherRemark = Object.prototype.hasOwnProperty.call(this.bookingData, 'otherRemark');
|
||||
if (!hasOtherRemark || this.bookingData.otherRemark === null || this.bookingData.otherRemark === undefined || this.bookingData.otherRemark === 'null') {
|
||||
(this.$set ? this.$set(this.bookingData, 'otherRemark', '') : this.bookingData.otherRemark = '');
|
||||
}
|
||||
}
|
||||
if(this.bookingData!==null && this.bookingData!==undefined && this.bookingData!==''){
|
||||
this.oldDateList = this.bookingData.dateList;
|
||||
this.checkList = [];
|
||||
@@ -498,11 +500,7 @@
|
||||
this.submitBooking();
|
||||
}
|
||||
},
|
||||
submitApproval() {
|
||||
// 显示审批模态框
|
||||
this.getApprovalReason();
|
||||
this.showApprovalModal = true;
|
||||
this.showModalBtn = true;
|
||||
buildUnqualifiedDateLists() {
|
||||
this.currentUnqualifiedIndex = 0;
|
||||
this.unqualifiedDateList = [];
|
||||
this.unqualifiedDateRemarks = [];
|
||||
@@ -510,33 +508,27 @@
|
||||
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]);
|
||||
if (this.checkList != null && this.checkList.length > 0) {
|
||||
if (this.bookingData.bookType == 1) {
|
||||
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) {
|
||||
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]);
|
||||
} else {
|
||||
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) {
|
||||
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([]);
|
||||
@@ -544,10 +536,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
submitApproval() {
|
||||
// 与 Waitlist 共用:必须先填充 unqualifiedDateList,否则 getWaitlistRemark 无法匹配 Extend
|
||||
this.buildUnqualifiedDateLists();
|
||||
// 显示审批模态框
|
||||
this.getApprovalReason();
|
||||
this.showApprovalModal = true;
|
||||
this.showModalBtn = true;
|
||||
},
|
||||
onApprovalChange(value){
|
||||
this.selectedApprover = value;
|
||||
// 多选:value 为数组,需要拼接 approverName
|
||||
@@ -1103,7 +1101,7 @@
|
||||
if (this.bookingData.extendDate[i].status == 1) {
|
||||
|
||||
// remarkText只保存remark输入的内容,不加Extend前缀
|
||||
this.bookingData.extendData[i].remarkText = this.unqualifiedDateRemarks[unqualifiedIndex] || '';
|
||||
this.bookingData.extendDate[i].remarkText = this.unqualifiedDateRemarks[unqualifiedIndex] || '';
|
||||
|
||||
// 添加approvalReason字段
|
||||
this.bookingData.extendDate[i].approvalReason = this.unqualifiedDateReasons[unqualifiedIndex] || null;
|
||||
@@ -1434,40 +1432,64 @@
|
||||
},
|
||||
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);
|
||||
let unqualifiedIndex = this.unqualifiedDateList.findIndex(uItem => uItem === item);
|
||||
if (unqualifiedIndex === -1 && item.date && item.date.length) {
|
||||
unqualifiedIndex = this.unqualifiedDateList.findIndex((uItem) => {
|
||||
const ud = uItem.date;
|
||||
const id = item.date;
|
||||
return ud && id && ud.length && id.length &&
|
||||
ud[0] === id[0] && ud[ud.length - 1] === id[id.length - 1];
|
||||
});
|
||||
}
|
||||
// 仅一条 Waitlist/Unqualified 时,引用不一致也会导致 findIndex 失败,直接对齐下标 0
|
||||
if (unqualifiedIndex === -1 && this.unqualifiedDateList.length === 1) {
|
||||
unqualifiedIndex = 0;
|
||||
}
|
||||
const checkboxState = unqualifiedIndex !== -1
|
||||
? (this.unqualifiedDateCheckboxStates[unqualifiedIndex] || [])
|
||||
: [];
|
||||
const otherSlot = unqualifiedIndex !== -1
|
||||
? (this.unqualifiedDateOtherRemarks[unqualifiedIndex] || '')
|
||||
: '';
|
||||
const wlTags = this.waitlistOtherRemarkCheckList || [];
|
||||
const globalOther = (this.bookingData && this.bookingData.otherRemark) ? String(this.bookingData.otherRemark) : '';
|
||||
const parseTags = (s) => String(s).split(';').map((x) => x.trim()).filter(Boolean);
|
||||
const hasExtend = checkboxState.includes('Extend') ||
|
||||
parseTags(otherSlot).includes('Extend') ||
|
||||
wlTags.includes('Extend') ||
|
||||
parseTags(globalOther).includes('Extend');
|
||||
|
||||
// 找到对应的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';
|
||||
}
|
||||
const roomRemark = this.bookingData.roomRemark;
|
||||
const idxRemark = unqualifiedIndex !== -1 ? this.unqualifiedDateRemarks[unqualifiedIndex] : '';
|
||||
const manualRemark = (idxRemark != null && idxRemark !== '') ? idxRemark : this.freeRemark;
|
||||
const remarkChecked = unqualifiedIndex !== -1 &&
|
||||
(this.unqualifiedDateCheckboxStates[unqualifiedIndex] || []).includes('Remark');
|
||||
|
||||
if (unqualifiedIndex !== -1 && this.unqualifiedDateOtherRemarks[unqualifiedIndex] != null) {
|
||||
this.bookingData.otherRemark = this.unqualifiedDateOtherRemarks[unqualifiedIndex];
|
||||
}
|
||||
|
||||
// 对应 BookingDate 的 remark:勾选 Extend 时放在字符串首位
|
||||
const dateParts = [];
|
||||
if (hasExtend) {
|
||||
dateParts.push('Extend');
|
||||
}
|
||||
if (roomRemark != null && roomRemark !== '' && roomRemark !== undefined) {
|
||||
dateParts.push(roomRemark);
|
||||
}
|
||||
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);
|
||||
item.remarkText != null && item.remarkText !== '' && item.remarkText !== undefined) {
|
||||
dateParts.push(item.remarkText);
|
||||
}
|
||||
if ((remarkChecked || this.showRemark) && manualRemark !== '' && manualRemark != null && item.status == 1) {
|
||||
if (manualRemark !== item.remarkText) dateParts.push(manualRemark);
|
||||
}
|
||||
|
||||
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{
|
||||
const dateRemarkJoin = dateParts.join('; ');
|
||||
if (dateRemarkJoin) {
|
||||
this.bookingData.remark = dateRemarkJoin;
|
||||
item.remark = dateRemarkJoin;
|
||||
} else {
|
||||
this.bookingData.remark = "";
|
||||
item.remark = "";
|
||||
}
|
||||
@@ -1563,6 +1585,10 @@
|
||||
},
|
||||
|
||||
showWaitlistPop() {
|
||||
// 关键:直接点「放入 Waitlist」不会经过 submitApproval,必须在此处填充 unqualifiedDateList,
|
||||
// 否则 getWaitlistRemark 里 findIndex 恒为 -1,Extend 永远不会写入 remark
|
||||
this.buildUnqualifiedDateLists();
|
||||
this.waitlistOtherRemarkCheckList = (this.unqualifiedDateCheckboxStates[0] || []).slice();
|
||||
this.showWaitlistModal = true;
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
@@ -1606,17 +1632,27 @@
|
||||
}
|
||||
});
|
||||
},
|
||||
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
|
||||
}
|
||||
onWaitlistRoomRemarkGroupChange(e) {
|
||||
const raw = Array.isArray(e) ? e : (e && Array.isArray(e.detail) ? e.detail : []);
|
||||
const names = raw.map((x) => (x != null ? String(x) : '')).filter(Boolean);
|
||||
if (!this.bookingData) {
|
||||
return;
|
||||
}
|
||||
this.$forceUpdate()
|
||||
if (!Object.prototype.hasOwnProperty.call(this.bookingData, 'roomRemark')) {
|
||||
this.$set(this.bookingData, 'roomRemark', '');
|
||||
}
|
||||
if (names.length === 0) {
|
||||
this.bookingData.roomRemark = '';
|
||||
return;
|
||||
}
|
||||
if (names.length === 1) {
|
||||
this.bookingData.roomRemark = names[0];
|
||||
return;
|
||||
}
|
||||
// 双选时视为互斥:保留本次切换目标(与原先不同的那一项)
|
||||
const prev = this.bookingData.roomRemark;
|
||||
const next = names.find((n) => n !== prev) || names[names.length - 1];
|
||||
this.bookingData.roomRemark = next;
|
||||
},
|
||||
// changeOtherRemark(e,item) {
|
||||
// if (e) {
|
||||
@@ -1635,27 +1671,41 @@
|
||||
// this.$forceUpdate()
|
||||
// }
|
||||
// },
|
||||
changeWaitlistOtherRemark(e) {
|
||||
const raw = Array.isArray(e) ? e : (e && Array.isArray(e.detail) ? e.detail : []);
|
||||
const names = raw.map((x) => (x != null ? String(x) : '')).filter(Boolean);
|
||||
this.waitlistOtherRemarkCheckList = names.slice();
|
||||
const extras = names.filter((n) => n !== 'Remark');
|
||||
const str = extras.join('; ');
|
||||
this.showRemark = names.includes('Remark');
|
||||
const n = this.unqualifiedDateCheckboxStates.length;
|
||||
for (let i = 0; i < n; i++) {
|
||||
this.$set(this.unqualifiedDateCheckboxStates, i, names.slice());
|
||||
this.$set(this.unqualifiedDateOtherRemarks, i, str);
|
||||
}
|
||||
if (this.bookingData) {
|
||||
this.bookingData.otherRemark = str;
|
||||
}
|
||||
},
|
||||
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 {
|
||||
const raw = Array.isArray(e) ? e : (e && Array.isArray(e.detail) ? e.detail : []);
|
||||
const idx = this.currentUnqualifiedIndex;
|
||||
if (!raw || raw.length === 0) {
|
||||
this.showRemark = false;
|
||||
this.unqualifiedDateOtherRemarks[this.currentUnqualifiedIndex] = '';
|
||||
this.unqualifiedDateCheckboxStates[this.currentUnqualifiedIndex] = [];
|
||||
this.$set(this.unqualifiedDateOtherRemarks, idx, '');
|
||||
this.$set(this.unqualifiedDateCheckboxStates, idx, []);
|
||||
if (this.bookingData) {
|
||||
this.bookingData.otherRemark = '';
|
||||
}
|
||||
return;
|
||||
}
|
||||
const names = raw.map((x) => (x != null ? String(x) : '')).filter(Boolean);
|
||||
const extras = names.filter((n) => n !== 'Remark');
|
||||
this.showRemark = names.includes('Remark');
|
||||
this.$set(this.unqualifiedDateCheckboxStates, idx, names.slice());
|
||||
this.$set(this.unqualifiedDateOtherRemarks, idx, extras.join('; '));
|
||||
if (this.bookingData) {
|
||||
this.bookingData.otherRemark = extras.join('; ');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1671,6 +1721,16 @@
|
||||
},
|
||||
},
|
||||
computed:{
|
||||
waitlistRoomGroupValue() {
|
||||
if (!this.bookingData || !this.bookingData.roomRemark) {
|
||||
return [];
|
||||
}
|
||||
const r = this.bookingData.roomRemark;
|
||||
if (r === '2nd Room' || r === '3rd Room') {
|
||||
return [r];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
getStatusColor(){
|
||||
return function (booking) {
|
||||
let operaStatus = null;
|
||||
@@ -1991,4 +2051,4 @@
|
||||
color: #C39A4B;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user