first commit
This commit is contained in:
@@ -0,0 +1,597 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<simple-watermark ref="watermark"></simple-watermark>
|
||||
<!-- #endif -->
|
||||
<mgmHeader ref="headerRef" />
|
||||
<view class="hz-page">
|
||||
<u-sticky customStyle="border-bottom:0.5px solid #f0f0f0;" bgColor="#fff">
|
||||
<u-tabs :scrollable="false" :list="tabList" lineWidth="50" @change="changeTopTab" itemStyle="width:50%; height: 40px"
|
||||
:activeStyle="{color: '#C39A4B'}" line-color="#C39A4B" ></u-tabs>
|
||||
</u-sticky>
|
||||
<!-- 搜索栏 -->
|
||||
<view class="hz-spacing hz-mr-t-20 hz-flex-row">
|
||||
<u-search :placeholder="searchHolder" v-model="searchInputStr" :showAction="false" bgColor="#ffffff"
|
||||
borderColor="gray" style="padding-right: 8px;" @search="toSearch()"></u-search>
|
||||
<view class="">
|
||||
<u-icon size="28px" @click="openFilter()" :name="filterIconPath" style="margin-top: 3px;"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 -->
|
||||
<view class="hz-mr-t-30">
|
||||
<uni-card
|
||||
style="padding:12px 12px 0px 12px;margin-bottom:24rpx;position:relative;box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 0px 0px;" class="hz-mr-t-20 hz-font-base">
|
||||
<!-- 卡片上方视图 -->
|
||||
<view class="hz-flex-row hz-mr-b-20 " style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 10px;">
|
||||
<view>
|
||||
<u-checkbox-group
|
||||
v-model="checkboxValue"
|
||||
placement="column"
|
||||
@change="checkboxChange"
|
||||
>
|
||||
<u-checkbox
|
||||
labelColor="#000000"
|
||||
activeColor="#C39A4B"
|
||||
v-for="(item, index) in checkboxList"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.id"
|
||||
>
|
||||
</u-checkbox>
|
||||
</u-checkbox-group>
|
||||
</view>
|
||||
<!-- 卡片日期 -->
|
||||
<span class="hz-font-sm" style="color:#999;margin-left: auto;">
|
||||
2025-12-30 18:35
|
||||
</span>
|
||||
</view>
|
||||
<!-- 卡片 Player Info 视图 -->
|
||||
<view class="hz-flex-row" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 10px;">
|
||||
<!-- 卡片左侧信息 -->
|
||||
<view class="hz-font-color-black" style="line-height:160%; flex: 1; overflow: hidden; min-width: 0;">
|
||||
<!-- 用户信息 -->
|
||||
<view class="hz-font-md hz-mr-b-20" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
11001960 / Chan, Tai Man / Supreme
|
||||
</view>
|
||||
<!-- Gaming Data -->
|
||||
<view class="hz-mr-b-20 hz-flex-row">
|
||||
<view>
|
||||
<view>C/I:2025-01-01</view>
|
||||
<view>C/I:2025-01-03</view>
|
||||
</view>
|
||||
<view style="margin-left: auto;">
|
||||
<view>MGM Macau</view>
|
||||
<view>GR,1Room</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row">
|
||||
<view>
|
||||
<view>Current Trip Theo</view>
|
||||
<view>Last 2 Days Theo</view>
|
||||
</view>
|
||||
<view style="margin-left: auto;">
|
||||
<view style="margin-left: auto;">900,732</view>
|
||||
<view style="margin-left: auto;">110,227</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="">R3 Theo /TPD /Actual win</view>
|
||||
<view class="">3,456,789/456,785/-479,887</view>
|
||||
<view class="">R6 Theo /TPD /Actual win</view>
|
||||
<view class="">3,456,789/456,785/-479,887</view>
|
||||
</view>
|
||||
<!-- 卡片右侧按钮 -->
|
||||
<view v-if="this.currentIndex===0" class="" style="width: 70px; flex-shrink: 0;">
|
||||
<view class="hz-bg-primary hz-font-color-white roomCount hz-mr-t-30" style="text-align: center;" @click="handleRoomCountClick">Room Count</view>
|
||||
</view>
|
||||
<view v-else class="" style="width: 70px; flex-shrink: 0;">
|
||||
<view class="roomCount hz-mr-t-30 hz-font-color-black"
|
||||
style="border: 0.5px #C39A4B solid; text-align: center;">Approved</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 booking 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Continuous / Overlap Booking(C/I to C/O)
|
||||
</view>
|
||||
<view class="">
|
||||
02 Jan to 04 Jan MGM C-S2K | Conf#fzfsesr1
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Waitlist 视图 -->
|
||||
<view v-show="currentIndex===0" class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Waitlist
|
||||
</view>
|
||||
<view class="">
|
||||
02 Jan to 03 Jan MGM-GR
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Remark 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Remarks
|
||||
</view>
|
||||
<view>
|
||||
Wynn big guest
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Sharer 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Sharer
|
||||
</view>
|
||||
<view>
|
||||
11001983 Corso Wong
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Request Reason 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="margin-bottom: 5px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Request Reason
|
||||
</view>
|
||||
<view>
|
||||
HP
|
||||
</view>
|
||||
</view>
|
||||
<!-- 按钮视图 -->
|
||||
<view v-show="currentIndex===0" class="hz-flex-row hz-font-color-primary" style="border-top:0.5px solid #a3a3a3;">
|
||||
<view class="actionButton" style="border-bottom-left-radius: 8px;" @click="handleApprovalClick">Approval</view>
|
||||
<view class="actionButton" style="border-left: 0.5px solid #a3a3a3; border-right: 0.5px solid #a3a3a3;" @click="handleRejectClick">Reject</view>
|
||||
<view class="actionButton" style="border-bottom-right-radius: 8px;" @click="handleDelegateClick">Delegate</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
<uni-card
|
||||
style="padding:12px 12px 0px 12px;margin-bottom:24rpx;position:relative;box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 0px 0px;" class="hz-mr-t-20 hz-font-base">
|
||||
<!-- 卡片上方视图 -->
|
||||
<view class="hz-flex-row hz-mr-b-20 " style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 10px;">
|
||||
<view>
|
||||
<u-checkbox-group
|
||||
v-model="checkboxValue"
|
||||
placement="column"
|
||||
@change="checkboxChange"
|
||||
>
|
||||
<u-checkbox
|
||||
labelColor="#000000"
|
||||
activeColor="#C39A4B"
|
||||
v-for="(item, index) in checkboxList"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.id"
|
||||
>
|
||||
</u-checkbox>
|
||||
</u-checkbox-group>
|
||||
</view>
|
||||
<!-- 卡片日期 -->
|
||||
<span class="hz-font-sm" style="color:#999;margin-left: auto;">
|
||||
2025-12-30 18:35
|
||||
</span>
|
||||
</view>
|
||||
<!-- 卡片 Player Info 视图 -->
|
||||
<view class="hz-flex-row" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 10px;">
|
||||
<!-- 卡片左侧信息 -->
|
||||
<view class="hz-font-color-black" style="line-height:160%; flex: 1; overflow: hidden; min-width: 0;">
|
||||
<!-- 用户信息 -->
|
||||
<view class="hz-font-md hz-mr-b-20" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
11001960 / Chan, Tai Man / Supreme
|
||||
</view>
|
||||
<!-- Gaming Data -->
|
||||
<view class="hz-mr-b-20 hz-flex-row">
|
||||
<view>
|
||||
<view>C/I:2025-01-01</view>
|
||||
<view>C/I:2025-01-03</view>
|
||||
</view>
|
||||
<view style="margin-left: auto;">
|
||||
<view>MGM Macau</view>
|
||||
<view>GR,1Room</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row">
|
||||
<view>
|
||||
<view>Current Trip Theo</view>
|
||||
<view>Last 2 Days Theo</view>
|
||||
</view>
|
||||
<view style="margin-left: auto;">
|
||||
<view style="margin-left: auto;">900,732</view>
|
||||
<view style="margin-left: auto;">110,227</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="">R3 Theo /TPD /Actual win</view>
|
||||
<view class="">3,456,789/456,785/-479,887</view>
|
||||
<view class="">R6 Theo /TPD /Actual win</view>
|
||||
<view class="">3,456,789/456,785/-479,887</view>
|
||||
</view>
|
||||
<!-- 卡片右侧按钮 -->
|
||||
<view v-if="this.currentIndex===0" class="" style="width: 70px; flex-shrink: 0;">
|
||||
<view class="hz-bg-primary hz-font-color-white roomCount hz-mr-t-30" style="text-align: center;" @click="handleRoomCountClick">Room Count</view>
|
||||
</view>
|
||||
<view v-else class="" style="width: 70px; flex-shrink: 0;">
|
||||
<view class="roomCount hz-mr-t-30 hz-font-color-black"
|
||||
style="border: 0.5px #C39A4B solid; text-align: center;">Approved</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 booking 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Continuous / Overlap Booking(C/I to C/O)
|
||||
</view>
|
||||
<view class="">
|
||||
02 Jan to 04 Jan MGM C-S2K | Conf#fzfsesr1
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Waitlist 视图 -->
|
||||
<view v-show="currentIndex===0" class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Waitlist
|
||||
</view>
|
||||
<view class="">
|
||||
02 Jan to 03 Jan MGM-GR
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Remark 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Remarks
|
||||
</view>
|
||||
<view>
|
||||
Wynn big guest
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Sharer 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="border-bottom:0.5px solid #a3a3a3;padding-bottom: 6px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Sharer
|
||||
</view>
|
||||
<view>
|
||||
11001983 Corso Wong
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 Request Reason 视图 -->
|
||||
<view class="hz-font-sm hz-font-color-black" style="margin-bottom: 5px;">
|
||||
<view style="font-weight: bolder;">
|
||||
Request Reason
|
||||
</view>
|
||||
<view>
|
||||
HP
|
||||
</view>
|
||||
</view>
|
||||
<!-- 按钮视图 -->
|
||||
<view v-show="currentIndex===0" class="hz-flex-row hz-font-color-primary" style="border-top:0.5px solid #a3a3a3;">
|
||||
<view class="actionButton" style="border-bottom-left-radius: 8px;" @click="handleApprovalClick">Approval</view>
|
||||
<view class="actionButton" style="border-left: 0.5px solid #a3a3a3; border-right: 0.5px solid #a3a3a3;" @click="handleRejectClick">Reject</view>
|
||||
<view class="actionButton" style="border-bottom-right-radius: 8px;" @click="handleDelegateClick">Delegate</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 点击按钮弹窗内容 -->
|
||||
<u-popup
|
||||
:safeAreaInsetBottom="true"
|
||||
:safeAreaInsetTop="true"
|
||||
:mode="'center'"
|
||||
:round="12"
|
||||
:show="showMsgBox"
|
||||
customStyle="width:94%; padding-top: 30px"
|
||||
:closeable="!showDirBtn"
|
||||
@close="closePopup()"
|
||||
>
|
||||
<view v-if="confirmType!=='DELEGATE'">
|
||||
<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-xl hz-font-bold hz-text-center" style="margin-top:20px;margin-bottom: 20px;margin-left: 15px;margin-right: 15px;white-space:pre-wrap;">
|
||||
<rich-text v-html="popMsgStr" style="line-height:26px;"></rich-text>
|
||||
</view>
|
||||
<view @click="callConfirmFunction()" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 15px;">
|
||||
{{$t("common.confirm").toUpperCase()}}
|
||||
</view>
|
||||
<view @click="closePopup()" class="hz-btn hz-font-color-primary hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 30px;background-color: white;border: 0.5px solid;">
|
||||
{{$t("common.cancel").toUpperCase()}}
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="hz-flex-row" style="margin: 30px 20px;">
|
||||
<view class="hz-font-bold" style="align-self: center;margin-right: 10px;">
|
||||
Delegate to
|
||||
</view>
|
||||
<view style="flex: 1;">
|
||||
<view @click="showPicker = true" style="border: 0.5px solid #a3a3a3; padding: 8px; border-radius: 4px;">
|
||||
{{ selectedDelegate || 'Select approver' }}
|
||||
</view>
|
||||
<u-picker :show="showPicker" :columns="delegateColumns" @confirm="handlePickerConfirm" @cancel="showPicker = false" :cancelText = 'cancelStr'
|
||||
:confirmText = 'okStr' confirmColor = '#C39A4B' :closeOnClickOverlay = "true"></u-picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-mr-b-30">
|
||||
<view @click="confirmDelegate()" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" style="width: 90%;margin: 0 auto;margin-bottom: 15px;">
|
||||
{{$t("common.confirm").toUpperCase()}}
|
||||
</view>
|
||||
<view @click="closePopup()" class="hz-btn hz-font-color-primary hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 30px;background-color: white;border: 0.5px solid;">
|
||||
{{$t("common.cancel").toUpperCase()}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<u-calendar closeOnClickOverlay :confirmText="confirmText" :confirmDisabledText="confirmText" color="#C39A4B"
|
||||
title="" :startText="startText" :endText="endText" :show="showCalendar" :allowSameDay="true"
|
||||
mode="range" @close="cancelDate" @confirm="confirmDate" :showMark="false">
|
||||
</u-calendar>
|
||||
|
||||
<!-- 悬浮栏 - 显示选中的记录数量 -->
|
||||
<view v-if="checkboxValue.length > 0" class="floating-bar">
|
||||
<view class="floating-content">
|
||||
<text class="selected-count">{{ checkboxValue.length }} selected</text>
|
||||
<view class="floating-actions">
|
||||
<view @click="handleBatchApprove" class="action-btn approve-btn">Approve</view>
|
||||
<view @click="handleBatchReject" class="action-btn reject-btn">Reject</view>
|
||||
</view>
|
||||
</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
|
||||
export default {
|
||||
components: {
|
||||
mgmHeader, // 注册组件
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: "Approval",
|
||||
currentIndex: 0,
|
||||
sliderPosition: 0,
|
||||
filterIconPath:"../../static/images/filter_inactive.png",
|
||||
cancelStr:this.$t('common.cancel'),
|
||||
okStr:this.$t('common.ok'),
|
||||
searchHolder:this.$t('approval.searchStr'),
|
||||
searchInputStr:'',
|
||||
keyword:'',
|
||||
checkboxValue:[],
|
||||
confirmType:'',
|
||||
userData:'',
|
||||
showMsgBox:false,
|
||||
showDirBtn:false,
|
||||
iconPath:'',
|
||||
popMsgStr:'',
|
||||
showPicker:false,
|
||||
confirmText:this.$t('common.confirm'),
|
||||
startText:this.$t('common.start'),
|
||||
endText:this.$t('common.end'),
|
||||
showCalendar:false,
|
||||
delegateColumns:[
|
||||
[
|
||||
{text: 'Mooney', value: '105868'},
|
||||
{text: 'Kelly', value: '130211'},
|
||||
{text: 'Eva', value: '100712'}
|
||||
]
|
||||
],
|
||||
selectedDelegate:'',
|
||||
checkboxList: [{
|
||||
name: 'Request from Annie Chan',
|
||||
disabled: false,
|
||||
id:1
|
||||
}
|
||||
],
|
||||
tabList: [{
|
||||
name: this.$t('approval.pendingApproval'),
|
||||
}, {
|
||||
name: this.$t('approval.allRequest'),
|
||||
}]
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
onReady() {
|
||||
// 页面首次渲染完成后,延迟触发水印更新
|
||||
setTimeout(() => {
|
||||
const watermarkStore = require('@/store/watermark.js');
|
||||
if (watermarkStore && watermarkStore.updateWatermark) {
|
||||
watermarkStore.updateWatermark(true);
|
||||
}
|
||||
}, 1200);
|
||||
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
if (this.userData !== null && this.userData !== undefined){
|
||||
this.showTabbarByPermission(this.userData);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
click(item) {
|
||||
console.log('item', item);
|
||||
},
|
||||
openFilter() {
|
||||
this.showCalendar = true;
|
||||
},
|
||||
toSearch(){
|
||||
console.log(this.searchInputStr);
|
||||
console.log("toSearch");
|
||||
},
|
||||
checkboxChange(n) {
|
||||
console.log('change', n);
|
||||
},
|
||||
handleRoomCountClick() {
|
||||
this.navTo('/pages/roomCount/roomCount',0,false)
|
||||
},
|
||||
handleApprovalClick() {
|
||||
this.navTo('/pages/playerDetail/playerDetail',0,false)
|
||||
},
|
||||
handleRejectClick() {
|
||||
this.iconPath = '../../static/images/ico_err.png';
|
||||
this.popMsgStr = this.$t("approval.submitReject") ;
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.confirmType = "REJECT";
|
||||
},
|
||||
handleDelegateClick() {
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.confirmType = "DELEGATE";
|
||||
},
|
||||
handlePickerConfirm(e) {
|
||||
const selectedItem = e.value[0];
|
||||
|
||||
if (selectedItem) {
|
||||
this.selectedDelegate = selectedItem.text;
|
||||
}
|
||||
this.showPicker = false;
|
||||
},
|
||||
changeTopTab(index) {
|
||||
this.currentIndex = index.index;
|
||||
},
|
||||
confirmApproval(){
|
||||
console.log("Approval");
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
confirmReject(){
|
||||
console.log("Reject");
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
confirmDelegate(){
|
||||
console.log("Delegate");
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
closePopup(){
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
handleBatchApprove(){
|
||||
console.log('Batch approve:', this.checkboxValue);
|
||||
this.iconPath = '../../static/images/ico_warn.png';
|
||||
this.popMsgStr = this.$t("approval.submitBatchApproval") ;
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.confirmType = "BATCHAPPROVAL";
|
||||
},
|
||||
handleBatchReject(){
|
||||
console.log('Batch reject:', this.checkboxValue);
|
||||
this.iconPath = '../../static/images/ico_err.png';
|
||||
this.popMsgStr = this.$t("approval.submitBatchReject") ;
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.confirmType = "BATCHREJECT";
|
||||
},
|
||||
cancelDate(){
|
||||
this.showCalendar = false;
|
||||
},
|
||||
confirmDate(){
|
||||
this.showCalendar = false;
|
||||
},
|
||||
confirmBatchApproval(){
|
||||
console.log("batch app");
|
||||
this.showMsgBox = false;
|
||||
this.checkboxValue = [];
|
||||
},
|
||||
confirmBatchReject(){
|
||||
console.log("batch rej");
|
||||
this.showMsgBox = false;
|
||||
this.checkboxValue = [];
|
||||
},
|
||||
callConfirmFunction(){
|
||||
if(this.confirmType === "REJECT"){
|
||||
this.confirmReject();
|
||||
}
|
||||
if(this.confirmType === "DELEGATE"){
|
||||
this.confirmDelegate()
|
||||
}
|
||||
if(this.confirmType === "BATCHREJECT"){
|
||||
this.confirmBatchReject();
|
||||
}
|
||||
if(this.confirmType ==="BATCHAPPROVAL"){
|
||||
this.confirmBatchApproval();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../../static/css/custom.scss';
|
||||
.roomCount{
|
||||
border-radius: 20px;
|
||||
font-size: 10px;
|
||||
padding: 3px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.actionButton{
|
||||
width: 33%;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.actionButton:active{
|
||||
background-color: #cccccc;
|
||||
}
|
||||
|
||||
.border-bt-sld{
|
||||
border-bottom:0.5px;
|
||||
color: #a3a3a3;
|
||||
padding-bottom: 10px
|
||||
}
|
||||
|
||||
.floating-bar{
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
|
||||
z-index: 999;
|
||||
padding: 12px 16px;
|
||||
border-top: 0.5px solid #a3a3a3;
|
||||
}
|
||||
|
||||
.floating-content{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.selected-count{
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.floating-actions{
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.action-btn{
|
||||
padding: 8px 20px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.approve-btn{
|
||||
background-color: #C39A4B;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.reject-btn{
|
||||
background-color: #C39A4B;
|
||||
color: #ffffff;
|
||||
}
|
||||
::v-deep .uni-card {
|
||||
margin: 10px;
|
||||
padding: 0 8px;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
flex: 1;
|
||||
}
|
||||
::v-deep .uni-card--border {
|
||||
border: 0.5px solid #ccc;
|
||||
}
|
||||
::v-deep .uni-card--shadow {
|
||||
position: relative;
|
||||
box-shadow: 0 0px 0px 0px rgba(165, 165, 165, 0.2);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<web-view :src="url"></web-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
//url:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&client_id=b4ba794c-cd0d-4033-924e-ace80b93d045&redirect_uri=https://hostcrmapp.mgm.mo/sso_callback/login&scope=openid%20profile%20email&response_mode=query",
|
||||
//url:"https://adserver.willtechmacau.com/adfs/oauth2/authorize?response_type=code&client_id=0fd2d7dd-35f5-47b5-a1e2-edc13e12a5cd&redirect_uri=https://hostcrmapp.mgm.mo/sso_callback/login&scope=openid&state=STATE",
|
||||
url:"https://adfs.mgm.mo/adfs/ls/IdpInitiatedSignOn?loginToRp="+encodeURIComponent('mgm_mobilecrm_app'),
|
||||
intervalId:null,
|
||||
newUrl:'',
|
||||
siteData:null
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.url) {
|
||||
this.url = options.url;
|
||||
}
|
||||
|
||||
this.listenUrl()
|
||||
},
|
||||
onShow() {
|
||||
//console.log("azureLogin.vue:onShow()");
|
||||
/*setTimeout(()=> {
|
||||
this.checkArguments();
|
||||
}, 10000);*/
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
},
|
||||
methods: {
|
||||
listenUrl() {
|
||||
var that = this;
|
||||
var count = 0;
|
||||
this.intervalId = setInterval(() => {
|
||||
var currentUrl = that.getCurrentUrl();
|
||||
that.newUrl = currentUrl;
|
||||
var code = that.getCurrentQueryString(currentUrl, 'SAMLResponse');
|
||||
//var code = that.getCurrentQueryString(currentUrl, 'code');
|
||||
|
||||
//uni.$u.toast(that.newUrl,10000);
|
||||
|
||||
//console.log('获取到的code:', code)
|
||||
if(currentUrl.indexOf('/login')!=-1){
|
||||
if (code){
|
||||
clearInterval(that.intervalId);
|
||||
uni.redirectTo({
|
||||
url:'/pages/login/login?code='+encodeURIComponent(code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}, 1000);
|
||||
},
|
||||
getCurrentQueryString(url, name) {
|
||||
var queryString = url.substring(url.indexOf('?'));
|
||||
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
|
||||
var r = queryString.substr(1).match(reg);
|
||||
if (r != null) {
|
||||
return unescape(r[2]);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getCurrentUrl(){
|
||||
var pages = getCurrentPages();
|
||||
var page = pages[pages.length - 1];
|
||||
var currentWebview = page.$getAppWebview();
|
||||
var url = currentWebview.children()[0].getURL();
|
||||
console.log("=======当前地址======", url);
|
||||
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<web-view :src="url"></web-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
//url:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&client_id=b4ba794c-cd0d-4033-924e-ace80b93d045&redirect_uri=https://hostcrmapp.mgm.mo/sso_callback/login&scope=openid%20profile%20email&response_mode=query",
|
||||
//url:"https://adserver.willtechmacau.com/adfs/ls/?wa=wsignout1.0&wtrealm=hostcrmapp&wreply=https://hostcrmapp.mgm.mo/sso_callback/logout",
|
||||
url:"https://adfs.mgm.mo/adfs/ls/?wa=wsignout1.0&wtrealm=mgm_mobilecrm_app&wreply=https://hostcrmapp.mgm.mo/sso_callback/logout",
|
||||
//url:"",
|
||||
intervalId:null,
|
||||
newUrl:'',
|
||||
siteData:null
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.url) {
|
||||
this.url = options.url;
|
||||
}
|
||||
|
||||
this.listenUrl()
|
||||
},
|
||||
onShow() {
|
||||
//console.log("azureLogin.vue:onShow()");
|
||||
/*setTimeout(()=> {
|
||||
this.checkArguments();
|
||||
}, 10000);*/
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
},
|
||||
methods: {
|
||||
listenUrl() {
|
||||
var that = this;
|
||||
var count = 0;
|
||||
this.intervalId = setInterval(() => {
|
||||
var currentUrl = that.getCurrentUrl();
|
||||
that.newUrl = currentUrl;
|
||||
//var code = that.getCurrentQueryString(currentUrl, 'SAMLResponse');
|
||||
|
||||
//uni.$u.toast(that.newUrl,10000);
|
||||
|
||||
//console.log('获取到的code:', code)
|
||||
if(currentUrl.indexOf('/logout')!=-1){
|
||||
clearInterval(that.intervalId);
|
||||
//uni.removeStorageSync("adfs_cookie");
|
||||
uni.removeStorageSync("userData");
|
||||
uni.removeStorageSync("token");
|
||||
uni.removeStorageSync("idToken");
|
||||
uni.removeStorageSync("clientId");
|
||||
uni.redirectTo({
|
||||
url:'/pages/login/login'
|
||||
});
|
||||
}
|
||||
|
||||
}, 1000);
|
||||
},
|
||||
getCurrentQueryString(url, name) {
|
||||
var queryString = url.substring(url.indexOf('?'));
|
||||
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
|
||||
var r = queryString.substr(1).match(reg);
|
||||
if (r != null) {
|
||||
return unescape(r[2]);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getCurrentUrl(){
|
||||
var pages = getCurrentPages();
|
||||
var page = pages[pages.length - 1];
|
||||
var currentWebview = page.$getAppWebview();
|
||||
var url = currentWebview.children()[0].getURL();
|
||||
console.log("=======当前地址======", url);
|
||||
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,311 @@
|
||||
<template>
|
||||
<view>
|
||||
<view>
|
||||
<mgmHeader ref="headerRef" />
|
||||
<view v-if="showDashboardView">
|
||||
<view class="hz-font-bolder hz-font-l hz-font-color-black hz-text-right"
|
||||
style="margin-top:36rpx;margin-right:36rpx;">
|
||||
{{$t('dashboard.dataAsOf')}} {{dataAsOf}}
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-font-color-black hz-text-left"
|
||||
style="margin-top:36rpx;margin-left:36rpx;">
|
||||
{{$t('dashboard.achievement')}}
|
||||
|
||||
</view>
|
||||
<uni-card>
|
||||
<view v-for="(record,index) in dashboardData" :key="index" v-show="getShowAchievement(record)"
|
||||
style="margin-top:12px;">
|
||||
<view class="hz-flex-row">
|
||||
<view style="width:37%">
|
||||
<view class="hz-font-color-dark hz-font-base">{{record.itemName}}</view>
|
||||
</view>
|
||||
<view v-if="record.targetValue!==0&&record.targetValue!==null&&record.targetValue!==undefined" class="hz-flex-row"
|
||||
style="width:63%;justify-content: flex-end;align-items: center;align-items: center;">
|
||||
<view class="hz-font-color-dark hz-font-12px" style="white-space: nowrap;">{{getTargetValue(record)}}</view>
|
||||
<view class="hz-card-level" style="margin-left:4px;">LV{{record.level}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="margin-top:3px;" v-if="record.targetValue!==0&&record.targetValue!==null&&record.targetValue!==undefined">
|
||||
<u-line-progress :percentage="getPercentValue(record)" activeColor="#C39A4B"
|
||||
height="16"></u-line-progress>
|
||||
</view>
|
||||
<view style="margin-top:3px;" v-else>
|
||||
<u-line-progress :percentage="0" activeColor="#C39A4B" height="16"><span
|
||||
style="font-size:10px;padding-left: 10px;">{{getCurrentValue(record)}}</span></u-line-progress>
|
||||
</view>
|
||||
</view>
|
||||
<view v-show="userSegment =='IM'">
|
||||
<view class="im-view-outside">
|
||||
<view class="im-view-inside" style="margin-right:5px;">
|
||||
<view class="im-text-gold">{{formatNumber(MFValue)}}</view>
|
||||
<view class="hz-font-color-dark hz-font-base">MF Turnover</view>
|
||||
</view>
|
||||
<view class="im-view-inside" style="margin-left:5px;">
|
||||
<view class="im-text-gold">{{formatNumber(IMValue)}}</view>
|
||||
<view class="hz-font-color-dark hz-font-base">IM Turnover</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="im-view-outside">
|
||||
<view class="im-view-inside" style="margin-right:5px;">
|
||||
<view class="im-text-gold">{{formatNumber(NFROValue)}}</view>
|
||||
<view class="hz-font-color-dark hz-font-base">NFRO Turnover</view>
|
||||
</view>
|
||||
<view class="im-view-inside" style="margin-left:5px;">
|
||||
<view class="im-text-gold">{{formatNumber(MRIValue)}}</view>
|
||||
<view class="hz-font-color-dark hz-font -base">MRI Turnover</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
<view class="hz-font-bolder hz-font-xl hz-font-color-black hz-text-left"
|
||||
style="margin-top:36rpx;margin-left:36rpx;">
|
||||
{{$t('dashboard.kpi')}}
|
||||
</view>
|
||||
<uni-card>
|
||||
<view v-for="(record,index) in dashboardData" :key="index" v-show="getShowKPI(record)"
|
||||
style="margin-top:12px;">
|
||||
<view class="hz-flex-row">
|
||||
<view style="width:85%">
|
||||
<view class="hz-font-color-dark hz-font-base">{{record.itemName}}</view>
|
||||
</view>
|
||||
<view class="hz-flex-row"
|
||||
style="width:15%;justify-content: flex-end;align-items: center;align-items: center;">
|
||||
<view class="hz-font-color-dark hz-font-12px">{{getTargetValue(record)}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="margin-top:3px;">
|
||||
<u-line-progress :percentage="getPercentValue(record)" activeColor="#C39A4B"
|
||||
height="16"><span
|
||||
style="font-size:10px;margin-right:6px;padding-left: 10px;">{{percentFormat(record.currentValue)}}</span></u-line-progress>
|
||||
</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
<u-modal :content="msgStr" :show="showMsg" :confirmText="okText" :showCancelButton="false"
|
||||
closeOnClickOverlay @confirm="showMsg=false" confirmColor="#C39A4B"
|
||||
@close="showMsg=false"></u-modal>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!showDashboardView">
|
||||
<view class="hz-flex-row" style="justify-content: center;margin-top:80px;">
|
||||
<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' // 引入头部组件
|
||||
import {
|
||||
getTodoDashboard
|
||||
} from '../../api/todoApi';
|
||||
import {
|
||||
logout
|
||||
} from '../../api/commonApi';
|
||||
import {
|
||||
formatDate
|
||||
} from '../../common/stringUtils';
|
||||
export default {
|
||||
components: {
|
||||
mgmHeader // 注册组件
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
deviceData: null,
|
||||
siteData: null,
|
||||
msgStr: null,
|
||||
showMsg: false,
|
||||
okText: this.$t("common.ok"),
|
||||
dataNull:this.$t("common.dataNotFound"),
|
||||
userData: null,
|
||||
dashboardData: [],
|
||||
dataAsOf:"",
|
||||
hasTargetValue:false,
|
||||
MFValue: '0',
|
||||
NFROValue: '0',
|
||||
IMValue: '0',
|
||||
MRIValue: '0',
|
||||
showDashboardView: false,
|
||||
userSegment: null
|
||||
}
|
||||
},
|
||||
onLoad(opt) {
|
||||
// 初始化界面
|
||||
this.initUI();
|
||||
},
|
||||
onShow() {
|
||||
this.playerData = uni.getStorageSync("playerData");
|
||||
this.getTodoDashboardByuserId();
|
||||
this.$nextTick(() => {
|
||||
const header = this.$refs.headerRef;
|
||||
if(header) {
|
||||
header.updateUserData();
|
||||
}
|
||||
});
|
||||
if (this.userData !== null && this.userData !== undefined)
|
||||
this.showTabbarByPermission(this.userData);
|
||||
},
|
||||
|
||||
methods: {
|
||||
formatNumber(num) {
|
||||
return num?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") || "0";
|
||||
},
|
||||
async getTodoDashboardByuserId() {
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
let requestBody = "";
|
||||
try {
|
||||
let params = {};
|
||||
requestBody = JSON.stringify(params);
|
||||
const res = await getTodoDashboard(params);
|
||||
if (res.data != null && res.success == true) {
|
||||
if(Array.isArray(res.data.records) && res.data.records.length > 0){
|
||||
this.dashboardData = res.data.records;
|
||||
this.showDashboardView = true;
|
||||
this.userSegment = this.dashboardData[0].userSegment;
|
||||
this.hasTargetValue = this.dashboardData[0].targetValue !== null ||this.dashboardData[0].targetValue !== undefined ? true :false;
|
||||
}
|
||||
if(this.userSegment == 'IM' && this.userSegment !== null){
|
||||
for (let i = 0; i < this.dashboardData.length; i++) {
|
||||
if (this.dashboardData[i].itemName == "MF Turnover") this.MFValue = this.dashboardData[i]
|
||||
.currentValue;
|
||||
if (this.dashboardData[i].itemName == "IM Turnover") this.IMValue = this.dashboardData[i]
|
||||
.currentValue;
|
||||
if (this.dashboardData[i].itemName == "NFRO Turnover") this.NFROValue = this.dashboardData[i]
|
||||
.currentValue;
|
||||
if (this.dashboardData[i].itemName == "MRI Turnover") this.MRIValue = this.dashboardData[i]
|
||||
.currentValue;
|
||||
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.dashboardData.length; i++) {
|
||||
if (this.dashboardData[i].type == "DataAsOf"){
|
||||
this.dataAsOf = this.dashboardData[i].itemName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.showDashboardView = false;
|
||||
if(res.errorCode == 'NO_PERMISSION'){
|
||||
this.dataNull = this.$t("todo.noPermission");
|
||||
}else if(res.errorCode == 'INVOKE_TODODASHBOARD_API_ERROR'){
|
||||
this.dataNull = this.$t("todo.invokeError");
|
||||
}else {
|
||||
if(res.errorCode.toUpperCase().indexOf('NO RECORD') != -1){
|
||||
this.dataNull = this.$t("common.noRecord");
|
||||
}else{
|
||||
this.dataNull = this.$t("todo.returnError");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
initUI() {
|
||||
this.deviceData = uni.getStorageSync("deviceData");
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getShowAchievement() {
|
||||
return function(record) {
|
||||
if (record.type == "Achievement" && record.itemName !=="MF Turnover" && record.itemName !=="IM Turnover"
|
||||
&& record.itemName !=="NFRO Turnover" && record.itemName !=="MRI Turnover") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
},
|
||||
getShowKPI() {
|
||||
return function(record) {
|
||||
if (record.type == "KPI") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
},
|
||||
getTargetValue() {
|
||||
return function(record) {
|
||||
if (record.targetValue != null && record.currentValue != null && record.targetValue != 0) {
|
||||
if (record.type == "KPI") {
|
||||
if (record.targetValue < 1) {
|
||||
return (record.targetValue * 100) + "%";
|
||||
} else {
|
||||
return this.formatNumber(record.targetValue);
|
||||
}
|
||||
} else {
|
||||
const targetShow = this.formatNumber(record.currentValue) + " / " + this.formatNumber(
|
||||
record.targetValue);
|
||||
return targetShow;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
},
|
||||
getCurrentValue(){
|
||||
return function(record){
|
||||
let result = this.formatNumber(parseInt(record.currentValue));
|
||||
return result;
|
||||
}
|
||||
},
|
||||
getPercentValue() {
|
||||
return function(record) {
|
||||
if (record.targetValue != null && record.currentValue != null && record.targetValue != 0) {
|
||||
if ((Math.floor(record.currentValue / record.targetValue * 100)) <= 100) {
|
||||
return Math.floor(record.currentValue / record.targetValue * 100);
|
||||
} else {
|
||||
return 100;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
percentFormat() {
|
||||
return function(val) {
|
||||
if (val < 1) {
|
||||
return Math.floor((val * 100) )+"%";
|
||||
} else {
|
||||
return this.formatNumber(Math.floor(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.im-view-outside {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 70px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.im-view-inside {
|
||||
width: 50%;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 8px;
|
||||
height: 95%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.im-text-gold {
|
||||
color: #cfa34f;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar
|
||||
:safeAreaInsetTop="true"
|
||||
:placeholder="true"
|
||||
:title="title"
|
||||
:fixed="true"
|
||||
:autoBack="false"
|
||||
leftIconColor="#C39A4B"
|
||||
bgColor="#C39A4B"
|
||||
titleStyle="font-weight:bold;color:#ffffff;"
|
||||
>
|
||||
</u-navbar>
|
||||
<view class="hz-flex-row" style="justify-content: center;margin-top:40px;">
|
||||
<image src="/static/images/err.png" style="width:80px;height:80px;"></image>
|
||||
</view>
|
||||
<view class="hz-flex-row hz-font-bolder hz-font-md hz-text-center" style="margin:20px;">
|
||||
{{message}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 界面变量
|
||||
userName:'',
|
||||
title: this.$t("common.jailBreakTitle"),
|
||||
message:this.$t("common.jailBreakMessage"),
|
||||
}
|
||||
},
|
||||
onLoad(prop) {
|
||||
},
|
||||
onShow(){
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
computed:{
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar
|
||||
:safeAreaInsetTop="true"
|
||||
:placeholder="true"
|
||||
:title="title"
|
||||
:fixed="true"
|
||||
:autoBack="false"
|
||||
leftIconColor="#C39A4B"
|
||||
bgColor="#C39A4B"
|
||||
titleStyle="font-weight:bold;color:#ffffff;"
|
||||
>
|
||||
<view
|
||||
@click="logout"
|
||||
style="margin-top:2px;margin-right:3px;"
|
||||
slot="right"
|
||||
>
|
||||
<image src="/static/images/ico_exit.png" style="width:24px;height:24px;"></image>
|
||||
</view>
|
||||
<view
|
||||
v-show="canViewApproval"
|
||||
@click="toNotification"
|
||||
style="margin-top:2px;margin-right:3px; position: relative"
|
||||
slot="left"
|
||||
>
|
||||
<image src="/static/images/160task01.png" style="width:24px;height:24px;"/>
|
||||
<u-badge :value="countAp" type="error" :offset="[-8, -8]" :show="countAp > 0" :absolute="true"></u-badge>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<view class="hz-text-center" style="margin-top:120rpx;">
|
||||
<image src="../../static/images/room_book.png" style="width:128rpx;height:128rpx;"></image>
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-primary">
|
||||
{{$t('hotel.roombooking')}}
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-dark" style="margin-top:160rpx;">
|
||||
{{$t('findPlayer.title')}}
|
||||
</view>
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<u--input
|
||||
v-model="searchPlayerId"
|
||||
:placeholder="playerIdStr"
|
||||
prefixIcon="search"
|
||||
prefixIconStyle="font-size: 26px;color:#C39A4B;"
|
||||
customStyle="border-radius:22px;"
|
||||
type="number"
|
||||
:clearable="true"
|
||||
:maxlength="8"
|
||||
></u--input>
|
||||
<view style="margin-top:30rpx;">
|
||||
<view @click="getProfileByPlayerId" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >{{$t("common.search").toUpperCase()}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-modal :content="msgStr" :show="showMsg" :confirmText="yesText" :showCancelButton="false" closeOnClickOverlay @confirm="confirmMsg" confirmColor="#C39A4B" @cancel="confirmMsg" @close="confirmMsg"></u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getApprovalCount } from '../../api/approvalApi.js';
|
||||
import {playerLookup} from '../../api/mgmApi.js'
|
||||
import mgmHeader from '@/components/header/header.vue'
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
mgmHeader // 注册组件
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 数据变量
|
||||
playerIdStr: this.$t("common.playerId"),
|
||||
searchPlayerId: '',
|
||||
userData:null,
|
||||
deviceData:null,
|
||||
siteData:null,
|
||||
countAp: '',
|
||||
// 定时器变量
|
||||
approvalCountTimer: null,
|
||||
// 页面激活态(避免残留定时器回调在非当前页继续请求)
|
||||
isFindPlayerActive: false,
|
||||
// 界面变量
|
||||
showMsg:false,
|
||||
title: '',
|
||||
msgStr:'',
|
||||
yesText:this.$t("common.ok"),
|
||||
canViewApproval:false
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化界面
|
||||
//uni.setLocale("en") //測試切換語言en or zh-Hant
|
||||
this.initUI();
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
},
|
||||
onShow() {
|
||||
this.isFindPlayerActive = true;
|
||||
this.getApporvalCount();
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
this.searchPlayerId = '';
|
||||
this.playerIdStr=this.$t("common.playerId");
|
||||
if(this.userData!==null && this.userData!==undefined){
|
||||
this.title = this.userData.userName+','+this.userData.userId;
|
||||
this.showTabbarByPermission(this.userData);
|
||||
}
|
||||
this.isLogin();
|
||||
this.$nextTick(() => {
|
||||
const header = this.$refs.headerRef;
|
||||
if(header) {
|
||||
header.updateUserData();
|
||||
}
|
||||
});
|
||||
|
||||
// 切回页面时,先停后启,避免存在残留定时器
|
||||
this.stopApprovalCountTimer();
|
||||
this.startApprovalCountTimer();
|
||||
if(this.userData.canViewApproval!==undefined && this.userData.canViewApproval==true) this.canViewApproval = true;
|
||||
},
|
||||
onHide() {
|
||||
this.isFindPlayerActive = false;
|
||||
// 切到其他页面时立即停止定时器,避免后台持续调用
|
||||
this.stopApprovalCountTimer();
|
||||
},
|
||||
onUnload() {
|
||||
this.isFindPlayerActive = false;
|
||||
// 页面销毁时兜底清理
|
||||
this.stopApprovalCountTimer();
|
||||
},
|
||||
onReady(){
|
||||
},
|
||||
methods: {
|
||||
startApprovalCountTimer() {
|
||||
if (!this.approvalCountTimer) {
|
||||
this.approvalCountTimer = setInterval(() => {
|
||||
// 双保险:非当前页不请求
|
||||
if (this.isFindPlayerActive) {
|
||||
this.getApporvalCount();
|
||||
}
|
||||
}, 30000); // 30秒
|
||||
}
|
||||
},
|
||||
stopApprovalCountTimer() {
|
||||
if (this.approvalCountTimer) {
|
||||
clearInterval(this.approvalCountTimer);
|
||||
this.approvalCountTimer = null;
|
||||
}
|
||||
},
|
||||
// 数据方法
|
||||
async getProfileByPlayerId(){
|
||||
if(!this.searchPlayerId){
|
||||
uni.$u.toast(this.$t("findPlayer.alert"));
|
||||
return;
|
||||
}
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
try{
|
||||
let params = {playerId:this.searchPlayerId,userId:this.userData.userId};
|
||||
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{
|
||||
this.msgStr = this.$t("findPlayer.noPermission");
|
||||
this.showMsg = true;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.msgStr = res.message;
|
||||
this.showMsg = true;
|
||||
}
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg,5000);
|
||||
var request = e.config!=undefined?JSON.stringify(e.config):"";
|
||||
var response = e.data!=undefined?JSON.stringify(e.data):"";
|
||||
await this.writeLog(this.userData.userId,"find_player","","[APP][findPlayer.vue][getProfileByPlayerId][Catch Exception]"+e.errMsg,request,response,1,false);
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
async getApporvalCount(){
|
||||
if (!this.isFindPlayerActive) return;
|
||||
try{
|
||||
let params = {};
|
||||
const res = await getApprovalCount(params);
|
||||
if(res.success == true){
|
||||
if(res.data !== null){
|
||||
this.countAp = res.data;
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg,5000);
|
||||
var request = e.config!=undefined?JSON.stringify(e.config):"";
|
||||
var response = e.data!=undefined?JSON.stringify(e.data):"";
|
||||
await this.writeLog(this.userData.userId,"find_player","","[APP][findPlayer.vue][getProfileByPlayerId][Catch Exception]"+e.errMsg,request,response,1,false);
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
// 界面方法
|
||||
confirmMsg(){
|
||||
this.msgStr = '';
|
||||
this.showMsg = false;
|
||||
},
|
||||
toNotification(){
|
||||
this.navTo("/pages/notification/notification",0,false)
|
||||
},
|
||||
clearSearchInput(){
|
||||
this.searchPlayerId = '';
|
||||
uni.removeStorageSync("playerData");
|
||||
},
|
||||
initUI() {
|
||||
this.deviceData = uni.getStorageSync("deviceData");
|
||||
},
|
||||
logoutWithADFSApp() {
|
||||
var wv = plus.webview.create(ADFS_LOGOUT_URL,'IDP');
|
||||
wv.show();
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.u-border {
|
||||
border-width: 0.5px !important;
|
||||
border-color: #434343 !important;
|
||||
border-style: solid;
|
||||
height:30px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
<!--sso login-->
|
||||
<template>
|
||||
<view>
|
||||
<view class="hz-text-center" style="padding-top:200rpx;">
|
||||
<image src="../../static/images/logo.png" style="width:138rpx;height:140rpx;"></image>
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-primary">
|
||||
{{$t('common.appName')}}
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-dark" style="margin-top:100rpx;">
|
||||
{{$t('common.userLogin')}}
|
||||
</view>
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<u--input
|
||||
v-model="userId"
|
||||
placeholder="Login User ID"
|
||||
prefixIcon="account"
|
||||
prefixIconStyle="font-size: 20px;color:#C39A4B;"
|
||||
customStyle="border-radius:22px;"
|
||||
></u--input>
|
||||
</view>
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<u--input
|
||||
v-model="password"
|
||||
placeholder="Login Password"
|
||||
prefixIcon="lock-open"
|
||||
:password="true"
|
||||
prefixIconStyle="font-size: 20px;color: #C39A4B"
|
||||
customStyle="border-radius:22px;"
|
||||
></u--input>
|
||||
</view>
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<view @click="internalLogin" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >{{$t("common.loginsso")}}</view>
|
||||
</view>
|
||||
<u-modal :content="msgStr" :show="showMsg" :confirmText="yesText" closeOnClickOverlay @confirm="confirmMsg" confirmColor="#C39A4B" @cancel="cancelMsg" @close="cancelMsg"></u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from '../../common/config.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 数据变量
|
||||
userId: '',
|
||||
password:'',
|
||||
// 界面变量
|
||||
msgStr:'',
|
||||
showMsg:false,
|
||||
yesText:this.$t("common.ok"),
|
||||
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if(options && options.errorCode){
|
||||
if(options.errorCode=='FormLoginFailed'){
|
||||
this.msgStr = this.$t("common.loginerror");
|
||||
}
|
||||
else if(options.errorCode=='MFALoginFailed'){
|
||||
this.msgStr = this.$t("common.mfaerror");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.msgStr = this.$t("common.loginfail");
|
||||
}
|
||||
this.showMsg = true;
|
||||
}else{
|
||||
this.showMsg = false;
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
},
|
||||
methods: {
|
||||
// 数据方法
|
||||
async internalLogin(){
|
||||
// 判断用户名密码是否为空
|
||||
|
||||
if(this.userId!='' && this.password!=''){
|
||||
if(this.userId.indexOf('@')==-1){
|
||||
this.userId = this.userId + '@mgm.mo';
|
||||
}
|
||||
uni.redirectTo({
|
||||
url:'/pages/samlLogin/samlLogin?uid=' + encodeURIComponent(this.userId) + '&pwd=' + encodeURIComponent(this.password)
|
||||
})
|
||||
}
|
||||
else{
|
||||
this.msgStr = this.$t("common.inputUserNameAndPassword");
|
||||
this.showMsg = true;
|
||||
}
|
||||
|
||||
},
|
||||
// 界面方法
|
||||
initUI() {
|
||||
},
|
||||
confirmMsg(){
|
||||
this.showMsg = false;
|
||||
},
|
||||
cancelMsg(){
|
||||
this.showMsg = false;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.u-border {
|
||||
border-width: 0.5px !important;
|
||||
border-color: #434343 !important;
|
||||
border-style: solid;
|
||||
height:30px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,408 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="hz-text-center" style="padding-top:200rpx;">
|
||||
<image src="../../static/images/logo.png" style="width:138rpx;height:140rpx;"></image>
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-primary">
|
||||
{{$t('common.appName')}}
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-dark" style="margin-top:160rpx;">
|
||||
{{$t('common.userLogin')}}
|
||||
</view>
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<view @click="goLogin" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >{{$t("common.loginsso")}}</view>
|
||||
<button type="primary" v-show="false" @click="checkVPNOpen">testVPNFunc</button>
|
||||
<button type="primary" v-show="false" @click="checkInMacau">testLocationFunc</button>
|
||||
<button type="primary" v-show="false" @click="testCfgDecrypt">testCfgDecrypt</button>
|
||||
</view>
|
||||
<view class="hz-font-sm hz-text-center" style="margin-top:30rpx;color:#999;">
|
||||
<u-row>
|
||||
<u-col span="6" customStyle="text-align:center;">
|
||||
{{siteData.version}}
|
||||
</u-col>
|
||||
<u-col span="6" customStyle="text-align:center;">
|
||||
<view v-if="showConnected" style="display:flex;flex-direction:row;align-items: center;justify-content:center;">
|
||||
<view style="width:6px;height:6px;background-color: #009933;border-radius: 50%;"></view>
|
||||
<view style="margin-left:3px;">{{$t('common.connected')}}</view>
|
||||
</view>
|
||||
<view v-if="!showConnected" style="display:flex;flex-direction:row;align-items: center;justify-content:center;">
|
||||
<view style="width:6px;height:6px;background-color: #ff0000;border-radius: 50%;"></view>
|
||||
<view style="margin-left:3px;">{{$t('common.disconnected')}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
|
||||
</view>
|
||||
<!--<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<view @click="logout" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >testlogout</view>
|
||||
</view>-->
|
||||
<!-- <u-modal :show="showCommitment" :customStyle="{height:contentHeight + 'px;overflow:auto;'}" :confirmText="confirmText" :showCancelButton="false" closeOnClickOverlay @confirm="checkInMacau" confirmColor="#C39A4B" @close="showCommitment=false">
|
||||
<scroll-view scroll-y style="max-height: 400rpx; margin: 20rpx 0;">
|
||||
<view class="hz-font-lg commit-content">{{commitmentText1 }}<p style="margin-top:20px;">{{commitmentText2}}</p></view>
|
||||
</scroll-view>
|
||||
</u-modal> -->
|
||||
|
||||
<view style="width: 100%;">
|
||||
<u-popup :show="showCommitment" :round="10" mode="center" customStyle="margin:0rpx 40rpx;">
|
||||
<view style="padding: 20px 22px 32px 22px;">
|
||||
<h4 style="font-size: 18px; display: flex; justify-content: center; padding: 7px;">{{commitTitle}}</h4>
|
||||
<view style="height:490px;font-size:13px;color:#333;">
|
||||
<view style="margin-bottom: 24rpx;line-height: 1.7;">{{commitmentText1}}</view>
|
||||
<view >{{commitmentText2}}</view>
|
||||
</view>
|
||||
<view >
|
||||
<view @click="handleConfirm()" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >{{confirmText}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getSettings} from '../../api/commonApi.js'
|
||||
import {getSSOTokenByCode,userSSOlogin,userOpenIdlogin} from '../../api/ssoApi.js'
|
||||
import { userConfirm } from '../../api/todoApi.js';
|
||||
import { getCfgSettingByKey } from '../../api/configApi.js';
|
||||
import config from '../../common/config.js';
|
||||
import { decryptCfgSettingValue } from '../../common/cfgSettingCrypto.js';
|
||||
import dayjs from '../../uni_modules/uview-ui/libs/util/dayjs.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 数据变量
|
||||
playerIdStr: this.$t("common.playerId"),
|
||||
searchPlayerId: '',
|
||||
userData:null,
|
||||
deviceData:null,
|
||||
siteData:null,
|
||||
// 界面变量
|
||||
title: '',
|
||||
userName:'',
|
||||
code:'',
|
||||
commitTitle:this.$t("region.commitTitle"),
|
||||
commitmentText1:this.$t("region.commitment1"),
|
||||
commitmentText2:this.$t("region.commitment2"),
|
||||
confirmText:this.$t("common.confirm"),
|
||||
showConnected:false,
|
||||
showCommitment:false,
|
||||
contentHeight:600,
|
||||
}
|
||||
},
|
||||
async onLoad(opt) {
|
||||
await this.$onLaunched; // 必须等App.vue中的initCfg执行完才执行onload
|
||||
// 初始化界面
|
||||
//uni.setLocale("en") //測試切換語言en or zh-Hant
|
||||
await this.initUI();
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
if(opt!=undefined && opt!=null && opt.code!=undefined && opt.code!=''){
|
||||
this.code = opt.code;
|
||||
this.goLogin();
|
||||
}else{
|
||||
this.code = '';
|
||||
}
|
||||
await this.getSetting();
|
||||
uni.onNetworkStatusChange(res => {
|
||||
console.log("是否联网:", res.isConnected);
|
||||
console.log("网络类型:", res.networkType);
|
||||
this.getSetting();
|
||||
});
|
||||
},
|
||||
onShow() {
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
var userData = uni.getStorageSync("userData");
|
||||
if(userData==undefined || userData==null || userData==""){
|
||||
this.code='';
|
||||
}
|
||||
/*let idToken = uni.getStorageSync("idToken");
|
||||
console.log("onshow idToken="+idToken);*/
|
||||
},
|
||||
methods: {
|
||||
/** 调试:拉取配置并 GCM 解密 keyValues,结果见控制台(需把按钮 v-show 改为 true 或在控制台调用) */
|
||||
async testCfgDecrypt(){
|
||||
try{
|
||||
console.log('[testCfgDecrypt] crypto.subtle:', !!(globalThis.crypto && globalThis.crypto.subtle));
|
||||
const params = { keyName: 'MACAU_IP' };
|
||||
const res = await getCfgSettingByKey(params);
|
||||
const cfg = new config();
|
||||
const cipher = res && res.data ? res.data.keyValues : '';
|
||||
const plain = await decryptCfgSettingValue(cipher, cfg.allowKey);
|
||||
console.log('[testCfgDecrypt] cipher:', cipher);
|
||||
console.log('[testCfgDecrypt] plain:', plain);
|
||||
}catch(e){
|
||||
console.error('[testCfgDecrypt]', e);
|
||||
}
|
||||
},
|
||||
async handleConfirm(){
|
||||
const userData = uni.getStorageSync("userData");
|
||||
const params = {
|
||||
userId : userData.userId,
|
||||
userName : userData.userName
|
||||
};
|
||||
const res = await userConfirm(params);
|
||||
this.checkInMacau();
|
||||
},
|
||||
checkInMacau(){
|
||||
this.showCommitment = false;
|
||||
//用户commit之后 将userData传到后端写log
|
||||
// #ifdef APP-PLUS
|
||||
let siteData = uni.getStorageSync("siteData");
|
||||
if(siteData.internalTag===true){
|
||||
let userData= uni.getStorageSync("userData");
|
||||
this.redirectByPermission(userData,true);
|
||||
}
|
||||
//只有外网才检查
|
||||
if(siteData!==undefined && siteData!==null && siteData.internalTag===false)
|
||||
{
|
||||
this.checkLocationAndVPN(false);
|
||||
}
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
let userData= uni.getStorageSync("userData");
|
||||
this.redirectByPermission(userData,true);
|
||||
// #endif
|
||||
},
|
||||
// 数据方法
|
||||
async getSetting(){
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
let that = this;
|
||||
// 获取是否mockSSO配置
|
||||
await getSettings({}).then((res) => {
|
||||
try{
|
||||
if(res!=null && res.success == true){
|
||||
if(res.data!=null){
|
||||
const settings = res.data;
|
||||
//console.log('SETTING');
|
||||
//console.log(settings);
|
||||
for(let i=0;i<settings.length;i++){
|
||||
const setting = settings[i];
|
||||
if(setting.settingKey == 'APP_MOCK_SSO'){
|
||||
if(setting.settingValue == "1")
|
||||
that.siteData.mockSSO = true;
|
||||
else
|
||||
that.siteData.mockSSO = false;
|
||||
|
||||
if(setting.internalNetwork == true)
|
||||
that.siteData.internalTag = true;
|
||||
else
|
||||
that.siteData.internalTag = false;
|
||||
}
|
||||
else if(setting.settingKey == 'APP_MOCK_TPD'){
|
||||
if(setting.settingValue == "1")
|
||||
that.siteData.mockTPD = true;
|
||||
else
|
||||
that.siteData.mockTPD = false;
|
||||
}
|
||||
}
|
||||
//that.siteData.mockSSO = true;
|
||||
//that.siteData.internalTag = true;
|
||||
that.showConnected = true;
|
||||
}else{
|
||||
that.showConnected = false;
|
||||
}
|
||||
uni.setStorageSync('siteData', that.siteData);
|
||||
that.$isResolve();
|
||||
}else{
|
||||
that.showConnected = false;
|
||||
}
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg,5000);
|
||||
that.writeLog("","login","","[APP][login.vue][getSetting][Parse Exception]"+e.errMsg,"","",1,false);
|
||||
uni.hideLoading();
|
||||
}
|
||||
finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
if(error.errMsg.indexOf('-1')>0){
|
||||
that.showConnected = false;
|
||||
}
|
||||
uni.$u.toast(error.errMsg,5000);
|
||||
var request = error.config!=undefined?JSON.stringify(error.config):"";
|
||||
var response = error.data!=undefined?JSON.stringify(error.data):"";
|
||||
that.writeLog("","login","","[APP][login.vue][getSetting][Catch Exception]"+error.errMsg,request,response,1,false);
|
||||
uni.hideLoading();
|
||||
});
|
||||
},
|
||||
logout(){
|
||||
uni.redirectTo({
|
||||
url:'/pages/azureLogout/azureLogout'
|
||||
//url:'/pages/adfs/adfs'
|
||||
});
|
||||
},
|
||||
async getTokenByCodeMock(code){
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
try{
|
||||
let params = {
|
||||
code:code,
|
||||
mockSSO:this.siteData.mockSSO,
|
||||
};
|
||||
let that = this;
|
||||
const res = await getSSOTokenByCode(params);
|
||||
if(res.success === true){
|
||||
if(res !== null){
|
||||
uni.setStorageSync("token",res.accessToken);
|
||||
uni.setStorageSync("userData",res.userData);
|
||||
uni.setStorageSync("clientId",res.clientId);
|
||||
uni.setStorageSync("timeOut",dayjs().add(30,'day').unix());
|
||||
uni.setStorageSync("tokenTime",dayjs().unix());
|
||||
uni.setStorageSync("refreshToken",res.refreshToken);
|
||||
// uni.setStorageSync("timeOut",dayjs().add(1,'day').unix());//For test
|
||||
// uni.setStorageSync("timeOut",dayjs().add(30, 'minutes').unix());
|
||||
//this.navTo('/pages/dashboard/dashboard',1,false);
|
||||
// that.redirectByPermission(res.data.userData,true);
|
||||
that.showCommitment = true;
|
||||
}else{
|
||||
uni.$u.toast(res.message,5000);
|
||||
this.writeLog("","getTokenByCodeMock","","[APP][login.vue][getTokenByCodeMock]data is null;"+res.message,"","",1,false);
|
||||
}
|
||||
}else{
|
||||
uni.$u.toast(res.message,5000);
|
||||
this.writeLog("","getTokenByCodeMock","","[APP][login.vue][getTokenByCodeMock]return false;"+res.message,"","",1,false);
|
||||
}
|
||||
}catch(e){
|
||||
// write exception log
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg,5000);
|
||||
this.writeLog("","getTokenByCodeMock","","[APP][login.vue][getTokenByCodeMock][Catch Exception]"+e.errMsg,"","",1,false);
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
async getTokenByCode(code){
|
||||
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
try{
|
||||
code = code.replaceAll(" ", "+");
|
||||
let params = {};
|
||||
|
||||
params = {
|
||||
SAMLResponse:code,
|
||||
};
|
||||
let that = this;
|
||||
const res = await userSSOlogin(params);
|
||||
if(res.success === true){
|
||||
if(res !== null){
|
||||
uni.setStorageSync("idToken",res.idToken);
|
||||
uni.setStorageSync("token",res.token);
|
||||
uni.setStorageSync("userData",res.userData);
|
||||
uni.setStorageSync("clientId",res.clientId);
|
||||
uni.setStorageSync("timeOut",dayjs().add(30,'day').unix());
|
||||
uni.setStorageSync("tokenTime",dayjs().unix());
|
||||
uni.setStorageSync("refreshToken",res.refreshToken);
|
||||
|
||||
that.showCommitment = true;
|
||||
// uni.setStorageSync("timeOut",dayjs().add(30, 'minutes').unix());
|
||||
// uni.setStorageSync("timeOut",dayjs().add(1,'day').unix());//For test
|
||||
|
||||
//根据权限进行页面跳转
|
||||
//that.redirectByPermission(res.data.userData,true);
|
||||
|
||||
//this.navTo('/pages/dashboard/dashboard',1,false);
|
||||
}else{
|
||||
// write log正常不会没有返回
|
||||
uni.$u.toast(res.message+" No response data.",5000);
|
||||
}
|
||||
}else{
|
||||
// write error log
|
||||
uni.$u.toast(res.message +" Server return false.",5000);
|
||||
}
|
||||
}catch(e){
|
||||
// write exception log
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg,5000);
|
||||
this.writeLog("","getTokenByCode","","[APP][login.vue][getTokenByCode][Catch Exception]"+e.errMsg,code,"",1,false);
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
|
||||
// 界面方法
|
||||
async goLogin(){
|
||||
await this.$onLaunched;
|
||||
await this.getSetting();
|
||||
const userData = uni.getStorageSync("userData");
|
||||
let loginTag = false;
|
||||
uni.setStorageSync("todoSwitch","true");
|
||||
if(userData!==undefined && userData!==null && userData!==''){
|
||||
loginTag = userData.loginTag;
|
||||
}
|
||||
|
||||
//uni.$u.toast("LoginTag="+loginTag + ";mockSSO="+this.siteData.mockSSO);
|
||||
if(loginTag===true){
|
||||
this.redirectByPermission(userData);
|
||||
}
|
||||
|
||||
// 模拟开启,没有code,默认进来的情况
|
||||
if(this.siteData.mockSSO==true && this.code=='' && loginTag===false){
|
||||
// 模拟SSO
|
||||
uni.redirectTo({
|
||||
url:'/pages/ssoLogin/ssoLogin'
|
||||
})
|
||||
}
|
||||
// 模拟开启,有code,SSO返回code的情况
|
||||
else if(this.siteData.mockSSO==true && this.code!==''){
|
||||
this.getTokenByCodeMock(this.code);
|
||||
}
|
||||
// 真实SSO环境,没有code,默认进来的情况
|
||||
else if(this.siteData.mockSSO==false && this.code=='' && loginTag===false)
|
||||
{
|
||||
if(this.siteData.internalTag==true)
|
||||
{
|
||||
console.log('INTERNAL LOGIN');
|
||||
uni.redirectTo({
|
||||
url:'/pages/idpLogin/idpLogin'
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('AZURE LOGIN');
|
||||
uni.redirectTo({
|
||||
url:'/pages/azureLogin/azureLogin'
|
||||
});
|
||||
}
|
||||
}
|
||||
// 真实SSO环境,有code,SSO返回code的情况
|
||||
else if(this.siteData.mockSSO==false && this.code!=='')
|
||||
{
|
||||
this.getTokenByCode(this.code);
|
||||
}
|
||||
},
|
||||
clearSearchInput(){
|
||||
this.searchPlayerId = '';
|
||||
uni.removeStorageSync("playerData");
|
||||
},
|
||||
initUI() {
|
||||
this.deviceData = uni.getStorageSync("deviceData");
|
||||
this.contentHeight = this.deviceData.windowHeight - 60;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.commit-content{
|
||||
line-height: 1.5; /* 增加行间距提升可读性 */
|
||||
color: #333; /* 深灰提升阅读舒适度 */
|
||||
max-height: 500px;
|
||||
overflow-y: auto!important;
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar
|
||||
:safeAreaInsetTop="true"
|
||||
:placeholder="true"
|
||||
:title="title"
|
||||
:fixed="true"
|
||||
:autoBack="true"
|
||||
leftIconColor="#000000"
|
||||
bgColor="#ffffff"
|
||||
titleStyle="font-weight:bold;color:#000000;"
|
||||
>
|
||||
<view style="margin-top:2px;margin-right:3px;" slot="right">
|
||||
<u-icon
|
||||
v-if="hasSelectedDate"
|
||||
@click="clearDateFilter"
|
||||
size="28px" name="../../static/images/filter-clear.svg"
|
||||
></u-icon>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<!-- 搜索栏 -->
|
||||
<view class="hz-spacing hz-mr-t-20 hz-flex-row">
|
||||
<u-search :placeholder="searchHolder" v-model="searchInputStr" :showAction="false" bgColor="#ffffff" :label="searchLabel"
|
||||
borderColor="gray" style="padding-right: 8px" @search="searchApprovalByPlayerId()"></u-search>
|
||||
<u-icon name="calendar" :size="45" :color="calendarIconColor" @click="showCalendar = true"></u-icon>
|
||||
</view>
|
||||
|
||||
<view v-if="!showApprovalList">
|
||||
<view class="hz-flex-row" style="justify-content: center;margin-top:80px;">
|
||||
<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 v-else>
|
||||
<uni-card v-for="(approvalRecord,index) in approvalList" :key="index" @click="toDetail(approvalRecord.playerId)">
|
||||
<view class="notification-content">
|
||||
<view class="icon-container">
|
||||
<image src="/static/images/task.png" class="task-icon"></image>
|
||||
</view>
|
||||
<view class="notification-info">
|
||||
<view class="notification-title">
|
||||
{{ $t("notification.pendingApprovalRequest") }}
|
||||
</view>
|
||||
<view class="notification-date">
|
||||
{{approvalRecord.createdAt}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="notification-time">
|
||||
{{getTimeAgo(approvalRecord.createdAt)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="notification-detail">
|
||||
{{approvalRecord.memberLastName}}, {{approvalRecord.playerId}} ({{approvalRecord.tier}}), {{approvalRecord.propertyName}}, {{approvalRecord.roomTypeCode}}, {{approvalRecord.checkinDate}} to {{approvalRecord.checkoutDate}}, {{approvalRecord.booker}}
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
|
||||
<u-calendar :show="showCalendar" @close="showCalendar = false" :confirmText="confirmText" :confirmDisabledText="confirmText"
|
||||
color="#C39A4B" :allowSameDay="true" :startText="startText" :endText="endText" mode="range" :showMark="false"
|
||||
title="" @confirm="handleFilterDate" :defaultDate="selectedDate">
|
||||
|
||||
</u-calendar>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getApprovalList} from '../../api/approvalApi.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title:this.$t("notification.pendingApproval"),
|
||||
searchInputStr:'',
|
||||
userData:'',
|
||||
approvalList:[],
|
||||
showApprovalList:true,
|
||||
dataNull:this.$t("notification.noData"),
|
||||
searchHolder:this.$t("approval.searchStr"),
|
||||
calendarIconColor: '#000000',
|
||||
showCalendar: false,
|
||||
confirmText: this.$t("common.confirm").toUpperCase(),
|
||||
startText: this.$t("common.start"),
|
||||
endText: this.$t("common.end"),
|
||||
selectedDate: [],
|
||||
searchLabel: this.$t("common.playerId")
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
this.getApprovalList();
|
||||
},
|
||||
methods: {
|
||||
handleFilterDate(e) {
|
||||
this.selectedDate = e;
|
||||
this.showCalendar = false;
|
||||
|
||||
if (Array.isArray(this.selectedDate) && this.selectedDate.length > 0) {
|
||||
this.calendarIconColor = '#C39A4B';
|
||||
} else {
|
||||
this.calendarIconColor = '#000000';
|
||||
}
|
||||
|
||||
this.getApprovalList();
|
||||
},
|
||||
clearDateFilter() {
|
||||
this.selectedDate = [];
|
||||
this.calendarIconColor = '#000000';
|
||||
this.getApprovalList();
|
||||
},
|
||||
|
||||
toDetail(playerId){
|
||||
this.navTo("/pages/playerDetail/playerDetail?playerId="+playerId,0,false)
|
||||
},
|
||||
getTimeAgo(createdAt) {
|
||||
if (!createdAt) return '';
|
||||
|
||||
const now = new Date();
|
||||
const created = new Date(createdAt);
|
||||
const diffMs = now - created;
|
||||
const diffMins = Math.floor(diffMs / 60000);
|
||||
const diffHours = Math.floor(diffMins / 60);
|
||||
const diffDays = Math.floor(diffHours / 24);
|
||||
|
||||
if (diffMins < 1) return 'just now';
|
||||
if (diffMins < 60) return diffMins + 'm';
|
||||
if (diffHours < 24) return diffHours + 'h';
|
||||
return diffDays + 'd';
|
||||
},
|
||||
async getApprovalList(){
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
try{
|
||||
let params = {
|
||||
userId: this.userData.userId,
|
||||
playerId: this.searchInputStr,
|
||||
rangeDate: this.selectedDate
|
||||
};
|
||||
const res = await getApprovalList(params);
|
||||
if(res.success == true){
|
||||
if(res.data !== null && res.data.length > 0){
|
||||
this.approvalList = res.data;
|
||||
// 提取所有 playerId 到新的 playerList 并去重
|
||||
const playerIds = this.approvalList.map(item => item.playerId);
|
||||
const uniquePlayerIds = [...new Set(playerIds)];
|
||||
this.playerList = uniquePlayerIds.map(playerId => ({ playerId }));
|
||||
uni.setStorageSync("approvalPlayerList",this.playerList);
|
||||
this.showApprovalList = true;
|
||||
} else {
|
||||
this.showApprovalList = false;
|
||||
this.dataNull = this.$t("notification.noData");
|
||||
}
|
||||
}else{
|
||||
this.msgStr = res.message;
|
||||
this.showMsg = true;
|
||||
this.showApprovalList = false;
|
||||
if(res.errorCode==="NO_PERMISSION") this.dataNull = this.$t("notification.noPermission");
|
||||
}
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg,5000);
|
||||
var request = e.config!=undefined?JSON.stringify(e.config):"";
|
||||
var response = e.data!=undefined?JSON.stringify(e.data):"";
|
||||
await this.writeLog(this.userData.userId,"find_player","","[APP][findPlayer.vue][getProfileByPlayerId][Catch Exception]"+e.errMsg,request,response,1,false);
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
// 搜索玩家審批請求
|
||||
searchApprovalByPlayerId() {
|
||||
this.getApprovalList();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasSelectedDate() {
|
||||
return Array.isArray(this.selectedDate) && this.selectedDate.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
margin-right: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.task-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.notification-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.notification-title {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.notification-date {
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.notification-time {
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
color: #C39A4B;
|
||||
background-color: #FFF8E7;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.notification-detail {
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
color: #000000;
|
||||
margin-top: 6px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,986 @@
|
||||
<template>
|
||||
<view class="hz-page">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<simple-watermark ref="watermark"></simple-watermark>
|
||||
<!-- #endif -->
|
||||
<u-navbar @leftClick="back()" :safeAreaInsetTop="true" :placeholder="true" :title="title" :fixed="true"
|
||||
:autoBack="false" leftIconColor="#000000" bgColor="#fff" titleStyle="font-weight:bold;">
|
||||
</u-navbar>
|
||||
<view class="hz-spacing hz-bg-white" style="margin-top:8px;">
|
||||
<!-- Player Info 卡片 -->
|
||||
<view class="hz-card-profile hz-mr-b-30">
|
||||
<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">
|
||||
{{bookingListData.length > 0 ? bookingListData[0].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">
|
||||
{{bookingListData.length > 0 ? bookingListData[0].tier : '-'}}</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">
|
||||
{{bookingListData.length > 0 ? (bookingListData[0].memberTitle || '') + ' ' + (bookingListData[0].memberFirstName || '') + ' ' + (bookingListData[0].memberLastName || '') : '-'}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- Booking Info 卡片 -->
|
||||
<view class="hz-pd-16 hz-font-bolder hz-font-md hz-card-extend"
|
||||
style="margin-top:10px;align-items: center;">
|
||||
<view class="hz-flex-row" style="align-items: center; width: 100%;">
|
||||
<!-- 房间信息轮播 -->
|
||||
<view style="flex: 1; margin-right: 10px; min-height: 80px;">
|
||||
<!-- 房间信息轮播 -->
|
||||
<view style="position: relative; height: 100px;" @touchstart="touchStart" @touchend="touchEnd">
|
||||
<!-- 轮播内容 -->
|
||||
<view v-for="(room, index) in roomList" :key="index"
|
||||
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; transition: opacity 0.5s;"
|
||||
:style="{ opacity: currentRoomIndex === index ? 1 : 0, zIndex: currentRoomIndex === index ? 1 : 0 }">
|
||||
<view class="hz-flex-row" style="align-items: center;">
|
||||
<!-- 多选框 -->
|
||||
<view
|
||||
style="width: 17px; height: 17px; display: flex; align-items: center; justify-content: center;;"
|
||||
@click="toggleSelection(index)">
|
||||
<view
|
||||
style="width: 15px; height: 15px; border: 0.5px solid #C39A4B; transition: all 0.3s; display: flex; align-items: center; justify-content: center;border-radius: 25px;"
|
||||
:style="{ backgroundColor: room.selected ? '#C39A4B' : '#ffffff' }">
|
||||
<view v-if="room.selected"
|
||||
style="color: white; font-size: 10px; font-weight: bold;">✔</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 房间信息 -->
|
||||
<view style="flex: 1;margin-left: 10px;">
|
||||
<!-- Edit 按钮 -->
|
||||
<view @click="toEdit()" style="display:flex;justify-content:flex-end;width:100%;">
|
||||
<image src="/static/images/edit_active.png"
|
||||
style="width: 17px; height: 17px;" />
|
||||
</view>
|
||||
|
||||
<view class="hz-flex-row" style="align-items: center;">
|
||||
<image src="/static/images/ico_calendar.png"
|
||||
style="width:16px;height:16px;"></image>
|
||||
<span class="hz-font-bolder"
|
||||
style="margin-left:4px;font-size: 14px;">{{room.date}} {{$t("common.to")}}
|
||||
{{room.endDate}}</span>
|
||||
</view>
|
||||
<view class="hz-flex-row" style="margin-top:8px;">
|
||||
<view class="hz-flex-row" style="align-items: center;">
|
||||
<image src="/static/images/ico_room.png"
|
||||
style="width:16px;height:16px;"></image>
|
||||
<span class="hz-font-bolder"
|
||||
style="margin-left:4px;font-size: 14px;">{{room.roomInfo}}</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 轮播指示器 -->
|
||||
<view
|
||||
style="position: absolute; bottom: 0; left: 0; width: 100%; display: flex; justify-content: center; gap: 8px;">
|
||||
<view v-for="(room, index) in roomList" :key="index"
|
||||
style="width: 6px; height: 6px; border-radius: 50%; transition: background-color 0.3s;"
|
||||
:style="{ backgroundColor: currentRoomIndex === index ? '#C39A4B' : '#CCCCCC' }"
|
||||
@click="currentRoomIndex = index"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 玩家信息 -->
|
||||
<view style="padding-left: 8px;padding-right: 8px;">
|
||||
<view class="infoButton">
|
||||
<view class="hz-flex-row dataMargin">
|
||||
<view class="" style="width: 50%;font-weight: bolder">
|
||||
Current Trip Theo
|
||||
</view>
|
||||
<view class="">
|
||||
{{formatWithThousands(currentApprovalData.currentTripTheoWinAmount)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row dataMargin">
|
||||
<view class="" style="width: 50%;font-weight: bolder">
|
||||
Last 2 Days Theo
|
||||
</view>
|
||||
<view class="">
|
||||
{{formatWithThousands(currentApprovalData.last2DayTheoWinAmount)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="dataMargin">
|
||||
<view class="hz-flex-row">
|
||||
<view class="" style="width: 50%;font-weight: bolder">
|
||||
R3 Theo/TPD/Actual win
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row">
|
||||
<view>
|
||||
{{formatWithThousands(currentApprovalData.r3TheoWin)}} / {{formatWithThousands(currentApprovalData.r3TPD)}} / {{formatWithThousands(currentApprovalData.r3ActualWin)}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row">
|
||||
<view class="" style="width: 50%;font-weight: bolder">
|
||||
R6 Theo/TPD/Actual win
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row">
|
||||
<view>
|
||||
{{formatWithThousands(currentApprovalData.r6TheoWin)}} / {{formatWithThousands(currentApprovalData.r6TPD)}} / {{formatWithThousands(currentApprovalData.r6ActualWin)}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="infoButton">
|
||||
<view style="font-weight: bolder">
|
||||
Continuous / Overlap Booking (C/I to C/O)
|
||||
</view>
|
||||
<view>
|
||||
{{currentApprovalData.overlapBooking}}
|
||||
</view>
|
||||
</view>
|
||||
<!-- RoomCount -->
|
||||
<view class="infoButton">
|
||||
<view style="font-weight: bolder">
|
||||
Room Count
|
||||
</view>
|
||||
<view>
|
||||
{{ sortRoomCountByDate(currentApprovalData.roomCount) }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- Remark -->
|
||||
<view class="infoButton">
|
||||
<view style="font-weight: bolder">
|
||||
Remark
|
||||
</view>
|
||||
<view class="">
|
||||
{{roomList[currentRoomIndex] && roomList[currentRoomIndex].remark ? roomList[currentRoomIndex].remark : '-'}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="infoButton">
|
||||
<view style="font-weight: bolder">
|
||||
Sharer
|
||||
</view>
|
||||
<view class="">
|
||||
{{roomList[currentRoomIndex] ? roomList[currentRoomIndex].sharer : '-'}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="infoButton">
|
||||
<view style="font-weight: bolder">
|
||||
Request Reason
|
||||
</view>
|
||||
<view class="">
|
||||
{{ currentApprovalRouting.approvalReason}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="infoButton">
|
||||
<view style="font-weight: bolder">
|
||||
Routing Reason
|
||||
</view>
|
||||
<view class="">
|
||||
{{currentApprovalRouting.routingReason}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-mr-t-30">
|
||||
<view class="hz-flex-row">
|
||||
<view class="" style="width: 50%;font-weight: bolder">
|
||||
Requested on
|
||||
</view>
|
||||
<view class="" style="font-weight: bolder">
|
||||
Requested by
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row">
|
||||
<view class="" style="width: 50%;">
|
||||
{{currentApprovalRouting.createdAt ? formatDate(currentApprovalRouting.createdAt) : '-'}}
|
||||
</view>
|
||||
<view class="" style="width: 50%;">
|
||||
{{currentApprovalRouting.createdBy}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-tabbar :fixed="true" :placeholder="true" :safeAreaInsetBottom="true" customStyle="z-index:100;height:58px;">
|
||||
<view @click="toPreviousRecord()" class="book hz-flex-row hz-spacing"
|
||||
:class="canPrevious==false? 'hz-disabled':''" style="width: 60%;">
|
||||
<view class="hz-btn hz-font-color-primary hz-font-lg hz-font-bold hz-text-center"
|
||||
style="background-color: #fff;border: #C39A4B solid 2px;display: flex;justify-content: center;align-items: center;">
|
||||
<image src="/static/images/arrow_previous_active.png"
|
||||
style="width: 25px; height: 25px;" />
|
||||
</view>
|
||||
</view>
|
||||
<view @click="onTabApproveTap" class="book hz-flex-row hz-spacing"
|
||||
:class="approvalLoading==true || roomList.filter(r => r.selected).length > 0? 'hz-disabled':''">
|
||||
<view class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center">
|
||||
{{$t("approval.approve")}}
|
||||
</view>
|
||||
</view>
|
||||
<view @click="onTabRejectTap" class="book hz-flex-row hz-spacing"
|
||||
:class="approvalLoading==true || roomList.filter(r => r.selected).length > 0? 'hz-disabled':''">
|
||||
<view class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center">
|
||||
{{$t("bookingDetail.reject")}}
|
||||
</view>
|
||||
</view>
|
||||
<view @click="toNextRecord()" class="book hz-flex-row hz-spacing" :class="canNext==false? 'hz-disabled':''"
|
||||
style="width: 60%">
|
||||
<view class="hz-btn hz-font-color-primary hz-font-lg hz-font-bold hz-text-center"
|
||||
style="background-color: #fff;border: #C39A4B solid 2px;display: flex;justify-content: center;align-items: center;">
|
||||
<image src="/static/images/arrow_next_active.png"
|
||||
style="width: 25px; height: 25px;" />
|
||||
</view>
|
||||
</view>
|
||||
</u-tabbar>
|
||||
<u-popup :safeAreaInsetBottom="true" :closeOnClickOverlay="false" :safeAreaInsetTop="true" :mode="'center'" :round="12" :show="showMsgBox"
|
||||
customStyle="width:94%; padding-top: 30px" @close="closePopup()">
|
||||
<view>
|
||||
<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-xl hz-font-bold hz-text-center"
|
||||
style="margin-top:20px;margin-bottom: 20px;margin-left: 15px;margin-right: 15px;white-space:pre-wrap;">
|
||||
<rich-text v-html="popMsgStr" style="line-height:26px;"></rich-text>
|
||||
</view>
|
||||
<view v-if="showSubmit">
|
||||
<view @click="currentAction === 'approve' ? confirmApproval() : confirmReject()"
|
||||
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 15px;">
|
||||
{{$t("common.confirm").toUpperCase()}}
|
||||
</view>
|
||||
<view @click="closePopup()"
|
||||
class="hz-btn hz-font-color-primary hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 30px;background-color: white;border: 0.5px solid;">
|
||||
{{$t("common.cancel").toUpperCase()}}
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view @click="backToNotification()"
|
||||
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 15px;">
|
||||
{{$t("approval.backToRecord").toUpperCase()}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<u-popup :safeAreaInsetBottom="true" :safeAreaInsetTop="true" :mode="'center'" :round="12"
|
||||
:show="showReturnMsgBox">
|
||||
<view :style="'width:'+ windowWidth + 'px;'" style="padding:20px;">
|
||||
<view class="hz-flex-row" style="justify-content: center;">
|
||||
<image :src="iconPath" style="width:64px;height:64px;"></image>
|
||||
</view>
|
||||
<view class="hz-font-md hz-font-bold hz-text-center" style="margin-top:20px;">
|
||||
<rich-text v-html="msgStr" style="line-height:26px;"></rich-text>
|
||||
</view>
|
||||
<view @click="showReturnMsgBox = false"
|
||||
class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" style="margin-top:20px;">
|
||||
{{buttonStr}}
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<u-calendar closeOnClickOverlay :confirmText="confirmText" :confirmDisabledText="confirmText" color="#C39A4B"
|
||||
title="" :startText="startText" :endText="endText" :show="showCalendar" :allowSameDay="true" mode="range"
|
||||
:minDate="selectAbleStart" :maxDate="selectAbleEnd" :defaultDate="[calendarStartDate, calendarEndDate]"
|
||||
@close="cancelDate" @confirm="confirmDate" :showMark="false">
|
||||
</u-calendar>
|
||||
|
||||
<!-- 悬浮栏 - 显示选中的记录数量 -->
|
||||
<view v-if="roomList.filter(r => r.selected).length > 0" class="floating-bar">
|
||||
<view class="floating-content">
|
||||
<text class="selected-count">{{ roomList.filter(r => r.selected).length }} {{ $t("common.selected") }}</text>
|
||||
<view class="floating-actions">
|
||||
<view @click="handleBatchApprove" class="action-btn approve-btn">{{ $t("approval.batchApprove") }}</view>
|
||||
<view @click="handleBatchReject" class="action-btn reject-btn">{{ $t("approval.batchReject") }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
batchSubmitApproval,
|
||||
batchSubmitReject,
|
||||
getApprovalData,
|
||||
rejectApproval,
|
||||
submitApproval
|
||||
} from '../../api/approvalApi';
|
||||
import {
|
||||
times
|
||||
} from '../../uni_modules/uview-ui/libs/function/digit';
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
import SimpleWatermark from '@/components/simple-watermark/simple-watermark.vue'
|
||||
// #endif
|
||||
|
||||
export default {
|
||||
components: {
|
||||
// #ifdef APP-PLUS
|
||||
SimpleWatermark
|
||||
// #endif
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: "Detail",
|
||||
approvalLoading: false,
|
||||
iconPath: '',
|
||||
popMsgStr: '',
|
||||
showMsgBox: false,
|
||||
confirmText: this.$t('playerDetail.confirm'),
|
||||
startText: this.$t('common.in'),
|
||||
endText: this.$t('common.out'),
|
||||
// 日历日期范围
|
||||
calendarStartDate: '',
|
||||
calendarEndDate: '',
|
||||
selectAbleStart: '',
|
||||
selectAbleEnd: '',
|
||||
searchPlayerId: '',
|
||||
showCalendar: false,
|
||||
showSubmit: true,
|
||||
deviceData: '',
|
||||
canNext: false,
|
||||
canPrevious: true,
|
||||
// 玩家导航
|
||||
currentPlayerIndex: 0,
|
||||
approvalPlayerList: [],
|
||||
showReturnMsgBox: false,
|
||||
// 触摸事件
|
||||
touchStartX: 0,
|
||||
touchEndX: 0,
|
||||
buttonStr: '',
|
||||
msgStr: '',
|
||||
windowWidth: 0,
|
||||
// 房间信息轮播
|
||||
currentRoomIndex: 0,
|
||||
// 当前操作类型:approve 或 reject
|
||||
currentAction: '',
|
||||
bookingListData: [],
|
||||
approvalGamingDataList: [],
|
||||
approvalRoutingList: [],
|
||||
roomList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 获取当前房间对应的 approvalGamingData
|
||||
currentApprovalData() {
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
if (currentRoom && currentRoom.id) {
|
||||
const approvalData = this.approvalGamingDataList.find(
|
||||
item => item.bookingId == currentRoom.id
|
||||
);
|
||||
return approvalData || {};
|
||||
}
|
||||
return {};
|
||||
},
|
||||
// 当前轮播房间对应的 cfgApprovalRouting(按 bookingId 匹配)
|
||||
currentApprovalRouting() {
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
if (!currentRoom || currentRoom.id == null) return {};
|
||||
const row = this.approvalRoutingList.find(
|
||||
item => item.bookingId == currentRoom.id
|
||||
);
|
||||
return row || {};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatWithThousands(value) {
|
||||
if (value === null || value === undefined || value === '') return '-';
|
||||
const str = String(value).trim();
|
||||
// 已经是合法千分位格式(支持负数和小数)时,直接返回
|
||||
if (/^-?\d{1,3}(,\d{3})*(\.\d+)?$/.test(str)) return str;
|
||||
// 未格式化数字(或带逗号但格式不标准)时,去逗号后重新格式化
|
||||
const normalized = str.replace(/,/g, '');
|
||||
if (/^-?\d+(\.\d+)?$/.test(normalized)) {
|
||||
const n = Number(normalized);
|
||||
return n.toLocaleString('en-US');
|
||||
}
|
||||
return value;
|
||||
},
|
||||
// 将形如:2025-03-18 +12 (W +2) | 2025-03-16 + 16 ... 按日期升序排序
|
||||
sortRoomCountByDate(roomCountValue) {
|
||||
if (roomCountValue === null || roomCountValue === undefined || roomCountValue === '') return '-';
|
||||
const input = String(roomCountValue).trim();
|
||||
if (!input) return '-';
|
||||
const dateRegex = /^(\d{4}-\d{2}-\d{2})/;
|
||||
|
||||
// 新格式:类似 2026-04-01(100,W+0),2026-04-03(100,W+0),...(逗号分隔,括号内部也包含逗号)
|
||||
// 不能简单 split(','),提取每个完整的 “YYYY-MM-DD(... )” 片段再排序
|
||||
const parts = input.match(/\d{4}-\d{2}-\d{2}\s*[^)]*\([^)]*\)/g);
|
||||
if (!parts || parts.length <= 1) return input;
|
||||
|
||||
const enriched = parts.map((part) => {
|
||||
const m = part.match(dateRegex);
|
||||
const dateStr = m ? m[1] : '';
|
||||
const time = dateStr ? Date.parse(dateStr) : Number.POSITIVE_INFINITY;
|
||||
return { part, time };
|
||||
});
|
||||
enriched.sort((a, b) => {
|
||||
if (a.time === b.time) return a.part.localeCompare(b.part);
|
||||
return a.time - b.time;
|
||||
});
|
||||
|
||||
// 新格式分段之间通常是逗号
|
||||
return enriched.map(x => x.part).join(',');
|
||||
},
|
||||
back() {
|
||||
this.navBack();
|
||||
},
|
||||
toEdit() {
|
||||
// 获取当前轮播图显示的房间信息
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
if (currentRoom) {
|
||||
// 从 bookingListData 中获取原始日期范围作为可选范围
|
||||
// 因为 roomList 中的日期可能已经被修改过
|
||||
const originalBooking = this.bookingListData.find(item => item.id === currentRoom.id);
|
||||
if (originalBooking) {
|
||||
// 可选日期范围保持为原始日期
|
||||
// 注意:selectAbleStart 和 selectAbleEnd 只在数据加载时设置,这里不再修改
|
||||
|
||||
// 但默认显示的日期应该是当前房间的当前日期(可能已经被修改过的)
|
||||
this.calendarStartDate = currentRoom.checkinDate;
|
||||
this.calendarEndDate = currentRoom.checkoutDate;
|
||||
}
|
||||
}
|
||||
this.showCalendar = true;
|
||||
},
|
||||
showApproval() {
|
||||
// 设置当前操作类型为 approve
|
||||
this.currentAction = 'approve';
|
||||
this.iconPath = '../../static/images/warn.png';
|
||||
this.popMsgStr = this.$t("approval.submitApproval");
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.showSubmit = true;
|
||||
},
|
||||
// 底部 Approve:有选中记录或 loading 时不进入 confirmApproval(避免仅样式置灰仍触发)
|
||||
onTabApproveTap() {
|
||||
if (this.approvalLoading || this.roomList.some(r => r.selected)) return;
|
||||
this.confirmApproval();
|
||||
},
|
||||
// 底部 Reject:同上
|
||||
onTabRejectTap() {
|
||||
if (this.approvalLoading || this.roomList.some(r => r.selected)) return;
|
||||
this.confirmReject();
|
||||
},
|
||||
async confirmApproval() {
|
||||
if (this.approvalLoading || this.roomList.some(r => r.selected)) return;
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
|
||||
// 获取当前轮播图显示的房间信息
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
if (currentRoom) {
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
let params = {
|
||||
bookingId: currentRoom.id,
|
||||
checkinDate: currentRoom.checkinDate,
|
||||
checkoutDate: currentRoom.checkoutDate
|
||||
};
|
||||
const res = await submitApproval(params);
|
||||
this.showMsgBox = false;
|
||||
if (res.success == true) {
|
||||
this.iconPath = '../../static/images/ico_suc.png';
|
||||
this.popMsgStr = this.$t("bookingConfirm.approvalSuccess");
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.showSubmit = false;
|
||||
} else {
|
||||
this.buttonStr = this.$t("common.ok");
|
||||
this.iconPath = '../../static/images/ico_err.png';
|
||||
this.msgStr = res.message!=null?res.message:this.$t("common.approvalFail");
|
||||
this.url = '';
|
||||
this.showReturnMsgBox = true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg, 5000);
|
||||
var request = e.config != undefined ? JSON.stringify(e.config) : "";
|
||||
var response = e.data != undefined ? JSON.stringify(e.data) : "";
|
||||
await this.writeLog(this.userData.userId, "find_player", "",
|
||||
"[APP][findPlayer.vue][getProfileByPlayerId][Catch Exception]" + e.errMsg, request,
|
||||
response, 1, false);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
|
||||
},
|
||||
async getApprovalDetailData(playerId) {
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
try {
|
||||
// 如果传入了 playerId,则使用传入的,否则使用 searchPlayerId
|
||||
const targetPlayerId = playerId || this.searchPlayerId;
|
||||
let params = {
|
||||
playerId: targetPlayerId
|
||||
};
|
||||
const res = await getApprovalData(params);
|
||||
if (res.success == true) {
|
||||
if (res.data !== null) {
|
||||
this.bookingListData = res.data.bookingsViewList;
|
||||
this.approvalGamingDataList = res.data.approvalGamingData || [];
|
||||
const routingList = res.data.cfgApprovalRoutingList;
|
||||
if (Array.isArray(routingList) && routingList.length > 0) {
|
||||
this.approvalRoutingList = routingList;
|
||||
} else if (res.data.cfgApprovalRouting) {
|
||||
this.approvalRoutingList = [res.data.cfgApprovalRouting];
|
||||
} else {
|
||||
this.approvalRoutingList = [];
|
||||
}
|
||||
|
||||
// 将 bookingListData 转换为 roomList 格式
|
||||
if (this.bookingListData && this.bookingListData.length > 0) {
|
||||
this.roomList = this.bookingListData.map(item => {
|
||||
// 格式化日期,添加星期和月份
|
||||
const formatDate = (dateStr) => {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||
const weekday = weekdays[date.getDay()];
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
return `(${weekday})${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
bookingId: item.id, // 保存 bookingId 用于匹配 approvalGamingData
|
||||
date: formatDate(item.checkinDate),
|
||||
checkinDate: item.checkinDate, // 保存原始入住日期
|
||||
endDate: formatDate(item.checkoutDate),
|
||||
checkoutDate: item.checkoutDate, // 保存原始退房日期
|
||||
roomInfo: `${item.propertyName || ''}, ${item.room || ''}`.trim(),
|
||||
selected: false,
|
||||
sharer: item.sharer || '-',
|
||||
remark: item.remark
|
||||
};
|
||||
});
|
||||
|
||||
// 切换 player 后重置轮播索引,避免 new roomList 更短导致取不到数据
|
||||
this.currentRoomIndex = 0;
|
||||
|
||||
// 数据加载完成后,获取当前房间的日期作为可选范围
|
||||
if (this.roomList.length > 0) {
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
if (currentRoom) {
|
||||
this.selectAbleStart = currentRoom.checkinDate;
|
||||
this.selectAbleEnd = currentRoom.checkoutDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新当前玩家在列表中的位置
|
||||
this.updateCurrentPlayerIndex(targetPlayerId);
|
||||
|
||||
uni.hideLoading();
|
||||
}
|
||||
} else {
|
||||
this.msgStr = res.message;
|
||||
this.showMsg = true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg, 5000);
|
||||
var request = e.config != undefined ? JSON.stringify(e.config) : "";
|
||||
var response = e.data != undefined ? JSON.stringify(e.data) : "";
|
||||
await this.writeLog(this.userData.userId, "find_player", "",
|
||||
"[APP][findPlayer.vue][getProfileByPlayerId][Catch Exception]" + e.errMsg, request,
|
||||
response, 1, false);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
closePopup() {
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
cancelDate() {
|
||||
this.showCalendar = false;
|
||||
},
|
||||
confirmDate(e) {
|
||||
// e 是选择的日期数组,格式为 [开始日期, 结束日期]
|
||||
if (e) {
|
||||
const startDate = e[0];
|
||||
const endDate = e[e.length - 1];
|
||||
|
||||
// 获取当前轮播图显示的房间信息
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
if (currentRoom) {
|
||||
// 更新原始日期字段
|
||||
currentRoom.checkinDate = startDate;
|
||||
currentRoom.checkoutDate = endDate;
|
||||
|
||||
// 更新显示用的格式化日期
|
||||
// 这里需要重新格式化日期,保持与之前相同的格式
|
||||
const formatDateForDisplay = (dateStr) => {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||
const weekday = weekdays[date.getDay()];
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
return `(${weekday})${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
const formatEndDateForDisplay = (dateStr) => {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||
const weekday = weekdays[date.getDay()];
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
return `(${weekday})${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
currentRoom.date = formatDateForDisplay(startDate);
|
||||
currentRoom.endDate = formatEndDateForDisplay(endDate);
|
||||
|
||||
}
|
||||
}
|
||||
this.showCalendar = false;
|
||||
},
|
||||
// 日期格式化方法
|
||||
formatDate(timestamp) {
|
||||
if (!timestamp) return '-';
|
||||
const date = new Date(timestamp);
|
||||
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}`;
|
||||
},
|
||||
// 更新当前玩家在列表中的位置
|
||||
updateCurrentPlayerIndex(playerId) {
|
||||
if (this.approvalPlayerList && this.approvalPlayerList.length > 0) {
|
||||
const currentIndex = this.approvalPlayerList.findIndex(item => item.playerId === playerId);
|
||||
if (currentIndex !== -1) {
|
||||
this.currentPlayerIndex = currentIndex;
|
||||
// 更新 canPrevious 和 canNext
|
||||
this.canPrevious = currentIndex > 0;
|
||||
this.canNext = currentIndex < this.approvalPlayerList.length - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
backToNotification() {
|
||||
this.navBack();
|
||||
},
|
||||
toPreviousRecord() {
|
||||
if (this.canPrevious === true) {
|
||||
// 导航到上一个玩家
|
||||
const previousIndex = this.currentPlayerIndex - 1;
|
||||
if (previousIndex >= 0 && this.approvalPlayerList[previousIndex]) {
|
||||
const previousPlayerId = this.approvalPlayerList[previousIndex].playerId;
|
||||
// 先重置轮播索引,避免切换过程中出现空白
|
||||
this.currentRoomIndex = 0;
|
||||
this.getApprovalDetailData(previousPlayerId);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
},
|
||||
toNextRecord() {
|
||||
if (this.canNext === true) {
|
||||
// 导航到下一个玩家
|
||||
const nextIndex = this.currentPlayerIndex + 1;
|
||||
if (nextIndex < this.approvalPlayerList.length && this.approvalPlayerList[nextIndex]) {
|
||||
const nextPlayerId = this.approvalPlayerList[nextIndex].playerId;
|
||||
// 先重置轮播索引,避免切换过程中出现空白
|
||||
this.currentRoomIndex = 0;
|
||||
this.getApprovalDetailData(nextPlayerId);
|
||||
}
|
||||
}
|
||||
},
|
||||
// 处理轮播图切换事件
|
||||
handleSwiperChange(e) {
|
||||
this.currentRoomIndex = e.detail.current;
|
||||
this.updateSelectableDates();
|
||||
},
|
||||
// 触摸开始事件
|
||||
touchStart(e) {
|
||||
this.touchStartX = e.touches[0].clientX;
|
||||
},
|
||||
// 触摸结束事件
|
||||
touchEnd(e) {
|
||||
this.touchEndX = e.changedTouches[0].clientX;
|
||||
this.handleSwipe();
|
||||
},
|
||||
// 处理滑动事件
|
||||
handleSwipe() {
|
||||
const swipeThreshold = 30; // 滑动阈值
|
||||
// 向左滑动
|
||||
if (this.touchStartX - this.touchEndX > swipeThreshold) {
|
||||
this.currentRoomIndex = (this.currentRoomIndex + 1) % this.roomList.length;
|
||||
this.updateSelectableDates();
|
||||
}
|
||||
// 向右滑动
|
||||
else if (this.touchEndX - this.touchStartX > swipeThreshold) {
|
||||
this.currentRoomIndex = (this.currentRoomIndex - 1 + this.roomList.length) % this.roomList.length;
|
||||
this.updateSelectableDates();
|
||||
}
|
||||
},
|
||||
// 更新可选日期范围
|
||||
updateSelectableDates() {
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
if (currentRoom) {
|
||||
// 从 bookingListData 中获取原始日期范围作为可选范围
|
||||
const originalBooking = this.bookingListData.find(item => item.id === currentRoom.id);
|
||||
if (originalBooking) {
|
||||
// 可选日期范围保持为原始日期
|
||||
this.selectAbleStart = originalBooking.checkinDate;
|
||||
this.selectAbleEnd = originalBooking.checkoutDate;
|
||||
|
||||
// 但默认显示的日期应该是当前房间的当前日期(可能已经被修改过的)
|
||||
this.calendarStartDate = currentRoom.checkinDate;
|
||||
this.calendarEndDate = currentRoom.checkoutDate;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 切换房间选择状态
|
||||
toggleSelection(index) {
|
||||
this.roomList[index].selected = !this.roomList[index].selected;
|
||||
},
|
||||
showReject() {
|
||||
// 设置当前操作类型为 reject
|
||||
this.currentAction = 'reject';
|
||||
this.iconPath = '../../static/images/ico_err.png';
|
||||
this.popMsgStr = this.$t("approval.submitReject");
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.showSubmit = true;
|
||||
},
|
||||
|
||||
async confirmReject() {
|
||||
if (this.approvalLoading || this.roomList.some(r => r.selected)) return;
|
||||
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
|
||||
// 获取当前轮播图显示的房间信息
|
||||
const currentRoom = this.roomList[this.currentRoomIndex];
|
||||
|
||||
try {
|
||||
let params = {
|
||||
bookingId: currentRoom.id
|
||||
};
|
||||
const res = await rejectApproval(params);
|
||||
if (res.success == true) {
|
||||
if (res.data !== null) {
|
||||
this.iconPath = '../../static/images/ico_suc.png';
|
||||
this.popMsgStr = this.$t("bookingConfirm.rejectSuccess");
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.showSubmit = false;
|
||||
}
|
||||
} else {
|
||||
this.buttonStr = this.$t("common.ok");
|
||||
this.iconPath = '../../static/images/ico_err.png';
|
||||
this.msgStr = res.message!=null?res.message:this.$t("common.rejectFail");
|
||||
this.url = '';
|
||||
this.showReturnMsgBox = true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg, 5000);
|
||||
var request = e.config != undefined ? JSON.stringify(e.config) : "";
|
||||
var response = e.data != undefined ? JSON.stringify(e.data) : "";
|
||||
await this.writeLog(this.userData.userId, "find_player", "",
|
||||
"[APP][findPlayer.vue][getProfileByPlayerId][Catch Exception]" + e.errMsg, request,
|
||||
response, 1, false);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
|
||||
// 延时显示Success
|
||||
setTimeout(() => {}, 1000);
|
||||
},
|
||||
// 批量批准
|
||||
async handleBatchApprove() {
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
|
||||
try {
|
||||
const selectedRooms = this.roomList.filter(room => room.selected);
|
||||
|
||||
// 新建参数,包含每个房间的 RoomId、checkindate 和 checkoutdate
|
||||
const roomInfoList = selectedRooms.map(room => ({
|
||||
bookingId: room.id,
|
||||
checkinDate: room.checkinDate,
|
||||
checkoutDate: room.checkoutDate
|
||||
}));
|
||||
|
||||
const params = {submitInfoList:roomInfoList};
|
||||
const res = await batchSubmitApproval(params);
|
||||
|
||||
this.showMsgBox = false;
|
||||
if (res.success == true) {
|
||||
this.iconPath = '../../static/images/suc.png';
|
||||
this.popMsgStr = this.$t("bookingConfirm.approvalSuccess");
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.showSubmit = false;
|
||||
} else {
|
||||
this.buttonStr = this.$t("common.ok");
|
||||
this.iconPath = '../../static/images/ico_err.png';
|
||||
this.msgStr = res.message!=null?res.message:this.$t("common.appro")
|
||||
this.url = '';
|
||||
this.showReturnMsgBox = true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg, 5000);
|
||||
var request = e.config != undefined ? JSON.stringify(e.config) : "";
|
||||
var response = e.data != undefined ? JSON.stringify(e.data) : "";
|
||||
await this.writeLog(this.userData.userId, "batch_approval", "",
|
||||
"[APP][playerDetail.vue][handleBatchApprove][Catch Exception]" + e.errMsg, request,
|
||||
response, 1, false);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
|
||||
this.roomList.forEach(room => room.selected = false);
|
||||
},
|
||||
// 批量拒绝
|
||||
async handleBatchReject() {
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
|
||||
try {
|
||||
const selectedRooms = this.roomList.filter(room => room.selected);
|
||||
|
||||
// 新建参数,包含每个房间的 RoomId、checkindate 和 checkoutdate
|
||||
const roomInfoList = selectedRooms.map(room => ({
|
||||
bookingId: room.id
|
||||
}));
|
||||
|
||||
const params = {submitInfoList:roomInfoList};
|
||||
const res = await batchSubmitReject(params);
|
||||
|
||||
this.showMsgBox = false;
|
||||
if (res.success == true) {
|
||||
this.iconPath = '../../static/images/suc.png';
|
||||
this.popMsgStr = this.$t("bookingConfirm.rejectSuccess");
|
||||
this.showMsgBox = true; // 显示整个弹窗
|
||||
this.showSubmit = false;
|
||||
} else {
|
||||
this.buttonStr = this.$t("common.ok");
|
||||
this.iconPath = '../../static/images/ico_err.png';
|
||||
this.msgStr = this.$t("common.rejectFail") +":"+ res.message;
|
||||
this.url = '';
|
||||
this.showReturnMsgBox = true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg, 5000);
|
||||
var request = e.config != undefined ? JSON.stringify(e.config) : "";
|
||||
var response = e.data != undefined ? JSON.stringify(e.data) : "";
|
||||
await this.writeLog(this.userData.userId, "batch_approval", "",
|
||||
"[APP][playerDetail.vue][handleBatchApprove][Catch Exception]" + e.errMsg, request,
|
||||
response, 1, false);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
this.roomList.forEach(room => room.selected = false);
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
// 手动触发水印更新,确保水印在页面显示时正确显示
|
||||
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);
|
||||
});
|
||||
},
|
||||
onLoad(opt) {
|
||||
|
||||
this.deviceData = uni.getStorageSync("deviceData");
|
||||
this.windowWidth = this.deviceData.windowWidth - 70;
|
||||
this.searchPlayerId = opt.playerId;
|
||||
this.approvalPlayerList = uni.getStorageSync("approvalPlayerList");
|
||||
|
||||
if (this.searchPlayerId != null) this.getApprovalDetailData()
|
||||
},
|
||||
onReady() {
|
||||
// 页面首次渲染完成后,延迟触发水印更新
|
||||
setTimeout(() => {
|
||||
console.log('[TodoList] Triggering watermark update on ready');
|
||||
const watermarkStore = require('@/store/watermark.js');
|
||||
if (watermarkStore && watermarkStore.updateWatermark) {
|
||||
watermarkStore.updateWatermark(true);
|
||||
}
|
||||
}, 1200);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 悬浮栏样式 - 显示在tabbar上方 */
|
||||
.floating-bar {
|
||||
position: fixed;
|
||||
bottom: 65px;
|
||||
/* tabbar高度 */
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #ffffff;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
border-radius: 25px;
|
||||
padding: 10px 15px;
|
||||
margin: 0px 10px;
|
||||
z-index: 99;
|
||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.floating-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.selected-count {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.floating-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.approve-btn {
|
||||
background-color: #C39A4B;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.reject-btn {
|
||||
background-color:#C39A4B;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.infoButton {
|
||||
border-bottom: 0.5px #999 solid;
|
||||
padding-bottom: 6px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.dataMargin {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar
|
||||
:safeAreaInsetTop="true"
|
||||
:placeholder="true"
|
||||
:title="title"
|
||||
:fixed="true"
|
||||
:autoBack="false"
|
||||
leftIconColor="#C39A4B"
|
||||
bgColor="#C39A4B"
|
||||
titleStyle="font-weight:bold;color:#ffffff;"
|
||||
>
|
||||
<view
|
||||
@click="logout()"
|
||||
style="margin-top:2px;margin-right:3px;"
|
||||
slot="right"
|
||||
>
|
||||
<image src="../../static/images/ico_exit.png" style="width:24px;height:24px;"></image>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<view class="hz-flex-row" style="justify-content: center;margin-top:40px;">
|
||||
<image src="/static/images/location_fail.png" style="width:160px;height:160px;"></image>
|
||||
</view>
|
||||
<view class="hz-flex-row hz-font-bolder hz-font-md" style="margin:20px;">
|
||||
{{message}}
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-md" style="margin:20px;">
|
||||
{{reson}}:{{resonMsg}}
|
||||
</view>
|
||||
<view class="hz-flex-row hz-spacing" style="justify-content: center;">
|
||||
<view @click="checkLocationAndVPN(true)" class="hz-btn hz-bg-primary hz-font-lg hz-font-bold hz-font-color-white hz-text-center" style="width: 150px;">{{$t("region.retry")}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 数据变量
|
||||
userData:null,
|
||||
deviceData:null,
|
||||
siteData:null,
|
||||
// 界面变量
|
||||
userName:'',
|
||||
title: this.$t("region.title"),
|
||||
message:this.$t("region.showMessage"),
|
||||
reson: this.$t("region.reson"),
|
||||
resonMsg:"",
|
||||
}
|
||||
},
|
||||
onLoad(prop) {
|
||||
// 初始化界面
|
||||
//uni.setLocale("en") //測試切換語言en or zh-Hant
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
if(prop!==null && prop!==undefined && prop.type!==null && prop.type!==undefined && prop.type!==''){
|
||||
if(prop.type == '1'){
|
||||
this.resonMsg = this.$t("region.resonMsglocationErr")
|
||||
}
|
||||
if(prop.type == '2'){
|
||||
this.resonMsg = this.$t("region.resonMsgVPNErr")
|
||||
}
|
||||
if(prop.type == '3'){
|
||||
this.resonMsg = this.$t("region.resonMsgFunctionErr")
|
||||
}
|
||||
if(prop.type == '4'){
|
||||
this.resonMsg = this.$t("region.resonMsgNotInMacau")
|
||||
}
|
||||
if(prop.type == '5'){
|
||||
this.resonMsg = this.$t("region.resonMsgOpenVPN")
|
||||
}
|
||||
if(prop.type == '6'){
|
||||
this.resonMsg = this.$t("region.resonMsgNotInMacauOpenVpn")
|
||||
}
|
||||
if(prop.type == '7'){
|
||||
this.resonMsg = this.$t("region.resonMsgNotInMacauIP")
|
||||
}
|
||||
}
|
||||
},
|
||||
onShow(){
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
this.userName = this.userData.userName + " (" + this.userData.userId+")";
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
computed:{
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<view class="hz-pd-16">
|
||||
<u-navbar @leftClick="back()" :safeAreaInsetTop="true" :placeholder="true" :title="title" :fixed="true"
|
||||
:autoBack="false" leftIconColor="#000000" bgColor="#C39A4B" titleStyle="font-weight:bold;color:#ffffff;">
|
||||
</u-navbar>
|
||||
<uni-card>
|
||||
<view style="border-bottom: 0.3px #999 dashed;padding-bottom: 6px;">
|
||||
<view style="">
|
||||
<view class="hz-font-bolder hz-font-xl">
|
||||
Macau
|
||||
</view>
|
||||
<view class="hz-font-base">
|
||||
Grand(35),WL+0
|
||||
</view>
|
||||
<view class="hz-font-base">
|
||||
X1(2),Alpha X1+1
|
||||
</view>
|
||||
<view class="hz-font-base">
|
||||
Alpha X2+1,WL+0
|
||||
</view>
|
||||
<view class="hz-font-base">
|
||||
Total(35);Overbook Limit(67)
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="border-bottom: 0.3px #999 dashed;padding-bottom: 6px;margin-top: 6px;">
|
||||
<view>V1 +0,WL +0</view>
|
||||
<view>V2 +4(V2M +1,V2 +3),WL +0</view>
|
||||
<view>V3 +1,WL +0</view>
|
||||
</view>
|
||||
<view style="border-bottom: 0.3px #999 solid;padding-bottom: 6px;margin-top: 6px;">
|
||||
<view>MO GTD Room:95/95; MO GTD Suite:5/5,WL:0</view>
|
||||
<view>Ascott GTD Room:55/54; Ascott GTD Studio:46/46; WL:0</view>
|
||||
<view>H6V GTD Room:10/10: WL:0</view>
|
||||
<view>LMG Room: 10/10;WL:0</view>
|
||||
</view>
|
||||
<view style="border-bottom: 0.3px #999 dashed;padding-bottom: 6px;margin-top: 6px;">
|
||||
<view class="hz-font-xl">MGM Cotai</view>
|
||||
<view>Resort (119)</view>
|
||||
<view>E1+5</view>
|
||||
<view>R1 (5)</view>
|
||||
<view>R2+2</view>
|
||||
<view>Skylofts Room +0</view>
|
||||
<view>Terry</view>
|
||||
<view>Y1+1</view>
|
||||
<view>Y2+0</view>
|
||||
<view>Total (116); Overbook Limit (167)</view>
|
||||
</view>
|
||||
<view class="">
|
||||
<view>S1 +1</view>
|
||||
<view>S2 +6(S2M +4,S2K +2)</view>
|
||||
<view>S3 +1</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: "Room Count",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
this.navBack();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,92 @@
|
||||
<!--sso login-->
|
||||
<template>
|
||||
<view class="container">
|
||||
<web-view :src="url"></web-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
url:'',
|
||||
intervalId:null,
|
||||
newUrl:'',
|
||||
siteData:null
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
if(options && options.uid && options.pwd){
|
||||
let username = options.uid.replaceAll(" ", "+");
|
||||
let password = options.pwd.replaceAll(" ", "+");
|
||||
this.url = this.siteData.internalUrl + this.siteData.apiPath + "/app/sso/login_saml_with_mfa?username="+encodeURIComponent(username)+"&password="+encodeURIComponent(password);
|
||||
}
|
||||
if (options && options.url){
|
||||
this.url = options.url;
|
||||
}
|
||||
this.listenUrl()
|
||||
},
|
||||
onShow() {
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
},
|
||||
methods: {
|
||||
listenUrl() {
|
||||
var that = this;
|
||||
var count = 0;
|
||||
this.intervalId = setInterval(() => {
|
||||
var currentUrl = that.getCurrentUrl();
|
||||
that.newUrl = currentUrl;
|
||||
var code = that.getCurrentQueryString(currentUrl, 'SAMLResponse');
|
||||
var errorCode = that.getCurrentQueryString(currentUrl, 'errorCode');
|
||||
//uni.$u.toast('url1='+currentUrl);
|
||||
if(currentUrl.indexOf('/sso_callback/login')!=-1){
|
||||
//uni.$u.toast('url2='+currentUrl);
|
||||
if (code){
|
||||
//uni.$u.toast('get code');
|
||||
clearInterval(that.intervalId);
|
||||
uni.redirectTo({
|
||||
url:'/pages/login/login?code='+encodeURIComponent(code)
|
||||
})
|
||||
}
|
||||
else if (errorCode){
|
||||
//uni.$u.toast('get errorcode');
|
||||
clearInterval(that.intervalId);
|
||||
uni.redirectTo({
|
||||
url:'/pages/idpLogin/idpLogin?errorCode='+encodeURIComponent(errorCode)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}, 1000);
|
||||
},
|
||||
getCurrentQueryString(url, name) {
|
||||
try{
|
||||
var queryString = url.substring(url.indexOf('?'));
|
||||
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
|
||||
var r = queryString.substr(1).match(reg);
|
||||
if (r != null) {
|
||||
return unescape(r[2]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch(e){
|
||||
uni.$u.toast('getCurrentQueryString exception:'+e.errMsg);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
getCurrentUrl(){
|
||||
var pages = getCurrentPages();
|
||||
var page = pages[pages.length - 1];
|
||||
var currentWebview = page.$getAppWebview();
|
||||
var url = currentWebview.children()[0].getURL();
|
||||
console.log("=======当前地址======", url);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,454 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar
|
||||
:safeAreaInsetTop="true"
|
||||
:placeholder="true"
|
||||
:title="title"
|
||||
:fixed="true"
|
||||
:autoBack="false"
|
||||
leftIconColor="#C39A4B"
|
||||
bgColor="#C39A4B"
|
||||
titleStyle="font-weight:bold;color:#ffffff;"
|
||||
>
|
||||
<view @click="logout"
|
||||
style="margin-top:2px;margin-right:3px;"
|
||||
slot="right"
|
||||
>
|
||||
<image src="../../static/images/ico_exit.png" style="width:24px;height:24px;"></image>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;margin-top:5px;border-bottom:1rpx solid #ddd;height:80rpx;line-height:90rpx;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">{{$t("common.user")}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;height:90rpx;line-height: 22px;padding-top: 8px;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;color:#666;">{{userName}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<!-- <view v-if="show" style="margin-left:20px;margin-right:20px;border-bottom:1rpx solid #ddd;height:90rpx;line-height:90rpx;">
|
||||
<u-row>
|
||||
<u-col span="4" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">{{$t("common.block")}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="8">
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-text-right hz-font-md" style="color:#666;margin-right:16rpx;width:100%;">{{userData.block}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view> -->
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;border-bottom:1rpx solid #ddd;height:80rpx;line-height:90rpx;margin-top:2px">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">{{$t("common.department")}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;height:90rpx;line-height: 22px;padding-top: 8px;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;color:#666;">{{userData.department}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;border-bottom:1rpx solid #ddd;height:80rpx;line-height:90rpx;margin-top:2px">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">{{$t("common.division")}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;height:90rpx;line-height: 22px;padding-top: 8px;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;color:#666;">{{userData.division}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;border-bottom:1rpx solid #ddd;height:80rpx;line-height:90rpx;margin-top:2px">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">{{$t("common.section")}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;height:90rpx;line-height: 22px;padding-top: 8px;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;color:#666;">{{userData.section}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;border-bottom:1rpx solid #ddd;height:80rpx;line-height:90rpx;margin-top:2px">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">{{$t("common.language")}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" @click="popupLang" style="margin-left:20px;margin-right:20px;height:80rpx;line-height: 27px;padding-top: 8px;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;color:#666;">{{lang}}</view>
|
||||
<u-icon name="arrow-right" color="#666;" style="margin-left: auto;"></u-icon>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" style="margin-left:20px;margin-right:20px;border-bottom:1rpx solid #ddd;height:80rpx;line-height:90rpx;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">{{$t("common.version")}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" @click="openDebugMode" style="margin-left:20px;margin-right:20px;height:80rpx;line-height: 27px;padding-top: 8px;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;color:#666;">{{siteData.version}}</view>
|
||||
<u-icon name="arrow-right" color="#666;" style="margin-left: auto;"></u-icon>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<!-- <view v-if="show" style="margin-left:20px;margin-right:20px;border-bottom:1rpx solid #ddd;height:80rpx;line-height:90rpx;margin-top:2px">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;">Delegate Approval Request</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view v-if="show" @click="showDelegate()" style="margin-left:20px;margin-right:20px;height:80rpx;line-height: 27px;padding-top: 8px;">
|
||||
<u-row>
|
||||
<u-col span="12" >
|
||||
<view class="hz-flex-row">
|
||||
<view class="hz-font-md" style="margin-left:16rpx;color:#666;">{{userStatus}}</view>
|
||||
<u-icon name="arrow-right" color="#666;" style="margin-left: auto;"></u-icon>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view> -->
|
||||
<u-picker closeOnClickOverlay :show="showPicker" :defaultIndex="currentLangIndex" :columns="langList"
|
||||
@close="showPicker=false" :cancelText="cancelText" :confirmText="okText" confirmColor="#C39A4B"
|
||||
@cancel="showPicker=false" @confirm="confirmLang" keyName="name">
|
||||
</u-picker>
|
||||
<!-- <u-popup
|
||||
:safeAreaInsetBottom="true"
|
||||
:safeAreaInsetTop="true"
|
||||
:mode="'center'"
|
||||
:round="12"
|
||||
:show="showMsgBox"
|
||||
customStyle="width:94%; padding-top: 30px"
|
||||
:closeable="!showDirBtn"
|
||||
@close="closePopup()"
|
||||
>
|
||||
<view>
|
||||
<view class="hz-flex-row" style="margin: 30px 30px;">
|
||||
<view style="width: 40%;">
|
||||
Status
|
||||
</view>
|
||||
<view style=" display: flex; align-items: center;">
|
||||
<view style="margin-right: 10px; font-size: 14px; color: #333;">{{ userStatus === 'ON' ? 'ON' : 'OFF' }}</view>
|
||||
<u-switch v-model="userStatus" @change="handleStatusChange"
|
||||
activeValue="ON" inactiveValue="OFF" activeColor="#C39A4B" inactiveColor="#999" size="30"></u-switch>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row" style="margin: 30px 30px;width: 100%;">
|
||||
<view style="width: 30%; flex-shrink: 0;">
|
||||
Delegate to
|
||||
</view>
|
||||
<view style="margin-left: auto; flex: 1;">
|
||||
<lu-data-select placeholder="Select Other Approver" :options="selectData" v-model="selectedApprover"
|
||||
:multiple="false" :filterable="true" @change="onchange" style="width: 78%;" :clearable="false"></lu-data-select>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hz-flex-row" style="margin: 30px 30px;width: 100%;">
|
||||
<view style="width: 30%; flex-shrink: 0;">
|
||||
Date
|
||||
</view>
|
||||
<view style="width: 55%;">
|
||||
<uni-datetime-picker class="delegate-data-picker" v-model="range" type="daterange" :clearIcon="false" @maskClick="maskClick" />
|
||||
</view>
|
||||
</view>
|
||||
<view @click="saveDelegate()" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 15px;">
|
||||
{{$t("common.confirm").toUpperCase()}}
|
||||
</view>
|
||||
<view @click="closePopup()" class="hz-btn hz-font-color-primary hz-font-lg hz-font-bold hz-text-center"
|
||||
style="width: 90%;margin: 0 auto;margin-bottom: 30px;background-color: white;border: 0.5px solid;">
|
||||
{{$t("common.cancel").toUpperCase()}}
|
||||
</view>
|
||||
</view>
|
||||
</u-popup> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {logout} from '../../api/commonApi.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 数据变量
|
||||
userData:null,
|
||||
deviceData:null,
|
||||
siteData:null,
|
||||
langList:[
|
||||
[{
|
||||
name: 'English',
|
||||
code: 'en'
|
||||
}, {
|
||||
name: '繁體中文',
|
||||
code: 'zh-Hant'
|
||||
}]
|
||||
],
|
||||
// 界面变量
|
||||
show:false,
|
||||
showPicker:false,
|
||||
cancelText:this.$t("common.cancel"),
|
||||
confirmText:this.$t("common.confirm").toUpperCase(),
|
||||
okText:this.$t("common.ok"),
|
||||
userName:'',
|
||||
showMsgBox:false,
|
||||
showDirBtn:false,
|
||||
userStatus:'ON',
|
||||
selectedApprover:"",
|
||||
lang:',',
|
||||
currentLangIndex:[0],
|
||||
title: this.$t("setting.title"),
|
||||
single: "2021-04-3",
|
||||
today: new Date(),
|
||||
range: [],
|
||||
selectData:[{
|
||||
value: '1',
|
||||
label: 'Corso'
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: 'Mauve',
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: 'Calmi',
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化界面
|
||||
//this.redirectByPermission(this.userData,false);
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
this.show = true;
|
||||
this.lang = this.mapLocale(uni.getLocale());
|
||||
// 初始化 range 变量
|
||||
this.range = [this.today, new Date(this.today.getTime() + 24 * 60 * 60 * 1000)];
|
||||
},
|
||||
onShow(){
|
||||
//uni.setLocale("en") //測試切換語言en or zh-Hant
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
this.userName = this.userData.userName + " (" + this.userData.userId+")";
|
||||
// const userPoint = turf.point([113.560831,22.224397]);
|
||||
// // console.log(userPoint,point)
|
||||
// let fea = point.features
|
||||
// for(let i =0;i<fea.length;i++){
|
||||
// let co = fea[i];
|
||||
// // console.log(co.geometry)
|
||||
// for(let j = 0 ;j<co.geometry.coordinates.length;j++){
|
||||
// let geo = co.geometry.coordinates[j];
|
||||
// console.log(geo)
|
||||
// let po = turf.polygon(geo[0]);
|
||||
// // console.log(po)
|
||||
// const isInside = turf.booleanPointInPolygon(userPoint, [geo]);
|
||||
// console.log(isInside)
|
||||
// }
|
||||
// }
|
||||
|
||||
},
|
||||
onReady(){
|
||||
if (this.userData !== null && this.userData !== undefined)
|
||||
this.showTabbarByPermission(this.userData);
|
||||
},
|
||||
methods: {
|
||||
async logout(){
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
try{
|
||||
let params = {};
|
||||
const res = await logout(params);
|
||||
if(res.success == true){
|
||||
if(res.data !== null){
|
||||
if(this.siteData.mockSSO==false&&!this.siteData.internalTag){
|
||||
//this.logoutWithADFSApp()
|
||||
uni.redirectTo({
|
||||
url:'/pages/azureLogout/azureLogout'
|
||||
});
|
||||
}else{
|
||||
uni.removeStorageSync("userData");
|
||||
uni.removeStorageSync("token");
|
||||
uni.removeStorageSync("idToken");
|
||||
this.navTo('/pages/login/login',2,false);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(this.siteData.mockSSO==false&&!this.siteData.internalTag){
|
||||
//this.logoutWithADFSApp()
|
||||
uni.redirectTo({
|
||||
url:'/pages/azureLogout/azureLogout'
|
||||
});
|
||||
}else{
|
||||
uni.removeStorageSync("userData");
|
||||
uni.removeStorageSync("token");
|
||||
uni.removeStorageSync("idToken");
|
||||
this.navTo('/pages/login/login',2,false);
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
uni.$u.toast(e.errMsg,5000);
|
||||
await this.writeLog(this.userData.userId,"logout","","[APP][setting.vue][logout][Catch Exception]"+e.errMsg,"","",1,false);
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
popupLang(){
|
||||
this.currentLangIndex = [];
|
||||
for(let i=0;i<this.langList[0].length;i++){
|
||||
if(this.langList[0][i].code === uni.getLocale()){
|
||||
this.currentLangIndex.push(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.showPicker = true;
|
||||
},
|
||||
showDelegate() {
|
||||
this.showMsgBox = true;
|
||||
},
|
||||
confirmLang(e){
|
||||
uni.setLocale(e.value[0].code);
|
||||
this.$i18n.locale = e.value[0].code;
|
||||
this.lang = e.value[0].name;
|
||||
this.title = this.$t("setting.title");
|
||||
this.cancelText=this.$t("common.cancel");
|
||||
this.okText=this.$t("common.ok");
|
||||
// App 端 tabBar 文案不会自动跟随 i18n 刷新,需要手动更新
|
||||
// #ifdef APP-PLUS
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
// pages.json tabBar.list 顺序:
|
||||
// 0 dashboard, 1 todo, 2 hotel(findPlayer), 3 setting
|
||||
uni.setTabBarItem({ index: 0, text: this.$t("dashboard.title") });
|
||||
uni.setTabBarItem({ index: 1, text: this.$t("todo.title") });
|
||||
uni.setTabBarItem({ index: 2, text: this.$t("hotel.title") });
|
||||
uni.setTabBarItem({ index: 3, text: this.$t("setting.title") });
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
this.showPicker = false;
|
||||
},
|
||||
openDebugMode(){
|
||||
let count = uni.getStorageSync("countOfDebugMode");
|
||||
if(count===undefined || count===''){
|
||||
count = 0;
|
||||
}
|
||||
count++;
|
||||
uni.setStorageSync("countOfDebugMode",count);
|
||||
if(count === 5){
|
||||
if(this.siteData.debugMode === false){
|
||||
this.siteData.debugMode = true;
|
||||
uni.$u.toast(this.$t("common.debugMode") + ": ON");
|
||||
}
|
||||
else{
|
||||
this.siteData.debugMode = false;
|
||||
uni.$u.toast(this.$t("common.debugMode") + ": OFF");
|
||||
}
|
||||
uni.setStorageSync("siteData",this.siteData);
|
||||
uni.removeStorageSync("countOfDebugMode");
|
||||
|
||||
}
|
||||
},
|
||||
saveDelegate(){
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
closePopup(){
|
||||
this.showMsgBox = false;
|
||||
},
|
||||
handleStatusChange(value){
|
||||
this.userStatus = value;
|
||||
},
|
||||
onchange(value){
|
||||
this.selectedApprover = value;
|
||||
},
|
||||
maskClick(){
|
||||
console.log("date");
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
mapLocale() {
|
||||
return function (lang) {
|
||||
if(lang=='zh-Hant'){
|
||||
return '繁體中文';
|
||||
}else{
|
||||
return 'English';
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .uni-calendar__content{
|
||||
bottom: 0 !important;
|
||||
}
|
||||
|
||||
::v-deep .uni-calendar .uni-calendar__content .uni-date-changed .uni-datetime-picker--btn {
|
||||
background-color: #C39A4B !important;
|
||||
}
|
||||
|
||||
::v-deep .uni-calendar-item__weeks-box .uni-calendar-item--checked {
|
||||
background-color: #C39A4B !important;
|
||||
}
|
||||
|
||||
::v-deep .uni-calendar-item--multiple .uni-calendar-item--before-checked {
|
||||
background-color: #C39A4B !important;
|
||||
}
|
||||
|
||||
::v-deep .uni-calendar-item--multiple .uni-calendar-item--after-checked {
|
||||
background-color: #C39A4B !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="hz-text-center" style="padding-top:200rpx;">
|
||||
<image src="../../static/images/logo.png" style="width:138rpx;height:140rpx;"></image>
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-primary">
|
||||
{{$t('common.appName')}}
|
||||
</view>
|
||||
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-dark" style="margin-top:160rpx;">
|
||||
Mockup IDP Login
|
||||
</view>
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<u--input
|
||||
v-model="userId"
|
||||
placeholder="Login User ID"
|
||||
prefixIcon="account"
|
||||
prefixIconStyle="font-size: 20px;color:#C39A4B;"
|
||||
customStyle="border-radius:22px;"
|
||||
></u--input>
|
||||
</view>
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<u--input
|
||||
v-model="password"
|
||||
placeholder="Login Password"
|
||||
prefixIcon="lock-open"
|
||||
:password="true"
|
||||
prefixIconStyle="font-size: 20px;color: #C39A4B"
|
||||
customStyle="border-radius:22px;"
|
||||
></u--input>
|
||||
</view>
|
||||
<!--<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<u-radio-group
|
||||
v-model="propertyCode"
|
||||
placement="row">
|
||||
<u-radio activeColor="#C39A4B" label="Macau" name="MM" customStyle="width:50%;" @change="changeProperty"></u-radio>
|
||||
<u-radio activeColor="#C39A4B" label="Cotai" name="MC" @change="changeProperty"></u-radio>
|
||||
</u-radio-group>
|
||||
</view>-->
|
||||
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
|
||||
<view @click="mockSSOLogin" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >{{$t("common.loginsso")}}</view>
|
||||
</view>
|
||||
<u-modal :content="msgStr" :show="showMsg" :confirmText="yesText" closeOnClickOverlay @confirm="confirmMsg" confirmColor="#C39A4B" @cancel="cancelMsg" @close="cancelMsg"></u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CryptoJS from 'crypto-js';
|
||||
import {mockUserSSOLogin} from '../../api/ssoApi.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 数据变量
|
||||
userId: '',
|
||||
password:'',
|
||||
propertyCode:'MM',
|
||||
userData:null,
|
||||
deviceData:null,
|
||||
siteData:null,
|
||||
// 界面变量
|
||||
msgStr:'',
|
||||
showMsg:false,
|
||||
yesText:this.$t("common.ok"),
|
||||
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化界面
|
||||
this.initUI();
|
||||
this.siteData = uni.getStorageSync("siteData");
|
||||
this.userData = uni.getStorageSync("userData");
|
||||
},
|
||||
onShow() {
|
||||
},
|
||||
methods: {
|
||||
// 加密方法
|
||||
hashPassword(pwd){
|
||||
if(!pwd){
|
||||
return '';
|
||||
}
|
||||
return CryptoJS.SHA256(pwd).toString(CryptoJS.enc.Hex);
|
||||
},
|
||||
// 数据方法
|
||||
async mockSSOLogin(){
|
||||
uni.showLoading({
|
||||
title: this.$t("common.loading")
|
||||
});
|
||||
try{
|
||||
const encryptedPassword = this.hashPassword(this.password);
|
||||
let params = {userId:this.userId, credential:encryptedPassword, propertyCode:this.propertyCode};
|
||||
const res = await mockUserSSOLogin(params);
|
||||
|
||||
if(res.success === true){
|
||||
if(res.data !== null){
|
||||
uni.redirectTo({
|
||||
url:'/pages/login/login?code=' + res.accessToken
|
||||
})
|
||||
}
|
||||
}else if(res.errorCode!==undefined && res.errorCode == 'ERROR_LOCKED'){
|
||||
this.msgStr = this.$t("common.userLocked");
|
||||
this.showMsg = true;
|
||||
} else if (res != null && res.code == 'ERROR_LOCKED') {
|
||||
this.msgStr = this.$t("common.userLocked");
|
||||
this.showMsg = true;
|
||||
} else if (res != null && res.code == 'ERROR_IP_BANNED') {
|
||||
this.msgStr = this.$t("common.ipLocked");
|
||||
this.showMsg = true;
|
||||
} else {
|
||||
this.msgStr = 'Login failed.';
|
||||
this.showMsg = true;
|
||||
}
|
||||
}catch(e){
|
||||
this.writeLog(this.userId,"mockSSOLogin","","[APP][ssoLogin.vue][mockSSOLogin]catch error"+JSON.stringify(e),"","",1,false);
|
||||
if(e.data !== undefined && e.data.errorCode !== undefined && e.data.errorCode !==""){
|
||||
if(e.data.errorCode == 'ERROR_LOCKED'){
|
||||
this.msgStr = this.$t("common.userLocked");
|
||||
this.showMsg = true;
|
||||
}
|
||||
}else{
|
||||
this.msgStr = "System Error";
|
||||
this.showMsg = true;
|
||||
}
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
// 界面方法
|
||||
changeProperty(e){
|
||||
this.propertyCode = e;
|
||||
},
|
||||
initUI() {
|
||||
this.deviceData = uni.getStorageSync("deviceData");
|
||||
},
|
||||
confirmMsg(){
|
||||
this.showMsg = false;
|
||||
},
|
||||
cancelMsg(){
|
||||
this.showMsg = false;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.u-border {
|
||||
border-width: 0.5px !important;
|
||||
border-color: #434343 !important;
|
||||
border-style: solid;
|
||||
height:30px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user