merge limo to daylight

This commit is contained in:
Mauve
2026-09-22 16:37:00 +08:00
parent 0c92868836
commit a7359d443b
73 changed files with 11614 additions and 1040 deletions
+155 -20
View File
@@ -1,7 +1,35 @@
<template>
<view>
<view>
<mgmHeader ref="headerRef" />
<!-- <mgmHeader ref="headerRef" :showNotification="true" /> -->
<u-navbar
:safeAreaInsetTop="true"
:placeholder="true"
:title="title"
:fixed="true"
:autoBack="false"
leftIconColor="#C39A4B"
bgColor="#C39A4B"
titleStyle="font-weight:bold;color:#ffffff;"
>
<view
@tap="goNotification"
class="notification-bell-wrap"
slot="left"
>
<u-icon name="bell" color="#FFFFFF" size="24"></u-icon>
<view v-if="notificationCount > 0" class="notification-badge">
<text class="notification-badge-text">{{ notificationBadgeText }}</text>
</view>
</view>
<view @tap="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="showDashboardView">
<view class="hz-font-bolder hz-font-l hz-font-color-black hz-text-right"
style="margin-top:36rpx;margin-right:36rpx;">
@@ -109,6 +137,9 @@
import {
logout
} from '../../api/commonApi';
import {
countNotification
} from '../../api/notificationApi';
import {
formatDate
} from '../../common/stringUtils';
@@ -124,6 +155,7 @@
showMsg: false,
okText: this.$t("common.ok"),
dataNull:this.$t("common.dataNotFound"),
title:'',
userData: null,
dashboardData: [],
dataAsOf:"",
@@ -132,10 +164,13 @@
NFROValue: '0',
IMValue: '0',
MRIValue: '0',
showAchievement: false,
showKPI: false,
showKPI:false,
showAchievement:false,
showDashboardView: false,
userSegment: null
userSegment: null,
notificationCount: 0,
notificationCountTimer: null,
isDashboardActive: false
}
},
onLoad(opt) {
@@ -143,19 +178,84 @@
this.initUI();
},
onShow() {
this.isDashboardActive = true;
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.userData = uni.getStorageSync("userData");
if (this.userData !== null && this.userData !== undefined){
this.showTabbarByPermission(this.userData);
this.title = this.userData.userName+','+this.userData.userId;
}
this.getTodoDashboardByuserId();
this.fetchNotificationCount();
this.stopNotificationCountTimer();
this.startNotificationCountTimer();
},
onHide() {
this.isDashboardActive = false;
this.stopNotificationCountTimer();
},
onUnload() {
this.isDashboardActive = false;
this.stopNotificationCountTimer();
},
methods: {
goNotification() {
uni.navigateTo({
url: '/limo/notification/notification'
});
},
getUserIdFromUserData(userData) {
if (userData == null || userData === '') {
return '';
}
const userId = userData.userId != null && userData.userId !== ''
? userData.userId
: userData.UserId;
return userId != null && userId !== '' ? userId : '';
},
parseNotificationCount(res) {
if (res == null) {
return 0;
}
const count = res.count ?? res.Count ?? res.data?.count ?? res.data?.Count;
return Number(count) || 0;
},
async fetchNotificationCount() {
this.userData = uni.getStorageSync('userData');
const userId = this.getUserIdFromUserData(this.userData);
if (!userId) {
this.notificationCount = 0;
return;
}
try {
const res = await countNotification({ userId });
this.notificationCount = this.parseNotificationCount(res);
console.log('[Dashboard] notification count res=', res, 'notificationCount=', this.notificationCount);
} catch (error) {
console.error('[Dashboard] countNotification failed', error);
this.notificationCount = 0;
}
},
startNotificationCountTimer() {
if (!this.notificationCountTimer) {
this.notificationCountTimer = setInterval(() => {
if (this.isDashboardActive) {
this.fetchNotificationCount();
}
}, 30000);
}
},
stopNotificationCountTimer() {
if (this.notificationCountTimer) {
clearInterval(this.notificationCountTimer);
this.notificationCountTimer = null;
}
},
formatNumber(num) {
return num?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") || "0";
},
normalizeDashboardRecord(record) {
record = record || {};
return {
@@ -169,9 +269,6 @@
userSegment: record.userSegment ?? record.UserSegment,
};
},
formatNumber(num) {
return num?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") || "0";
},
async getTodoDashboardByuserId() {
uni.showLoading({
title: this.$t("common.loading")
@@ -181,10 +278,6 @@
let params = {};
requestBody = JSON.stringify(params);
const res = await getTodoDashboard(params);
this.dashboardData = [];
this.dataAsOf = "";
this.userSegment = null;
this.MFValue = this.IMValue = this.NFROValue = this.MRIValue = "0";
if (res.data != null && res.success == true) {
const records = Array.isArray(res.data.records)
? res.data.records
@@ -194,6 +287,7 @@
if (records.length > 0) {
this.dashboardData = records.map((record) => this.normalizeDashboardRecord(record));
this.showDashboardView = true;
// 设置用户类型
this.userSegment = this.dashboardData[0].userSegment;
this.hasTargetValue = this.dashboardData[0].targetValue !== null && this.dashboardData[0].targetValue !== undefined;
@@ -258,7 +352,7 @@
}else if(res.errorCode == 'INVOKE_TODODASHBOARD_API_ERROR'){
this.dataNull = this.$t("todo.invokeError");
}else {
if(String(res.errorCode || res.code || '').toUpperCase().indexOf('NO RECORD') != -1){
if(res.errorCode.toUpperCase().indexOf('NO RECORD') != -1){
this.dataNull = this.$t("common.noRecord");
}else{
this.dataNull = this.$t("todo.returnError");
@@ -282,6 +376,12 @@
}
},
computed: {
notificationBadgeText() {
if (this.notificationCount > 99) {
return '99+';
}
return String(this.notificationCount);
},
getShowAchievement() {
return function(record) {
if (record.type == "Achievement" && record.itemName !=="MF Turnover" && record.itemName !=="IM Turnover"
@@ -375,4 +475,39 @@
.im-text-gold {
color: #cfa34f;
}
.notification-bell-wrap {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
margin-top: 2px;
margin-left: 3px;
width: 24px;
height: 24px;
overflow: visible;
}
.notification-badge {
position: absolute;
top: -4px;
right: -5px;
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 8px;
background-color: #fa3534;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
z-index: 10;
}
.notification-badge-text {
color: #ffffff;
font-size: 10px;
line-height: 1;
font-weight: bold;
}
</style>
+224 -84
View File
@@ -1,5 +1,6 @@
<template>
<view>
<u-navbar
:safeAreaInsetTop="true"
:placeholder="true"
@@ -10,31 +11,33 @@
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
v-if="showNotificationBell"
@click="goNotification"
class="notification-bell-wrap"
slot="left"
>
<u-icon name="bell" color="#FFFFFF" size="24"></u-icon>
<view v-if="notificationCount > 0" class="notification-badge">
<text class="notification-badge-text">{{ notificationBadgeText }}</text>
</view>
</view>
<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-text-center" style="margin-top:120rpx;">
<image src="../../static/images/room_book.png" style="width:128rpx;height:128rpx;"></image>
<image src="/static/images/limo.png" class="mr-[40]" style="width: 58px; height: 58px;"></image>
<image src="/static/images/room_book.png" class="find-player-ico"></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;">
<view class="hz-font-bolder hz-font-xl hz-text-center hz-font-color-dark mt-[160]">
{{$t('findPlayer.title')}}
</view>
<view style="margin-top:30rpx;margin-right:60rpx;margin-left:60rpx;">
@@ -58,7 +61,8 @@
<script>
import { getApprovalCount } from '../../api/approvalApi.js';
import {playerLookup} from '../../api/mgmApi.js'
import {playerLookup} from '../../api/mgmApi.js'
import { countNotification } from '../../api/notificationApi.js'
import mgmHeader from '@/components/header/header.vue'
@@ -67,25 +71,30 @@ import {playerLookup} from '../../api/mgmApi.js'
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
}
return {
// 数据变量
playerIdStr: this.$t("common.playerId"),
searchPlayerId: '',
userData:null,
deviceData:null,
siteData:null,
// 界面变量
showMsg:false,
title: '',
msgStr:'',
yesText:this.$t("common.ok"),
notificationCount: 0,
approvalRoutingCount: 0,
limoNotificationCount: 0,
countAp: '',
// 定时器变量
approvalCountTimer: null,
notificationCountTimer: null,
// 页面激活态(避免残留定时器回调在非当前页继续请求)
isFindPlayerActive: false,
canViewApproval:false
}
},
onLoad() {
// 初始化界面
@@ -95,56 +104,133 @@ import {playerLookup} from '../../api/mgmApi.js'
},
onShow() {
this.isFindPlayerActive = true;
this.getApporvalCount();
// 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);
const realUserData = this.getEffectiveUserData(this.userData);
this.showTabbarByPermission(realUserData);
this.title = realUserData.userName+','+realUserData.userId;
}
this.isLogin();
this.$nextTick(() => {
const header = this.$refs.headerRef;
if(header) {
header.updateUserData();
}
});
this.fetchNotificationCount();
// 切回页面时,先停后启,避免存在残留定时器
this.stopApprovalCountTimer();
this.startApprovalCountTimer();
if(this.userData.canViewApproval!==undefined && this.userData.canViewApproval==true) this.canViewApproval = true;
this.stopNotificationCountTimer();
this.startNotificationCountTimer();
this.canViewApproval = this.effectiveUserData.canViewApproval === true;
},
onHide() {
this.isFindPlayerActive = false;
// 切到其他页面时立即停止定时器,避免后台持续调用
this.stopApprovalCountTimer();
// this.stopApprovalCountTimer();
this.stopNotificationCountTimer();
},
onUnload() {
this.isFindPlayerActive = false;
// 页面销毁时兜底清理
this.stopApprovalCountTimer();
// this.stopApprovalCountTimer();
this.stopNotificationCountTimer();
},
onReady(){
},
methods: {
startApprovalCountTimer() {
if (!this.approvalCountTimer) {
this.approvalCountTimer = setInterval(() => {
// 双保险:非当前页不请求
getEffectiveUserData(userData) {
if (userData && userData.data && typeof userData.data === 'object') {
return userData.data;
}
return userData || {};
},
goNotification() {
const url = this.buildNotificationUrl();
uni.navigateTo({
url
});
},
buildNotificationUrl(extraParams = []) {
const params = extraParams.slice();
if (this.effectiveUserData.canViewNotification === true) {
params.push('notificationCount=' + encodeURIComponent(this.limoNotificationCount));
}
if (this.effectiveUserData.canViewApproval === true) {
params.push('approvalRoutingCount=' + encodeURIComponent(this.approvalRoutingCount));
}
return params.length
? '/limo/notification/notification?' + params.join('&')
: '/limo/notification/notification';
},
getUserIdFromUserData(userData) {
const realUserData = this.getEffectiveUserData(userData);
if (userData == null || userData === '') {
return '';
}
const userId = realUserData.userId != null && realUserData.userId !== ''
? realUserData.userId
: realUserData.UserId;
return userId != null && userId !== '' ? userId : '';
},
parseNotificationCounts(res) {
const data = res && res.data && typeof res.data === 'object' ? res.data : (res || {});
return {
count: Number(data.count ?? data.Count) || 0,
notificationCount: Number(data.notificationCount ?? data.NotificationCount) || 0,
approvalRoutingCount: Number(data.approvalRoutingCount ?? data.ApprovalRoutingCount) || 0,
};
},
async fetchNotificationCount() {
this.userData = uni.getStorageSync('userData');
const userId = this.getUserIdFromUserData(this.userData);
if (!userId) {
this.notificationCount = 0;
this.limoNotificationCount = 0;
this.approvalRoutingCount = 0;
return;
}
try {
const res = await countNotification({ userId });
const counts = this.parseNotificationCounts(res);
this.notificationCount = counts.count;
this.limoNotificationCount = counts.notificationCount;
this.approvalRoutingCount = counts.approvalRoutingCount;
} catch (error) {
console.error('[FindPlayer] countNotification failed', error);
this.notificationCount = 0;
this.limoNotificationCount = 0;
this.approvalRoutingCount = 0;
}
},
startNotificationCountTimer() {
if (!this.notificationCountTimer) {
this.notificationCountTimer = setInterval(() => {
if (this.isFindPlayerActive) {
this.getApporvalCount();
this.fetchNotificationCount();
}
}, 30000); // 30秒
}, 30000);
}
},
stopApprovalCountTimer() {
if (this.approvalCountTimer) {
clearInterval(this.approvalCountTimer);
this.approvalCountTimer = null;
stopNotificationCountTimer() {
if (this.notificationCountTimer) {
clearInterval(this.notificationCountTimer);
this.notificationCountTimer = null;
}
},
// 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){
@@ -155,7 +241,7 @@ import {playerLookup} from '../../api/mgmApi.js'
title: this.$t("common.loading")
});
try{
let params = {playerId:this.searchPlayerId,userId:this.userData.userId};
let params = {playerId:this.searchPlayerId,userId:this.effectiveUserData.userId};
const res = await playerLookup(params);
if(res.success == true){
if(res.data !== null){
@@ -177,38 +263,39 @@ import {playerLookup} from '../../api/mgmApi.js'
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);
await this.writeLog(this.effectiveUserData.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.effectiveUserData.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)
this.navTo(this.buildNotificationUrl(['tab=1']),0,false)
},
clearSearchInput(){
this.searchPlayerId = '';
@@ -222,6 +309,24 @@ import {playerLookup} from '../../api/mgmApi.js'
wv.show();
},
},
computed: {
effectiveUserData() {
return this.getEffectiveUserData(this.userData);
},
showNotificationBell() {
return !!(
this.effectiveUserData &&
(this.effectiveUserData.canViewApproval === true ||
this.effectiveUserData.canViewNotification === true)
);
},
notificationBadgeText() {
if (this.notificationCount > 99) {
return '99+';
}
return String(this.notificationCount);
}
}
}
</script>
@@ -232,4 +337,39 @@ import {playerLookup} from '../../api/mgmApi.js'
border-style: solid;
height:30px;
}
.notification-bell-wrap {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
margin-top: 2px;
margin-left: 3px;
width: 24px;
height: 24px;
overflow: visible;
}
.notification-badge {
position: absolute;
top: -4px;
right: -5px;
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 8px;
background-color: #fa3534;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
z-index: 10;
}
.notification-badge-text {
color: #ffffff;
font-size: 10px;
line-height: 1;
font-weight: bold;
}
</style>
+19 -44
View File
@@ -44,13 +44,13 @@
<view style="width: 100%;">
<u-popup :show="showCommitment" :round="10" mode="center" customStyle="margin:0rpx 40rpx;">
<view class="commitment-dialog" style="padding: 20px 22px 32px 22px;">
<h4 class="commitment-title" style="font-size: 18px; display: flex; justify-content: center; padding: 7px;">{{commitTitle}}</h4>
<view class="commitment-body" style="height:490px;font-size:13px;color:#333;">
<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 class="commitment-footer">
<view >
<view @click="handleConfirm()" class="hz-btn hz-font-color-white hz-font-lg hz-font-bold hz-text-center" >{{confirmText}}</view>
</view>
</view>
@@ -141,6 +141,18 @@
userName : userData.userName
};
const res = await userConfirm(params);
// #ifdef APP-PLUS
if (userData != null && userData.userId != null) {
const app = getApp();
if (app) {
app.syncPushDeviceTokenFromNative();
await app.syncPendingPushNotificationsFromNative();
if (app.tryConsumePendingPushNavigation()) {
return;
}
}
}
// #endif
this.checkInMacau();
},
checkInMacau(){
@@ -331,6 +343,7 @@
async goLogin(){
await this.$onLaunched;
await this.getSetting();
const userData = uni.getStorageSync("userData");
let loginTag = false;
uni.setStorageSync("todoSwitch","true");
@@ -342,9 +355,10 @@
if(loginTag===true){
this.redirectByPermission(userData);
}
// 模拟开启,没有code,默认进来的情况
if(this.siteData.mockSSO==true && this.code=='' && loginTag===false){
// 模拟SSO
uni.redirectTo({
url:'/pages/ssoLogin/ssoLogin'
@@ -391,45 +405,6 @@
</script>
<style>
/* #ifdef H5 */
.commitment-dialog {
display: flex;
flex-direction: column;
box-sizing: border-box;
max-height: calc(100vh - 48px);
max-height: calc(100dvh - 48px);
overflow: hidden;
}
.commitment-title,
.commitment-footer {
flex-shrink: 0;
}
.commitment-body {
min-height: 0;
overflow-y: scroll;
overflow-x: hidden;
overflow-wrap: anywhere;
padding-right: 10px;
scrollbar-gutter: stable;
}
.commitment-body::-webkit-scrollbar {
/* uView globally sets scrollbar width to 0 !important. */
width: 2px !important;
height: 2px !important;
display: block;
}
.commitment-body::-webkit-scrollbar-track {
background: #eee;
border-radius: 4px;
}
.commitment-body::-webkit-scrollbar-thumb {
background: #a67c30;
border-radius: 4px;
}
.commitment-footer {
padding-top: 16px;
}
/* #endif */
.commit-content{
line-height: 1.5; /* 增加行间距提升可读性 */
color: #333; /* 深灰提升阅读舒适度 */
+5 -227
View File
@@ -1,235 +1,13 @@
<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>
<view></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;
}
onLoad() {
uni.redirectTo({
url: '/limo/notification/notification?tab=1'
});
}
}
</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>
+25 -3
View File
@@ -370,7 +370,7 @@
const currentRoom = this.roomList[this.currentRoomIndex];
if (currentRoom && currentRoom.id) {
const approvalData = this.approvalGamingDataList.find(
item => item.bookingId == currentRoom.id
item => (item.bookingId != null ? item.bookingId : item.BookingId) == currentRoom.id
);
return approvalData || {};
}
@@ -401,6 +401,26 @@
return value;
},
// 将形如:2025-03-18 +12 (W +2) | 2025-03-16 + 16 ... 按日期升序排序
normalizeApprovalGamingData(item) {
if (!item) return {};
return {
bookingId: item.bookingId != null ? item.bookingId : item.BookingId,
playerId: item.playerId != null ? item.playerId : item.PlayerId,
currentTripTheoWinAmount: item.currentTripTheoWinAmount != null ? item.currentTripTheoWinAmount : item.CurrentTripTheoWinAmount,
last2DayTheoWinAmount: item.last2DayTheoWinAmount != null ? item.last2DayTheoWinAmount : item.Last2DayTheoWinAmount,
r3TheoWin: item.r3TheoWin != null ? item.r3TheoWin : item.R3TheoWin,
r3TPD: item.r3TPD != null ? item.r3TPD : item.R3TPD,
r3ActualWin: item.r3ActualWin != null ? item.r3ActualWin : item.R3ActualWin,
r6TheoWin: item.r6TheoWin != null ? item.r6TheoWin : item.R6TheoWin,
r6TPD: item.r6TPD != null ? item.r6TPD : item.R6TPD,
r6ActualWin: item.r6ActualWin != null ? item.r6ActualWin : item.R6ActualWin,
r12TheoWin: item.r12TheoWin != null ? item.r12TheoWin : item.R12TheoWin,
r12TPD: item.r12TPD != null ? item.r12TPD : item.R12TPD,
r12ActualWin: item.r12ActualWin != null ? item.r12ActualWin : item.R12ActualWin,
overlapBooking: item.overlapBooking != null ? item.overlapBooking : item.OverlapBooking,
roomCount: item.roomCount != null ? item.roomCount : item.RoomCount
};
},
sortRoomCountByDate(roomCountValue) {
if (roomCountValue === null || roomCountValue === undefined || roomCountValue === '') return '-';
const input = String(roomCountValue).trim();
@@ -524,7 +544,9 @@
if (res.success == true) {
if (res.data !== null) {
this.bookingListData = res.data.bookingsViewList;
this.approvalGamingDataList = res.data.approvalGamingData || [];
this.approvalGamingDataList = Array.isArray(res.data.approvalGamingData)
? res.data.approvalGamingData.map(item => this.normalizeApprovalGamingData(item))
: [];
const routingList = res.data.cfgApprovalRoutingList;
if (Array.isArray(routingList) && routingList.length > 0) {
this.approvalRoutingList = routingList;
@@ -983,4 +1005,4 @@
.dataMargin {
margin-bottom: 3px;
}
</style>
</style>
+4 -23
View File
@@ -165,13 +165,11 @@
propertyTabItemStyle() {
return {
height: '78rpx',
padding: '0 24rpx',
flexShrink: 0,
padding: '0',
};
},
propertyTabActiveStyle() {
return {
whiteSpace: 'nowrap',
color: '#C39A4B',
fontFamily: 'Inter-Bold',
fontSize: '30rpx',
@@ -180,7 +178,6 @@
},
propertyTabInactiveStyle() {
return {
whiteSpace: 'nowrap',
color: '#111111',
fontFamily: 'Inter-Bold',
fontSize: '30rpx',
@@ -197,12 +194,6 @@
this.title = this.$t("roomCalendar.title");
this.userData = uni.getStorageSync("userData");
this.showTabbarByPermission(this.userData);
if (!this.userData || this.userData.canViewCalendar !== true) {
this.calendarNoPermission = true;
this.calendarReady = false;
return;
}
this.calendarNoPermission = false;
this.loadPropertiesRoomTypes();
},
onUnload() {
@@ -211,10 +202,6 @@
},
methods: {
async loadPropertiesRoomTypes() {
if (!this.userData || this.userData.canViewCalendar !== true) {
this.showCalendarNoPermission();
return;
}
try {
this.calendarReady = false;
uni.showLoading({
@@ -222,19 +209,14 @@
});
await this.loadCalendarSetting();
const res = await getPropertiesRoomTypes({});
if (this.isNoPermissionResponse(res)) {
this.showCalendarNoPermission();
return;
}
this.propertyList = Array.isArray(res && res.propertyList) ? res.propertyList : [];
if (!this.propertyList.length) throw new Error('No calendar properties configured');
this.propertyList = res.propertyList;
this.selectedPropertyCode = this.propertyList[0].code;
this.selectDefaultOptions();
this.buildCalendar();
await this.loadAvailabilityData();
this.calendarRenderKey += 1;
this.$nextTick(() => {
this.calendarReady = !this.calendarNoPermission;
this.calendarReady = true;
});
} catch (e) {
uni.$u.toast(e.message || e.errMsg || 'Load property room types failed');
@@ -437,7 +419,6 @@
}));
},
refreshCalendar() {
if (!this.userData || this.userData.canViewCalendar !== true || this.calendarNoPermission) return;
this.ensureSelectedOptionsForRefresh(true);
this.loadAvailabilityData();
},
@@ -520,7 +501,7 @@
});
},
isNoPermissionResponse(res) {
return res && res.success === false && (res.errorCode || res.code) === 'NO_PERMISSION';
return res && res.success === false && res.errorCode === 'NO_PERMISSION';
},
showCalendarNoPermission() {
this.availabilityMap = {};
+38 -14
View File
@@ -1,7 +1,6 @@
<!--sso login-->
<template>
<view class="container">
<web-view :src="url"></web-view>
</view>
</template>
<script>
@@ -11,26 +10,46 @@
url:'',
intervalId:null,
newUrl:'',
siteData:null
siteData:null,
samlWebview: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()
},
this.siteData = uni.getStorageSync("siteData");
if(options && options.uid && options.pwd){
let username = options.uid.replaceAll(" ", "+");
let password = options.pwd.replaceAll(" ", "+");
const loginUrl = this.siteData.internalUrl + this.siteData.apiPath + "/app/sso/login_saml_with_mfa?username="+encodeURIComponent(username)+"&password="+encodeURIComponent(password);
this.url = loginUrl;
this.openWebview(loginUrl);
}
if (options && options.url){
this.url = options.url;
this.openWebview(options.url);
}
this.listenUrl()
},
onShow() {
this.siteData = uni.getStorageSync("siteData");
},
methods: {
listenUrl() {
openWebview(loginUrl) {
// #ifdef APP-PLUS
const wv = plus.webview.create(loginUrl, 'saml-login-webview', {
'uni-app': 'none',
top: '0px',
bottom: '0px',
additionalHttpHeaders: {
'Origin': 'MGM_MCRM_APP'
}
});
this.samlWebview = wv;
const pages = getCurrentPages();
const page = pages[pages.length - 1];
page.$getAppWebview().append(wv);
// #endif
},
listenUrl() {
var that = this;
var count = 0;
this.intervalId = setInterval(() => {
@@ -75,6 +94,11 @@
}
},
getCurrentUrl(){
if (this.samlWebview) {
var url = this.samlWebview.getURL();
console.log("=======当前地址======", url);
return url;
}
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page.$getAppWebview();
+6 -14
View File
@@ -217,6 +217,7 @@
<script>
import {logout} from '../../api/commonApi.js'
import {updateDeviceToken} from '../../api/notificationApi.js'
export default {
data() {
@@ -251,19 +252,6 @@
single: "2021-04-3",
today: new Date(),
range: [],
selectData:[{
value: '1',
label: 'Corso'
},
{
value: '2',
label: 'Mauve',
},
{
value: '3',
label: 'Calmi',
}
],
}
},
onLoad() {
@@ -356,7 +344,7 @@
showDelegate() {
this.showMsgBox = true;
},
confirmLang(e){
async confirmLang(e){
uni.setLocale(e.value[0].code);
this.$i18n.locale = e.value[0].code;
this.lang = e.value[0].name;
@@ -378,6 +366,10 @@
// ignore
}
});
//这里加上接口,切换语言时 更新DeviceToken中的useLanguage字段
const useLanguage = e.value[0].code === 'en'? 0 : 1;
console.log(useLanguage);
await updateDeviceToken({userId : this.userData.userId,useLanguage});
// #endif
this.showPicker = false;
},