Files
2026-09-29 21:51:58 +08:00

1705 lines
58 KiB
Vue
Raw Permalink 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>
<!-- #ifdef APP-PLUS -->
<simple-watermark ref="watermark"></simple-watermark>
<!-- #endif -->
<view>
<view class="hz-page">
<view class="u-navbar" :show="showNavbar" :style="{ opacity: navbarOpacity }">
<view class="u-navbar__placeholder" :style="{
height: navbarHeight+'px',
backgroundColor: bgColor,
}"></view>
<view :class="[true && 'u-navbar--fixed']">
<u-status-bar :bgColor="bgColor"></u-status-bar>
<view class="u-navbar__content" :style="{
height: navbarHeight,
backgroundColor: bgColor,
}">
<view class="u-navbar__content__left">
<slot name="left">
<u-icon
size="28px" v-if="showTrashIcon()" @click="setCalendar()" name="../../static/images/filter-clear.svg"
></u-icon>
</slot>
</view>
<slot name="center">
<text class="u-line-1 u-navbar__content__title">{{ $t('todo.title') }}</text>
</slot>
<view class="u-navbar__content__right">
<slot name="right">
<p-checkbox :isOpen="isOpen" @toggle="switchFilterType"></p-checkbox>
</slot>
</view>
</view>
<view class="hz-flex-row" style="height:30px;line-height:44px;" :style="{
backgroundColor: bgColor,
}">
<view class="hz-flex-row" style="justify-content: center;align-items: center;" :style="{width: currentIndex==2 || currentIndex==3? '100%':'90%'}">
<view class="tabs-container">
<view class="tabs-row">
<view v-for="(tab, index) in tabs" :key="index" class="tab"
:class="{active: currentIndex === index}" :data-index="index"
@tap="switchTab(index)" :id="'tab'+index">
<view @click="handlerGetToDoList(index)">{{tab.name}}</view>
</view>
</view>
<view class="slider-container" id="slider-container">
<view class="slider" :style="{
left: sliderPosition + 'px',
backgroundColor: tabs[currentIndex].color
}"></view>
</view>
</view>
</view>
<view v-if="currentIndex==2 || currentIndex==3? false:true" @click="openCalendar()" class="hz-flex-row" style="width:10%;justify-content: center;align-items: center;">
<u-icon name="calendar" :size="30" :color="calendarIconColor"></u-icon>
</view>
</view>
</view>
</view>
<!--content begin-->
<view v-if="showTodoListView" class="hz-spacing" style="position: relative;top:44px;">
<view v-if="currentIndex !== 3" v-for="(record,index) in listData"
:key="'record'+index" style="margin-bottom:8px;">
<view class="hz-date-title">{{record.date}}</view>
<uni-swipe-action v-for="(rowRecord,index) in record.dateRecords" :key="'row'+index"
:style="{marginTop: index==0? '6px':'0px'}">
<uni-swipe-action-item ref="swipeAction" :show="rowRecord.itemOpen" :autoClose="false" @change="changeTest(rowRecord,1,$event)">
<uni-card @click="fetchTodoDetail(rowRecord)"
style="margin-left:4rpx;margin-right:4rpx;margin-top:4px;margin-bottom:4px;padding:12px;position:relative;">
<!-- ETA标签 -->
<!-- <view class="conner-label conner-label-eta"> -->
<view v-show="showETA(rowRecord)"
class="conner-label" :style="{ backgroundColor: getETAColor(rowRecord) }">
<view class="conner-label-text" :style="{color: getTextColor(rowRecord)}">{{getETALable(rowRecord)}}</view>
</view>
<u-row>
<u-col span="11">
<view class="hz-font-color-dark hz-font-md text-truncate">
<template v-if="rowRecord.playerId">{{ rowRecord.playerId }}</template>
<template v-if="rowRecord.englishName"><span style="color: gray;">/</span>{{ rowRecord.englishName }}
</template>
<template v-if="rowRecord.tierName"><span style="color: gray;">/</span>({{ rowRecord.tierName }})
</template>
<span v-if="rowRecord.hasArrivalRecord == 1" class="dot-arrival"></span>
<span v-if="rowRecord.hasDepartureRecord == 1" class="dot-departure"></span>
<span v-if="rowRecord.hasInhouseRecord == 1" class="dot-inhouse"></span>
<span v-if="rowRecord.hasOthersRecord == 1" class="dot-other"></span>
</view>
</u-col>
<u-col span="1" align="flex-end" justify="flex-end" textAlign="right">
<u-icon :name="rowRecord.arrowName"
v-if="!rowRecord.showDetailLoading"></u-icon>
<u-loading-icon mode="circle" :size="18"
v-if="rowRecord.showDetailLoading"></u-loading-icon>
</u-col>
</u-row>
<view class="hz-flex-row" style="align-items: flex-start;">
<view class="text-container" v-if="!rowRecord.showDetail">
<span v-for="(itemRecord,index) in rowRecord.descriptions" :key="'item'+index"
class="hz-date-des todo-summary-description"
style="display:block;">
<template v-for="(part, partIndex) in getDescriptionWithSharerIconParts(itemRecord)">
<image v-if="part.type === 'sharerIcon'" :key="'item-sharer-'+index+'-'+partIndex"
src="../../static/images/sharer_line.svg"
class="icon-img-sharer todo-description-sharer-icon">
</image>
<span v-else :key="'item-text-'+index+'-'+partIndex">{{part.text}}</span>
</template>
<image
v-show="index == 0 && currentIndex !== 2 && rowRecord.hasFlightRecord ===1"
src="../../static/images/flight_line.svg" class="icon-img-flight">
</image>
<image
v-show="index == 0 && currentIndex !== 2 && rowRecord.hasLimoRecord ===1"
src="../../static/images/limo_line.svg" class="icon-img-limo"></image>
<image
v-show="index == 0 && currentIndex !== 2 && rowRecord.hasLimoRecord =='-1'"
src="../../static/images/limo_warn.png" class="icon-img-limo"></image>
</span>
</view>
<!-- 直接使用v-if配合CSS动画类 -->
<view v-if="rowRecord.showDetail" class="detail-content"
:class="{'detail-show': rowRecord.showDetail, 'detail-ide': !rowRecord.showDetail}"
style="width:100%;">
<view>Location: {{rowRecord.detailData.location}}</view>
<view v-show="filterType==='IM'">Active Prg Id: {{rowRecord.detailData.activePrgId}}</view>
<u-row customStyle="margin-top:10px;" v-show="filterType=='MASS'">
<u-col
v-show="(currentIndex === 1 || currentIndex === 2)"
span="6">
<view class="hz-font-12px">Today TPD : {{formatNumber(rowRecord.detailData.todayTPD)}}
</view>
<view class="hz-font-12px">Today Win : {{formatNumber(rowRecord.detailData.todayWin)}}
</view>
<view v-show="currentIndex === 2 && filterType ==='MASS'" class="hz-font-12px">Today Theo : {{formatNumber(rowRecord.detailData.todayTheo)}}
</view>
</u-col>
<u-col v-show="currentIndex === 2" span="6">
<view class="hz-font-12px">Trip TPD: {{formatNumber(rowRecord.detailData.tripTPD)}}</view>
<view class="hz-font-12px">Trip Win: {{formatNumber(rowRecord.detailData.tripWin)}}</view>
<view class="hz-font-12px">Trip RI: {{getPercentFormat(rowRecord.detailData.tripRIPercentage)}}
</view>
<view v-show="currentIndex === 2 && filterType ==='MASS'" class="hz-font-12px">Trip Theo : {{formatNumber(rowRecord.detailData.tripTheo)}}
</view>
</u-col>
</u-row>
<u-row v-show="filterType==='IM'&&currentIndex===0" customStyle="margin-top:10px;">
<u-col span="6">
<view class="hz-font-12px">Prg T/O : {{formatNumber(rowRecord.detailData.prgTO)}}
</view>
<view class="hz-font-12px">Prg Win : {{formatNumber(rowRecord.detailData.prgWin)}}
</view>
</u-col>
<u-col span="6">
<view class="hz-font-12px">Front Money: {{formatNumber(rowRecord.detailData.frontMoney)}}</view>
<view class="hz-font-12px">TTO: {{formatNumber(rowRecord.detailData.tto)}}</view>
<view class="hz-font-12px">0.1Comp Balance: {{formatNumber(rowRecord.detailData.comBalance)}}
</view>
</u-col>
</u-row>
<u-row v-show="filterType==='IM'&&currentIndex===1" customStyle="margin-top:10px;">
<u-col span="6">
<view class="hz-font-12px">Prg T/O : {{formatNumber(rowRecord.detailData.prgTO)}}
</view>
<view class="hz-font-12px">Prg Win : {{formatNumber(rowRecord.detailData.prgWin)}}
</view>
<view class="hz-font-12px">Exp comm : {{formatNumber(rowRecord.detailData.expComm)}}
</view>
<view class="hz-font-12px">Unsettled Expenses : {{formatNumber(rowRecord.detailData.unsettledExpenses)}}
</view>
</u-col>
<u-col span="6">
<view class="hz-font-12px">Front Money: {{formatNumber(rowRecord.detailData.frontMoney)}}</view>
<view class="hz-font-12px">TTO: {{formatNumber(rowRecord.detailData.tto)}}</view>
<view class="hz-font-12px">0.1Comp Balance: {{formatNumber(rowRecord.detailData.comBalance)}}
</view>
<view class="hz-font-12px">Net Credit outstanding: {{formatNumber(rowRecord.detailData.netCreditOutstanding)}}
</view>
</u-col>
</u-row>
<u-row v-show="filterType==='IM'&&currentIndex===2" customStyle="margin-top:10px;">
<u-col span="6">
<view class="hz-font-12px">Today T/O : {{formatNumber(rowRecord.detailData.todayTo)}}
</view>
<view class="hz-font-12px">Today Win : {{formatNumber(rowRecord.detailData.todayWin)}}
</view>
</u-col>
<u-col span="6">
<view class="hz-font-12px">Yesterday T/O: {{formatNumber(rowRecord.detailData.yesterdayTO)}}</view>
<view class="hz-font-12px">Yesterday Win: {{formatNumber(rowRecord.detailData.yesterdayWin)}}</view>
<view class="hz-font-12px">Yesterday Playhour: {{formarHour(rowRecord.detailData.yesterdayPlayHour)}}
</view>
</u-col>
</u-row>
<u-row v-show="filterType==='IM'&&currentIndex===2" customStyle="margin-top:10px;">
<u-col span="6">
<view class="hz-font-12px">Prg T/O : {{formatNumber(rowRecord.detailData.prgTO)}}
</view>
<view class="hz-font-12px">Prg Win : {{formatNumber(rowRecord.detailData.prgWin)}}
</view>
<view class="hz-font-12px">Prg Avg PlayHour : {{formarHour(rowRecord.detailData.averagePlayHour)}}
</view>
<view class="hz-font-12px">IRC Prg Bal : {{formatNumber(rowRecord.detailData.iRCProgramFundBalance)}}
</view>
<view class="hz-font-12px">Exp comm : {{formatNumber(rowRecord.detailData.expComm)}}
</view>
<view class="hz-font-12px">Unsettled Expenses : {{formatNumber(rowRecord.detailData.unsettledExpenses)}}
</view>
</u-col>
<u-col span="6">
<view class="hz-font-12px">Front Money: {{formatNumber(rowRecord.detailData.frontMoney)}}</view>
<view class="hz-font-12px">TTO: {{formatNumber(rowRecord.detailData.tto)}}</view>
<!-- <view class="hz-font-12px">HA : {{getPercentFormat(rowRecord.detailData.houseAdvantage)}}
</view> -->
<view class="hz-font-12px">0.1Comp Balance: {{formatNumber(rowRecord.detailData.comBalance)}}
</view>
<view class="hz-font-12px">Net Credit outstanding: {{formatNumber(rowRecord.detailData.netCreditOutstanding)}}
</view>
</u-col>
</u-row>
<u-row customStyle="margin-top:10px;" v-show="filterType==='MASS'">
<u-col span="6">
<view class="hz-font-12px">R3M TPD: {{formatNumber(rowRecord.detailData.r3MTPD)}}</view>
<view class="hz-font-12px">R3M Win: {{formatNumber(rowRecord.detailData.r3MWin)}}</view>
<view class="hz-font-12px">R3M RI:
{{getPercentFormat(rowRecord.detailData.r3MRIPercentage)}}</view>
<view v-show="currentIndex === 2 && filterType ==='MASS'" class="hz-font-12px">R3M Theo : {{formatNumber(rowRecord.detailData.r3MTheo)}}
</view>
</u-col>
<u-col span="6">
<view class="hz-font-12px">R6M TPD: {{formatNumber(rowRecord.detailData.r6MTPD)}}</view>
<view class="hz-font-12px">R6M Win: {{formatNumber(rowRecord.detailData.r6MWin)}}</view>
<view class="hz-font-12px">R6M RI:
{{getPercentFormat(rowRecord.detailData.r6MRIPercentage)}}</view>
<view v-show="currentIndex === 2 && filterType ==='MASS'" class="hz-font-12px">R6M Theo : {{formatNumber(rowRecord.detailData.r6MTheo)}}
</view>
</u-col>
</u-row>
<u-row customStyle="margin-top:10px;" v-show="filterType==='IM'">
<u-col span="6">
<view class="hz-font-12px">R3M T/O: {{formatNumber(rowRecord.detailData.r3MTO)}}</view>
<view class="hz-font-12px">R3M T/O /D: {{formatNumber(rowRecord.detailData.r3MTOD)}}</view>
<view class="hz-font-12px">R3M Win:
{{formatNumber(rowRecord.detailData.r3MWin)}}</view>
</u-col>
<u-col span="6">
<view class="hz-font-12px">R6M T/O: {{formatNumber(rowRecord.detailData.r6MTO)}}</view>
<view class="hz-font-12px">R6M T/O /D: {{formatNumber(rowRecord.detailData.r6MTOD)}}</view>
<view class="hz-font-12px">R6M Win:
{{formatNumber(rowRecord.detailData.r6MWin)}}</view>
</u-col>
</u-row>
<view class="hz-split" style="margin-top:10px;"></view>
<view v-show="rowRecord.showOffer">
<view class="hz-font-color-dark hz-font-md">Available & Unredeem Offer</view>
<view v-for="(record,index) in rowRecord.detailData.descriptions"
:key="'offer-'+index" class="hz-font-12px todo-description-text">{{getOfferDescription(record)}}
</view>
<view class="hz-split"></view>
</view>
<view class="hz-font-color-dark hz-font-md" style="margin-top:10px;">Bookings
</view>
<view class="hz-flex-row" style="align-items: flex-start;"
v-show="hasFlightRecord(rowRecord.detailData.descriptions)">
<view class="icon-group" style="margin-top:5px;margin-left:0px;">
<image src="../../static/images/flight_line_2.svg"
class="icon-img-flight" style="margin-left:0px;margin-right:4px;">
</image>
</view>
<view class="hz-flex-col todo-description-list">
<view v-for="(record,index) in rowRecord.detailData.descriptions"
:key="'flight'+index" class="hz-flex-row todo-description-row"
style="align-items: flex-start;">
<span class="hz-font-12px todo-description-text">{{getFlightDescription(record)}}</span>
</view>
</view>
</view>
<view class="hz-flex-row" style="align-items: flex-start;"
v-show="hasLimoRecord(rowRecord.detailData.descriptions)">
<view class="icon-group" style="margin-top:3px;margin-left:0px;">
<image src="../../static/images/limo_line_2.svg" class="icon-img-limo"
style="margin-left:0px;margin-right:4px;"></image>
</view>
<view class="hz-flex-col todo-description-list">
<view v-for="(record,index) in rowRecord.detailData.descriptions"
:key="'limo'+index" class="hz-flex-row todo-description-row"
style="align-items: flex-start;">
<span class="hz-font-12px todo-description-text">{{getLimoDescription(record)}}</span>
</view>
</view>
</view>
<view class="hz-flex-row" style="align-items: flex-start;"
v-show="hasRoomRecord(rowRecord.detailData.descriptions)">
<view class="icon-group-room">
<image src="../../static/images/room_line_2.svg" class="icon-img-room"
style="margin-top:2px;margin-right:3px;"></image>
</view>
<view class="hz-flex-col todo-description-list">
<view v-for="(record,index) in rowRecord.detailData.descriptions"
:key="'room'+index" class="hz-flex-row todo-description-row"
style="align-items: center;">
<span class="hz-font-12px todo-description-text">
<template v-for="(part, partIndex) in getRoomDescriptionParts(record)">
<image v-if="part.type === 'sharerIcon'" :key="'room-sharer-'+index+'-'+partIndex"
src="../../static/images/sharer_line_2.svg"
class="icon-img-sharer todo-description-sharer-icon"></image>
<span v-else :key="'room-text-'+index+'-'+partIndex">{{part.text}}</span>
</template>
</span>
</view>
</view>
</view>
</view>
</view>
</uni-card>
<template v-slot:right>
<view v-if="currentIndex === 0" class="hz-flex-row" style="height:100%;align-items: center;margin-left:15px;"
@click.stop="openETA(rowRecord)" @touchstart.stop @touchend.stop>
<view class="slot-button slot-button-eta"><text class="slot-button-text">ETA</text>
</view>
</view>
<view v-else class="hz-flex-row" style="height:100%;align-items: center;margin-left:15px;"
@click.stop="openBookingRecord(rowRecord)" @touchstart.stop @touchend.stop>
<view class="slot-button slot-button-eta"><text class="slot-button-text">EXT</text>
</view>
</view>
<view v-if="currentIndex === 0" class="hz-flex-row" style="height:100%;align-items: center;margin-left:15px;"
@click.stop="openBookingRecord(rowRecord)" @touchstart.stop @touchend.stop>
<view class="slot-button slot-button-cancel">
<u-icon name="close" color="#ffffff" :size="16"></u-icon>
</view>
</view>
</template>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<view v-if="currentIndex === 3" v-for="(record,index) in listData" :key="'record'+index" style="margin-bottom:8px;">
<view class="hz-date-title">{{record.date}}</view>
<uni-card v-for="(rowRecord,rowIndex) in record.dateRecords" :key="'other-card-' + index + '-' + rowIndex" style="margin-left:4rpx;margin-right:4rpx;padding:12px;">
<u-row v-for="(rowDescription,descIndex) in getOtherDescription(rowRecord.descriptions)" :key="'other-desc-' + index + '-' + rowIndex + '-' + descIndex">
<u-col span="12">
<view class="hz-font-color-dark hz-font-md todo-description-text" style="margin-bottom:6px;">
<span v-if="descIndex !== 0">•</span> {{getEmojiDescription(rowDescription)}}
</view>
</u-col>
</u-row>
</uni-card>
</view>
</view>
<!--content end-->
</view>
<u-modal :show="showETAMsg" :confirmText="yesText" @confirm="submitETA()" confirmColor="#C39A4B" :closeOnClickConfirm="false"
@cancel="showETAMsg=false;" @close="showETAMsg=false;" :cancelText="cancelText" showCancelButton>
<view class="slot-content hz-flex-col" style="align-items: center;">
<image src="../../static/images/time_line.svg" class=" hz-mr-b-30" style="width:48px;height:48px;">
</image>
<view class="hz-font-xl hz-font-bolder">Estimate Time Arrival</view>
<view class="hz-font-md hz-mr-b-30" style="margin-top:8px;color:#666666;">{{etaPlayerId}} / {{etaPlayerName}}</view>
<view class="hz-flex-row" style="align-items: center;">
<u-code-input v-model="etaTime" :maxlength="4" :isColon="true" space="14" :focus="true" color="#333333" :fontSize="26"
:bold="true"></u-code-input>
</view>
<view class="hz-font-12px hz-mr-b-30" style="margin-top:12px;color:#666666;">( 24h, format: 02:30 )
</view>
</view>
</u-modal>
<u-modal :content="msgStr" :show="showMsg" :confirmText="okText" :showCancelButton="false" closeOnClickOverlay @confirm="showMsg=false" confirmColor="#C39A4B" @close="showMsg=false"></u-modal>
<u-popup
:safeAreaInsetBottom="true"
:safeAreaInsetTop="true"
:mode="'center'"
:round="12"
:show="showMsgBox"
:customStyle="'width:' + windowWidth + 'px;'"
>
<view
:style="'width:100%;max-width:' + windowWidth + 'px;'"
style="padding-top:30px;padding-bottom: 30px;"
>
<view class="hz-flex-row" style="justify-content:center;align-items:center;width:100%;">
<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;margin-bottom: 20px;">
<rich-text v-html="popMsgStr" style="line-height:26px;"></rich-text>
</view>
<view @click="showMsgBox = false" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" style="width: 90%;margin: 0 auto;">
{{$t("common.ok").toUpperCase()}}
</view>
</view>
</u-popup>
<u-calendar closeOnClickOverlay :confirmText="confirmText" :confirmDisabledText="confirmText" color="#C39A4B"
title="" :startText="startText" :endText="endText" :show="showCalendar" :allowSameDay="true"
:maxDate="maxDate" :minDate="minDate" mode="range" :monthNum="monthNum" :maxRange="maxRange" :footerInfo="footerInfo"
@close="cancelDate" @confirm="confirmDate" @rangeSelected="rangeSelected" :showMark="false"
:showRangePrompt="showRangePrompt" :defaultDate="calendarSave" :rangePrompt="rangeTip">
</u-calendar>
</view>
<view v-if="!showTodoListView">
<view class="hz-flex-row" style="justify-content: center;margin-top:40px;">
<image src="/static/images/datanull.png" style="width:160px;height:160px;"></image>
</view>
<view class="hz-flex-row hz-font-bolder hz-font-md" style="justify-content: center;margin:20px;">
{{dataNull}}
</view>
</view>
</view>
</template>
<script>
import mgmHeader from '@/components/header/header.vue' // 引入头部组件
// #ifdef APP-PLUS
import SimpleWatermark from '@/components/simple-watermark/simple-watermark.vue'
// #endif
import {
playerLookup
} from '../../api/mgmApi.js'
import {
getTodoDetail,
getTodoList,
submitETA
} from '../../api/todoApi';
import list from '../../uni_modules/uview-ui/libs/config/props/list';
import {
getProperties,
getBookingTypes,
getRooms,
getRoomTypes,
getSpecials,
getBedTypes,
getCriterias,
getAvailableRoom,
getSetting,
getExtendBooking
} from '../../api/configApi.js';
import { normalizeApiKeys, getApiRecords } from '../../common/normalizeApiKeys.js';
export default {
components: {
mgmHeader, // 注册组件
// #ifdef APP-PLUS
SimpleWatermark
// #endif
},
data() {
return {
isOpen: true,
filterType: '',
deviceData: null,
siteData: null,
listData: [],
etaTime: '',
comfList: [],
etaPlayerId:null,
isYesterday:false,
etaPlayerName:null,
//界面变量
// itemOpen: 'none',
showETAMsg: false,
showMsgBox:false,
popMsgStr:'',
iconPath:'',
etaConfNo:[],
cancelText: this.$t("common.cancel"),
okText: this.$t("common.ok"),
yesText: this.$t("common.submit"),
confirmText: this.$t("common.confirm").toUpperCase(),
inText: this.$t("common.in"),
outText: this.$t("common.out"),
startText: this.$t("common.start"),
endText: this.$t("common.end"),
dataNull:'',
showDetail: false,
showRangePrompt:true,
startDate:new Date(),
endDate:new Date(),
todayDate:new Date(),
yesterdayDate:new Date(),
tomorrowDate:new Date(),
minDate:'',
maxDate: '',
monthNum: 0,
maxRange: 0,
footerInfo: "",
showDetailLoading: false,
arrowName: 'arrow-down',
isProcessing: false,
navbarHeight: 0,
windowWidth:0,
bgColor: '#ffffff',
etaBackgroundClolor: null,
height: 44,
showNavbar: true,
showCalendar: false,
lastScrollPosition: 0, // 记录上次滚动位置
hideThreshold: 100, // 开始隐藏的滚动阈值
showThreshold: 100, // 修改为100px,向下滑动100px就显示
isHiding: false, // 是否正在隐藏过程中
isShowing: false, // 是否正在显示过程中
minScrollPosition: 0, // 记录页面最小滚动位置
downScrollStart: 0, // 记录向下滑动的起始位置
isDownScrolling: false, // 是否正在向下滚动
tabbarVisible: true,
navbarOpacity: 1, // 控制navbar的透明度
lastScrollTop: 0,
currentIndex: 0,
sliderPosition: 0,
userData: null,
msgStr:null,
showMsg:false,
handleETA:false,
ETATime: 0,
showTodoListView:false,
etaData: [],
playerData: {
playerId: "",
playerName: "",
tireName: ""
},
todoRecord: {
playerId: "11010001",
playerName: "IVAN LAU",
other: "Other Test"
},
todoDetailData: [],
tabs: [{
name: this.$t("todo.arrival"),
color: '#4a6da7' // 到达
},
{
name: this.$t("todo.departure"),
color: '#5b8a72' // 离开
},
{
name: this.$t("todo.inhouse"),
color: '#8e6f50' // 在住
},
{
name: this.$t("todo.others"),
color: '#333333' // 其他
}
],
calendarSave: [null, null],
rangeTip: this.$t("common.rangeTip"),
calendarIconColor: "#000000",
currentTask: null,
todoListRequestSeq: 0
}
},
watch: {
// 深度监听 tabs 数组的变化
tabs: {
handler(newVal, oldVal) {
// 只有当 tabs 内容实际变化时才调用(避免初始化时重复调用)
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.listData = [];
this.setCalendar();
}
},
deep: true // 设置为深度监听
},
// 同时监听 currentIndex 变化(切换 tab 时触发)
currentIndex() {
this.listData = [];
this.setCalendar();
}
},
onLoad() {
// 初始化界面
this.initUI();
this.siteData = uni.getStorageSync("siteData");
// 确保tabbarVisible被正确初始化
this.tabbarVisible = true;
},
mounted() {
// 在组件挂载后初始化滑块位置
this.$nextTick(() => {
setTimeout(() => {
this.updateSliderPosition();
}, 100); // 添加一点延迟确保DOM已经渲染完成
});
},
onReady() {
// onReady生命周期在页面渲染完成后触发,也可以在这里初始化滑块位置
this.updateSliderPosition();
// 页面首次渲染完成后,延迟触发水印更新
setTimeout(() => {
console.log('[TodoList] Triggering watermark update on ready');
const watermarkStore = require('@/store/watermark.js');
if (watermarkStore && watermarkStore.updateWatermark) {
watermarkStore.updateWatermark(true);
}
}, 1200);
},
onShow() {
this.setCalendar();
this.userData = uni.getStorageSync("userData");
this.playerData = uni.getStorageSync("playerData");
if(this.userData!==null && this.userData!==undefined)
this.showTabbarByPermission(this.userData);
this.listData = [];
// 确保每次页面显示时tabbar状态正确
if (this.tabbarVisible === undefined) {
this.tabbarVisible = true;
}
if(uni.getStorageSync('todoSwitch') === "true"){
if(this.userData.division !== 'VIP Marketing'){
console.log(this.userData.division);
this.isOpen = true;
this.filterType = "MASS";
}else{
console.log(this.userData.division);
this.isOpen = false;
this.filterType = 'IM';
}
uni.setStorageSync('todoSwitch',"false");
}
// 如果需要,可以强制显示tabbar
if (this.tabbarVisible) {
uni.showTabBar();
}
// 手动触发水印更新,确保水印在页面显示时正确显示
this.$nextTick(() => {
setTimeout(() => {
console.log('[TodoList] Manually triggering watermark update on show');
const watermarkStore = require('@/store/watermark.js');
if (watermarkStore && watermarkStore.updateWatermark) {
watermarkStore.updateWatermark(true);
}
}, 500);
});
this.tabs=[{
name: this.$t("todo.arrival"),
color: '#4a6da7' // 到达
},
{
name: this.$t("todo.departure"),
color: '#5b8a72' // 离开
},
{
name: this.$t("todo.inhouse"),
color: '#8e6f50' // 在住
},
{
name: this.$t("todo.others"),
color: '#333333' // 其他
}
]
},
onPageScroll(e) {
const scrollTop = e.scrollTop;
const scrollDelta = scrollTop - this.lastScrollPosition;
// 添加节流,避免频繁触发
if (this.isHiding || this.isShowing) {
this.lastScrollPosition = scrollTop;
return;
}
// 1. 检测滚动方向并跟踪向下滚动
if (scrollDelta < 0) {
// 向下滚动
if (!this.isDownScrolling) {
this.isDownScrolling = true;
this.downScrollStart = scrollTop; // 记录向下滑动的起始位置
}
} else {
// 向上滚动
this.isDownScrolling = false;
}
// 2. 处理向下滚动超过100px的情况
if (this.isDownScrolling) {
const downScrollDistance = this.downScrollStart - scrollTop;
if (downScrollDistance > this.showThreshold) {
if (!this.showNavbar || this.navbarOpacity < 1) {
this.showElements();
}
// 重置向下滚动状态,避免重复触发
this.isDownScrolling = false;
}
}
// 3. 主要显示/隐藏逻辑
if (scrollTop > this.hideThreshold && scrollDelta > 0 && !this.isHiding) {
this.hideElements();
}
// 4. 接近顶部时强制显示
else if (scrollTop <= 50 && !this.showNavbar && !this.isShowing) {
this.showElements();
}
// 5. 更新滚动位置
this.lastScrollPosition = scrollTop;
},
methods: {
swipeChange(e, index) {
console.log('返回:', e);
console.log('当前索引:', index);
},
changeTest(record,action,event){
// 滑动时候转换,handleETA时转换
if(action===1 && !(this.handleETA)){
if(record.itemOpen=='none'){
record.itemOpen = event;
}else{
record.itemOpen = event;
}
}
// 当点击ETA按钮时,在关闭滑块后将handleETA改为false
this.handleETA = false;
},
formatNumber(num) {
return num?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") || "0";
},
formarHour(num){
let hourStr = '';
if(num!==null && num!==0){
hourStr = num > 1 ? num + ' hours' : num + ' hour';
}else{
hourStr = 0 + ' hour'
}
return hourStr;
},
checkPassEtaTime(record) {
// 获取当前日期(不含时间)
let today = new Date();
let currentDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
// 解析actionDate并创建纯日期对象
let actionDateObj = new Date(record.actionDate);
let actionDate = new Date(actionDateObj.getFullYear(), actionDateObj.getMonth(), actionDateObj.getDate());
// 获取当前时间
let currentTime = new Date().toTimeString().slice(0, 5);
let currentHour = parseInt(currentTime.split(":")[0]);
let currentMinute = currentTime.split(":")[1];
// 解析ETA时间
let etaHour = parseInt(record.eta.split(":")[0]);
let etaMinute = record.eta.split(":")[1];
// 如果ETA小时小于6,将actionDate加一天
if (etaHour < 6) {
actionDate.setDate(actionDate.getDate() + 1);
}
// 如果当前小时小于6,将当前日期加一天
if (currentHour < 6) {
currentDate.setDate(currentDate.getDate() + 1);
}
// 比较纯日期(时间部分都是00:00:00)
if (actionDate < currentDate) {
return true; // actionDate在当前日期之前
} else if (actionDate > currentDate) {
return false; // actionDate在当前日期之后
} else {
// 日期相同,比较时间
if (currentHour > etaHour) {
return true;
} else if (currentHour === etaHour) {
if (currentMinute > etaMinute) {
return true;
}
}
return false;
}
},
openETA(e) {
this.etaData = [];
// 将handleETA改为true避免死循环
// this.handleETA = true ;
// e.itemOpen = 'none';
this.etaPlayerId = e.playerId;
this.etaPlayerName = e.englishName;
// 阻止事件冒泡和默认行为
if (e && e.stopPropagation) {
e.stopPropagation();
}
if (e && e.preventDefault) {
e.preventDefault();
}
// 重置状态变量
this.etaData = e;
// this.itemOpen = 'none';
this.etaConfNo = (e.operaConfirmationNo).split(",");
// 使用父组件的closeAll方法关闭滑块
this.$nextTick(() => {
// 查找uni-swipe-action父组件
let parent = this.$refs.swipeAction.$parent;
while (parent && parent.$options.name !== 'uniSwipeAction') {
parent = parent.$parent;
}
if (parent && parent.closeAll) {
parent.closeAll();
}
// 直接设置组件状态
if (this.$refs.swipeAction) {
this.$refs.swipeAction.is_show = 'none';
}
});
// 延迟执行以确保滑块动画完成
if(this.etaData.operaConfirmationNo !== undefined && this.etaData.operaConfirmationNo !== ';' && this.etaData.operaConfirmationNo !== null){
setTimeout(() => {
this.etaTime = '';
this.showETAMsg = true;
}, 100);
}else{
uni.showToast({
title:this.$t("todo.notConfNo"),
icon: "none"
});
}
},
async openBookingRecord(record) {
// 阻止事件冒泡和默认行为
// if (e && e.stopPropagation) {
// e.stopPropagation();
// }
// if (e && e.preventDefault) {
// e.preventDefault();
// }
// 重置状态变量
// this.itemOpen = 'none';
let params = {
playerId: record.playerId,
userId: this.userData.userId
};
try{
uni.showLoading({
title: this.$t("common.loading")
});
const res = await playerLookup(params);
if (res.success == true) {
if (res.data !== null) {
if(res.data.codedFlag==1){
uni.setStorageSync("playerData",res.data);
uni.hideLoading();
this.navTo("/booking/bookingRecord/bookingRecord",0,false);
}else{
uni.showToast({
title:this.$t("findPlayer.noPermission"),
icon: "none"
});
}
}
}
}catch(e){
}finally{
uni.hideLoading();
}
// 使用父组件的closeAll方法关闭滑块
this.$nextTick(() => {
// 查找uni-swipe-action父组件
let parent = this.$refs.swipeAction.$parent;
while (parent && parent.$options.name !== 'uniSwipeAction') {
parent = parent.$parent;
}
if (parent && parent.closeAll) {
parent.closeAll();
}
// 直接设置组件状态
if (this.$refs.swipeAction) {
this.$refs.swipeAction.is_show = 'none';
}
});
},
// 点击头部tab刷新todoList数据,如果点击了其他的tab,则不执行该方法
handlerGetToDoList(index) {
if (this.currentIndex == index) {
this.getTodoListByData();
}
},
isValid24HourTime(timeStr) {
if (!timeStr) return false;
const regex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
return regex.test(timeStr);
},
async submitETA() {
let paramData = {
items:[]
};
let hotelName = null;
// 获取接口参数
paramData = this.getparamData(this.etaData);
// 关闭模态框
uni.showLoading({
title: this.$t("common.loading")
});
let params = {};
// 获取用户输入的时间字符串
const etaTimeStr = this.etaTime;
// 檢驗etaTime不能為空
if (!etaTimeStr || etaTimeStr.trim() === '') {
uni.hideLoading();
uni.showToast({ title: this.$t("todo.etaRequired"), icon: "none" });
this.etaTime = '';
return;
}
params.ETATime = `${etaTimeStr.slice(0, 2)}:${etaTimeStr.slice(2)}`;
// 檢驗輸入時間格式是否為24小時制
if (!this.isValid24HourTime(params.ETATime)) {
uni.hideLoading();
uni.showToast({ title: this.$t("todo.etaFormatError"), icon: "none" });
this.etaTime = '';
return;
}
try{
params.recordInfo = paramData.items;
params.playerId = this.etaData.playerId;
// this.itemOpen = 'none';
const res = await submitETA(params);
if(res.success!==null && res.success == true){
this.iconPath = '../../static/images/ico_suc.png';
this.popMsgStr = this.$t("todo.etaSuccess");
// 重新获取数据,刷新eta
this.getTodoListByData();
// for(let i = 0 ; i < this.listData.length ; i++){
// console.log(i);
// for(let j = 0 ; j < this.listData[i].dateRecords.length ; j++){
// console.log(j);
// console.log(this.listData[i].dateRecords[j].itemOpen);
// }
// }
}else{
this.iconPath = '../../static/images/ico_err.png';
if(res.code == 'NO_RECORD'){
this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ this.$t("todo.notRecord");
}else if(res.code == 'MISS_PARAMETER'){
this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ this.$t("todo.missParams");
}else{
this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ res.code;
}
}
this.showMsgBox = true;
}catch(e){
console.error(e);
if(e.data!==null&&e.data!==undefined&&e.data.message!==undefined){
this.iconPath = '../../static/images/ico_err.png';
this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ e.data.error;
this.showMsgBox = true;
}else{
this.iconPath = '../../static/images/ico_err.png';
this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ e;
this.showMsgBox = true;
}
}finally{
this.showETAMsg = false;
uni.hideLoading();
this.etaTime = '';
}
// 使用父组件的closeAll方法关闭所有滑块
this.$nextTick(() => {
const swipeRef = this.$refs.swipeAction;
if (!swipeRef) return;
// 查找uni-swipe-action父组件
let parent = this.$refs.swipeAction.$parent;
while (parent && parent.$options.name !== 'uniSwipeAction') {
parent = parent.$parent;
}
if (parent && parent.closeAll) {
parent.closeAll();
}
// 直接设置组件状态
if (this.$refs.swipeAction) {
this.$refs.swipeAction.is_show = 'none';
}
});
},
initUI() {
this.deviceData = uni.getStorageSync("deviceData");
let device = this.deviceData;
let statusBarHeight = device.statusBarHeight;
this.navbarHeight = statusBarHeight + 44;
this.windowWidth = this.deviceData.windowWidth*0.95;
},
openCalendar(){
this.showCalendar = true;
},
async setCalendar(){
const today = new Date();
const tomorrow = new Date(today);
const nextMonth = new Date(today);
const yesterday = new Date(today);
let timeStart,timeEnd = '';
let dbStart = '';
let dbEnd = '';
tomorrow.setDate(tomorrow.getDate() + 1);
yesterday.setDate(yesterday.getDate() - 1);
nextMonth.setMonth(nextMonth.getMonth() + 1);
// 到Setting表获取时间区间
try {
let params = {};
const res = await getSetting(params);
if (res != null && res.success == true) {
for (let i of res.data) {
if (i.keys == "VIEW_YESTERDAY_TODOLIST_START") {
dbStart = i.keyValues;
}else if(i.keys == "VIEW_YESTERDAY_TODOLIST_END"){
dbEnd = i.keyValues
}
}
let today = new Date();
let currentHour = today.getHours();
let currentMinute = today.getMinutes();
// 解析 start 和 end 时间
let startHour = parseInt(dbStart.split(":")[0]);
let startMinute = parseInt(dbStart.split(":")[1] || 0);
let endHour = parseInt(dbEnd.split(":")[0]);
let endMinute = parseInt(dbEnd.split(":")[1] || 0);
// 将当前时间转换为分钟总数以便比较
let totalCurrent = currentHour * 60 + currentMinute;
let totalStart = startHour * 60 + startMinute;
let totalEnd = endHour * 60 + endMinute;
// 判断当前时间是否在 [start, end) 区间内
if (totalCurrent >= totalStart && totalCurrent < totalEnd) {
this.minDate = this.formatDate(yesterday);
this.isYesterday = true;
} else {
this.isYesterday = false;
this.minDate = this.formatDate(today);
}
} else {
// write log
}
} catch (e) {
// write log
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, "Set Calendar", "",
"[APP][newBooking.vue][getSetting][Catch Exception]" + e.errMsg, request,response, 1, false);
} finally {
}
if(this.isYesterday){
this.startDate = yesterday; // 存储为 Date 对象
this.endDate = today; // 存储为 Date 对象
}else{
this.startDate = today; // 存储为 Date 对象
this.endDate = tomorrow; // 存储为 Date 对象
}
this.todayDate = today;
this.yesterdayDate = yesterday;
this.tomorrowDate = tomorrow;
this.maxDate=this.formatDate(nextMonth);
this.monthNum=2;
this.maxRange=6;
this.showRangePrompt=true;
this.getTodoListByData();
},
switchFilterType() {
this.isOpen = !this.isOpen;
if (this.isOpen == true) {
this.filterType = 'MASS';
} else {
this.filterType = 'IM';
}
this.listData = [];
this.getTodoListByData();
},
// 显示元素的统一方法
showElements() {
if (this.isShowing) return;
this.isShowing = true;
this.isHiding = false;
// 使用CSS过渡效果显示元素
this.navbarOpacity = 1;
this.showNavbar = true;
// 修改这里的判断逻辑,确保tabbar能被显示
this.tabbarVisible = true;
uni.showTabBar();
// 重置状态,时间与CSS过渡时间匹配
setTimeout(() => {
this.isShowing = false;
}, 400);
},
cancelDate() {
this.showCalendar = false;
},
confirmDate(e) {
this.startDate = e[0];
this.endDate = e[e.length-1];
this.getTodoListByData();
this.showCalendar = false;
},
async rangeSelected(e) {
if (e && e.length >= 2) {
const startDate = e[0];
const endDate = e[e.length - 1];
}
},
hideElements() {
if (this.isHiding) return;
this.isHiding = true;
this.isShowing = false;
// 使用CSS过渡效果隐藏元素
this.navbarOpacity = 0;
this.showNavbar = false;
// 修改这里的判断逻辑,确保tabbar能被隐藏
this.tabbarVisible = false;
uni.hideTabBar();
// 重置状态,时间与CSS过渡时间匹配
setTimeout(() => {
this.isHiding = false;
}, 400);
},
// checkPassTimeArea(today,dbStart,dbEnd){
// let tMStart = dbStart.split(":");
// let tMEnd = dbEnd.split(":");
// let pass = false;
// // 判断是否超过时间区间
// if(today.getHours>tMStart[0] && today.getHourt<tMEnd[0]){
// // 没超过,返回true
// pass = ture;
// }else if(today.getHours===tMStart[0] && today.getMinutes>tMStart[1]){
// }
// else if(today.getHours<tMStart[0] && today.getHourt>tMEnd[0]){
// // 超过返回false
// pass = false
// }
// },
switchTab(index) {
this.currentIndex = index;
this.$nextTick(() => {
this.updateSliderPosition();
});
},
formatDate(date) {
if(typeof(date)!=='string'){
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}else{
// 兼容后端/前端返回的 ISO 字符串:2026-03-25T00:00:00
// 只保留 YYYY-MM-DD
if (date.includes('T')) {
return date.split('T')[0];
}
return date;
}
},
async getTodoListByData() {
const requestSeq = ++this.todoListRequestSeq;
if (this.currentTask) {
try {
this.currentTask.abort();
uni.hideLoading();
} catch (err) {
}
}
uni.showLoading({
title: this.$t("common.loading")
});
let requestBody = "";
try {
let params = {};
params.TodoSegment = this.filterType;
if(this.currentIndex ===0){//根据currentIndex获取TodoCategory
params.TodoCategory = "Arrival";
}else if(this.currentIndex ===1){
params.TodoCategory = "Departure";
}else if(this.currentIndex ===2){
params.TodoCategory = "Inhouse";
}else if(this.currentIndex ===3){
params.TodoCategory = "Others";
}
if(this.currentIndex===2||this.currentIndex===3){
if(this.isYesterday){
params.StartDate = this.formatDate(this.yesterdayDate);
params.EndDate = this.formatDate(this.yesterdayDate);
}else{
params.StartDate = this.formatDate(this.todayDate);
params.EndDate = this.formatDate(this.todayDate);
}
}else{
params.StartDate = this.formatDate(this.startDate);
params.EndDate = this.formatDate(this.endDate);
}
this.calendarSave[0] = this.formatDate(params.StartDate);
this.calendarSave[1] = this.formatDate(params.EndDate);
this.checkCalendarSave();
requestBody = JSON.stringify(params);
const res = await getTodoList(params, {
getTask: (task, options) => {
this.currentTask = task;
}
});
if (requestSeq !== this.todoListRequestSeq) return;
this.currentTask = null;
const records = res && res.data && Array.isArray(res.data.records) ? res.data.records : [];
if (res && res.success == true && records.length > 0) {
this.showTodoListView=true;
this.listData = records.map(record => ({
...record,
dateRecords: record.dateRecords.map(dateRecord => ({
...dateRecord,
showDetailLoading: false, // 为每条 dateRecord 添加 loading
showDetail: false, // 添加展开状态
arrowName: 'arrow-down', // 添加箭头方向
isProcessing: false,
detailData: null,
splitDescription:null,
showOffer:false,
itemOpen:"none"
}))
}));
}else{
const errorCode = res && res.errorCode ? res.errorCode.toUpperCase() : "";
if(errorCode.indexOf('NO RECORD') != -1 || (res && res.success == true && records.length == 0)){
this.dataNull = this.$t("common.noRecord");
}else{
this.dataNull = this.$t("todo.returnError");
}
this.showTodoListView=false;
}
} catch (e) {
if (e.errMsg && e.errMsg.includes("abort")) {
} else if (e.data!==null&&e.data!==undefined&&e.data.message!==undefined){
this.dataNull = e.data.message;
this.showTodoListView=false;
console.error(e.data.message);
}else{
this.dataNull = this.$t("todo.returnError");
this.showTodoListView=false;
console.error(e);
}
} finally {
if(requestSeq === this.todoListRequestSeq && !this.currentTask){
uni.hideLoading();
}
}
},
async fetchTodoDetail(record) {
// 防止重复点击
if (record.isProcessing) {
return;
}
if (record.arrowName === 'arrow-down') {
try {
this.todoDetailData = [];
let params = {
PlayerId: record.playerId,
TodoSegment: this.filterType
};
if(this.currentIndex ===0){//根据currentIndex获取TodoCategory
params.TodoCategory = "Arrival";
}else if(this.currentIndex ===1){
params.TodoCategory = "Departure";
}else if(this.currentIndex ===2){
params.TodoCategory = "Inhouse";
}else if(this.currentIndex ===3){
params.TodoCategory = "Others";
}
record.isProcessing = true;
record.showDetailLoading = true;
//如果是Inhouse或者Others 参数日期为当天
if(this.currentIndex === 2 || this.currentIndex ===3)params.Date = this.formatDate(this.todayDate);
else params.Date = this.formatDate(record.actionDate);
const res = await getTodoDetail(params);
if (res != null && res.success == true) {
record.detailData = normalizeApiKeys(res.data);
console.log(record.detailData.r3MTOD);
if(record.detailData.descriptions!==null){
for(let i=0;i<record.detailData.descriptions.length;i++){
if(record.detailData.descriptions[i].itemRecordType == 'Offer'){
record.showOffer = true;
}
}
}
setTimeout(() => {
record.arrowName = 'arrow-up';
record.showDetail = true;
record.showDetailLoading = false;
record.isProcessing = false;
}, 1000);
}else{
uni.showToast({
title:res.message,
icon: "none"
});
record.showDetail = false;
record.arrowName = 'arrow-down';
record.showDetailLoading = false;
record.isProcessing = false;
}
} catch (e) {
uni.showToast({
title:this.$t("todo.detailFail"),
icon: "none"
});
record.showDetail = false;
record.arrowName = 'arrow-down';
record.showDetailLoading = false;
record.isProcessing = false;
} finally {
}
} else {
// 收起时添加一个短暂的延迟,让动画更自然
record.isProcessing = true;
setTimeout(() => {
record.showDetail = false;
record.arrowName = 'arrow-down';
record.showDetailLoading = false;
record.isProcessing = false;
}, 100); // 100ms延迟让收起更自然
}
},
updateSliderPosition() {
const query = uni.createSelectorQuery().in(this);
// 获取当前选中tab的位置信息
query.select(`#tab${this.currentIndex}`).boundingClientRect();
// 获取slider-container的位置信息
query.select('#slider-container').boundingClientRect();
query.exec(rects => {
if (rects && rects.length === 2) {
const tabRect = rects[0];
const containerRect = rects[1];
if (tabRect && containerRect) {
// 计算tab的中心位置
const tabCenter = tabRect.left + (tabRect.width / 2);
// 计算slider应该移动的距离(相对于slider-container)
this.sliderPosition = tabCenter - containerRect.left - 10; // 10是slider宽度的一半
}
}
});
},
// 监听日期区间的变化,以修改日历 icon 的颜色
checkCalendarSave() {
if (!this.calendarSave[0] || !this.calendarSave[1]) {
this.calendarIconColor = "#000000";
return;
}
const startDt = new Date(this.calendarSave[0]);
const endDt = new Date(this.calendarSave[1]);
// 获取今天和明天的日期,并且设置时间部分为00:00:00
const today = new Date();
if(this.isYesterday){
today.setDate(today.getDate() - 1); // 设置为昨天
}
today.setHours(0, 0, 0, 0);
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
const isStartToday = this.isSameDate(startDt, today);
const isEndTomorrow = this.isSameDate(endDt, tomorrow);
this.calendarIconColor = isStartToday && isEndTomorrow ? "#000000" : "#C39A4B";
},
showTrashIcon(){
const startDt = new Date(this.calendarSave[0]);
const endDt = new Date(this.calendarSave[1]);
// 获取今天和明天的日期,并且设置时间部分为00:00:00
const today = new Date();
if(this.isYesterday){
today.setDate(today.getDate() - 1); // 设置为昨天
}
today.setHours(0, 0, 0, 0);
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
const isStartToday = this.isSameDate(startDt, today);
const isEndTomorrow = this.isSameDate(endDt, tomorrow);
const canShow = (isStartToday && isEndTomorrow) || this.currentIndex ===2 || this.currentIndex ===3 ? false : true;
return canShow;
},
isSameDate(date1, date2) {
return date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() &&
date1.getDate() === date2.getDate()
}
},
computed: {
getFlightDescription() {
return function(record) {
if (record.itemRecordType == 'Flight')
return record.itemRecordDescription;
};
},
hasFlightRecord() {
return function(record) {
let result = false;
for (let i = 0; i < record.length; i++) {
if (record[i].itemRecordType == 'Flight') {
result = true;
break;
} else {
result = false;
}
}
return result;
}
},
getOfferDescription() {
return function(record) {
if (record.itemRecordType == 'Offer')
return record.itemRecordDescription;
};
},
getLimoDescription() {
return function(record) {
if (record.itemRecordType == 'Limo')
return record.itemRecordDescription;
};
},
hasLimoRecord() {
return function(record) {
let result = false;
for (let i = 0; i < record.length; i++) {
if (record[i].itemRecordType == 'Limo') {
result = true;
break;
} else {
result = false;
}
}
return result;
}
},
getRoomDescription() {
return function(record) {
if (record.itemRecordType == 'Room'){
return record.itemRecordDescription.replace(/\s*\|\s*Sharer:\s*[YN]\s*/," ");
}
};
},
getRoomDescriptionParts() {
return (record) => {
if (!record || record.itemRecordType !== 'Room') {
return [];
}
return this.getDescriptionWithSharerIconParts(record.itemRecordDescription);
};
},
getDescriptionWithSharerIconParts() {
return (description) => {
if (description === null || description === undefined || description === '') {
return [];
}
const segments = String(description).split('|');
const parts = [];
for (let i = 0; i < segments.length; i++) {
const segment = segments[i].trim();
if (segment === '') {
continue;
}
const sharerMatch = segment.match(/^Sharer\s*:\s*([YN])$/i);
if (sharerMatch) {
if (String(sharerMatch[1]).toUpperCase() === 'Y') {
parts.push({ type: 'sharerIcon' });
}
continue;
}
const lastPart = parts.length ? parts[parts.length - 1] : null;
const text = lastPart && lastPart.type === 'text' ? ` | ${segment}` : segment;
parts.push({ type: 'text', text });
}
return parts;
};
},
hasRoomRecord() {
return function(record) {
let result = false;
for (let i = 0; i < record.length; i++) {
if (record[i].itemRecordType == 'Room') {
result = true;
break;
} else {
result = false;
}
}
return result;
}
},
getItemDescription() {
return function(record) {
if (this.currentIndex !== 3 && record.indexOf("Sharer") !== -1) {
return record.replace(/\s*\|\s*Sharer:\s*[YN]\s*/," ");
} else {
return record;
}
}
},
showETA(){
return function(record){
let isShow = false;
if (this.currentIndex ===0) {
if(record.eta !=='' && record.eta !== null){
isShow = true;
}
}
if(this.currentIndex === 2){
if(record.bigLossFlag === 1 || record.bigWinFlag === 1 || record.noPlayFlag === 1 || record.noPlayFlag === 2){
isShow = true;
}
}
return isShow;
}
},
getTextColor() {
return function(record) {
if (record.noPlayFlag == 1) {
return "#000000"; // black
}
return "#FFFFFF"; // white
}
},
getItemShowSharerIcon() {
return function(record) {
let sharerRecord = record.match(/\|\s*Sharer:\s*([YN])(?:\s*\||\s*$)/);
let hasSharer = sharerRecord !== null ? sharerRecord[1] : "N";
return hasSharer == "N" ? false : true;
}
},
getETALable() {
return function(record) {
if (this.currentIndex !== 1 && this.currentIndex !== 2) {
return record.eta;
} else if (record.bigLossFlag === 1) {
return "BIGLOSS";
} else if (record.bigWinFlag === 1) {
return "BIGWIN";
} else if (record.noPlayFlag === 1 || record.noPlayFlag === 2){
return "No Play";
}
}
},
getETAColor() {
return function(record) {
if (this.currentIndex !== 1 && this.currentIndex !== 2 && record.eta !== null && record.eta !== undefined) {
if(this.checkPassEtaTime(record)){
return '#ff5a5f';
}else{
return '#9f9f9f';
}
} else if (record.bigLossFlag === 1) {
return '#ff5a5f';
} else if (record.bigWinFlag === 1) {
return '#4a6da7';
} else if(record.noPlayFlag === 1){
return '#ffff00'; // yellow
} else if (record.noPlayFlag === 2) {
return '#aa0000' // red
}
}
},
getparamData() {
return function(record) {
let paramData = {
items:[]
};
if(record.operaConfirmationNo!==undefined && record.operaConfirmationNo!==null && record.operaConfirmationNo!==""){
//遍历opeaConfirmationNo拿到MGM的hotelName和confNo
let items = record.operaConfirmationNo.split(",");
for(let i =0;i<items.length;i++){
let item={};
let rowData = items[i];
if(rowData != ""){
let property = rowData.split(';')[0];
let confNo = rowData.split(';')[1];
if(property!=="" && confNo !=="")
{
item.hotelName = property;
item.confNo = confNo;
paramData.items.push(item);
}
}
}
}
return paramData;
}
},
getPercentFormat() {
return function(val) {
if(val){
return Math.trunc((val * 100)) + "%";
}else{
return "0%"
}
}
},
getOtherDescription(){
return function(descriptions){
let resList = [];
if(descriptions!==undefined && descriptions!==null){
for(let i=0;i<descriptions.length;i++){
let arrDesc = descriptions[i].split("#CRMLINE#");
if(arrDesc.length>0){
for(let j=0;j<arrDesc.length;j++){
if(arrDesc[j]!=""){
resList.push(arrDesc[j]);
}
}
}
}
}
return resList;
}
},
getEmojiDescription() {
return function(descriptions) {
return descriptions.replace(/&#([0-9A-Fa-f]+)/g, function(match, code) {
if (/[A-Fa-f]/.test(code)) {
return String.fromCodePoint(parseInt(code, 16));
} else {
return String.fromCodePoint(parseInt(code, 10));
}
});
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../../static/css/todo.scss';
@import '../../static/css/custom.scss';
</style>