From 3f8930df4c0903c1e0bb0e96fe2cb7e21de1757a Mon Sep 17 00:00:00 2001 From: Mauve Date: Tue, 29 Sep 2026 21:51:58 +0800 Subject: [PATCH] push them all --- api/bookingApi.js | 2 +- api/limoApi.js | 30 ++--- api/notificationApi.js | 14 +-- booking/bookingConfirm/bookingConfirm.vue | 6 +- booking/bookingDetail/bookingDetail.vue | 21 +++- booking/bookingRecord/bookingRecord.vue | 143 ++++++++++++++++------ booking/newBooking/newBooking.vue | 14 ++- booking/submitBooking/submitBooking.vue | 2 +- common/config.js | 4 +- common/request.js | 4 +- locale/en.json | 3 + locale/zh-Hant.json | 3 + salessupport/todoList/todoList.vue | 12 +- 13 files changed, 176 insertions(+), 82 deletions(-) diff --git a/api/bookingApi.js b/api/bookingApi.js index 61b6bbf..bbafffe 100644 --- a/api/bookingApi.js +++ b/api/bookingApi.js @@ -2,7 +2,7 @@ export const getBookingsMock = (params, config = {}) => uni.$u.http.post('/app/b export const saveBooking = (params, config = {}) => uni.$u.http.post('/app/booking/create', params, config) export const getBookings = (params, config = {}) => uni.$u.http.post('/app/bookings/search_optimize', params, config) export const getBookingByConf = (params, config = {}) => uni.$u.http.post('/app/booking/get_booking_by_conf', params, config) -export const getLimoBookings = (params, config = {}) => uni.$u.http.post('/limo/search_limo', params, config) +export const getLimoBookings = (params, config = {}) => uni.$u.http.post('/app/limo/search_limo', params, config) export const getBookingById = (params, config = {}) => uni.$u.http.post('/app/booking/get_booking_by_id', params, config) export const editBooking = (params, config = {}) => uni.$u.http.post('/app/booking/edit', params, config) export const getBookingsByGroupId = (params, config = {}) => uni.$u.http.post('/app/booking/get_bookings_by_groupId', params, config) diff --git a/api/limoApi.js b/api/limoApi.js index 484b081..38de0ba 100644 --- a/api/limoApi.js +++ b/api/limoApi.js @@ -1,22 +1,22 @@ -export const getLimoTripPriceList = (params, config = {}) => uni.$u.http.post('/limo/getTripPriceList', params, config) +export const getLimoTripPriceList = (params, config = {}) => uni.$u.http.post('/app/limo/getTripPriceList', params, config) export const getLimoLocation = (params, config = {}) => - uni.$u.http.get('/limo/getLocation', { params, ...config }) + uni.$u.http.get('/app/limo/getLocation', { params, ...config }) export const getLimoCarType= (params, config = {}) => - uni.$u.http.get('/limo/getCarType', { params, ...config }) + uni.$u.http.get('/app/limo/getCarType', { params, ...config }) export const getLimoGreetType = (params, config = {}) => - uni.$u.http.get('/limo/getGreetType', { params, ...config }) + uni.$u.http.get('/app/limo/getGreetType', { params, ...config }) export const getQualification = (params, config = {}) => - uni.$u.http.get('/limo/checkQualification', { params, ...config }) + uni.$u.http.get('/app/limo/checkQualification', { params, ...config }) export const getLimoOverrider = (params, config = {}) => - uni.$u.http.get('/limo/getOverrider', { params, ...config }) + uni.$u.http.get('/app/limo/getOverrider', { params, ...config }) export const getLimoApprover = (params, config = {}) => - uni.$u.http.get('/limo/playerLimoBooker', { params, ...config }) + uni.$u.http.get('/app/limo/playerLimoBooker', { params, ...config }) export const getLimoFlightDetails = (params, config = {}) => - uni.$u.http.get('/limo/getFlightDetails', { params, ...config }) -export const getLimoTodayBooking = (params, config = {}) => uni.$u.http.post('/limo/getTodayBooking', params, config) -export const createLimoBooking = (params, config = {}) => uni.$u.http.post('/limo/createBooking', params, config) -export const prepareBooking = (params, config = {}) => uni.$u.http.post('/limo/prepareBooking', params, config) -export const editLimoBooking = (params, config = {}) => uni.$u.http.post('/limo/updateBooking', params, config) -export const cancelLimoBooking = (params, config = {}) => uni.$u.http.post('/limo/cancelBooking', params, config) -export const getLimoBookingById = (params, config = {}) => uni.$u.http.post('/limo/get_limo_booking_by_id', params, config) -export const getLimoBookingByConf = (params, config = {}) => uni.$u.http.post('/limo/get_limo_booking_by_conf', params, config) \ No newline at end of file + uni.$u.http.get('/app/limo/getFlightDetails', { params, ...config }) +export const getLimoTodayBooking = (params, config = {}) => uni.$u.http.post('/app/limo/getTodayBooking', params, config) +export const createLimoBooking = (params, config = {}) => uni.$u.http.post('/app/limo/createBooking', params, config) +export const prepareBooking = (params, config = {}) => uni.$u.http.post('/app/limo/prepareBooking', params, config) +export const editLimoBooking = (params, config = {}) => uni.$u.http.post('/app/limo/updateBooking', params, config) +export const cancelLimoBooking = (params, config = {}) => uni.$u.http.post('/app/limo/cancelBooking', params, config) +export const getLimoBookingById = (params, config = {}) => uni.$u.http.post('/app/limo/get_limo_booking_by_id', params, config) +export const getLimoBookingByConf = (params, config = {}) => uni.$u.http.post('/app/limo/get_limo_booking_by_conf', params, config) \ No newline at end of file diff --git a/api/notificationApi.js b/api/notificationApi.js index d5fa900..a184172 100644 --- a/api/notificationApi.js +++ b/api/notificationApi.js @@ -1,9 +1,9 @@ -export const saveNotification = (params, config = {}) => uni.$u.http.post('/notification/saveNotification', params, config) +export const saveNotification = (params, config = {}) => uni.$u.http.post('/app/notification/saveNotification', params, config) export const getNotificationByUserId = (params, config = {}) => - uni.$u.http.get('/notification/get_notification_by_user_id', { params, ...config }) -export const changeNotification = (params, config = {}) => uni.$u.http.post('/notification/change_status', params, config) -export const readAllNotification = (params, config = {}) => uni.$u.http.post('/notification/read_all', params, config) + uni.$u.http.get('/app/notification/get_notification_by_user_id', { params, ...config }) +export const changeNotification = (params, config = {}) => uni.$u.http.post('/app/notification/change_status', params, config) +export const readAllNotification = (params, config = {}) => uni.$u.http.post('/app/notification/read_all', params, config) export const countNotification = (params, config = {}) => - uni.$u.http.get('/notification/count_notification_by_user_id', { params, ...config }) -export const saveDeviceToken = (params, config = {}) => uni.$u.http.post('/deviceToken/save_device_token', params, config) -export const updateDeviceToken = (params, config = {}) => uni.$u.http.post('/deviceToken/update_device_token', params, config) \ No newline at end of file + uni.$u.http.get('/app/notification/count_notification_by_user_id', { params, ...config }) +export const saveDeviceToken = (params, config = {}) => uni.$u.http.post('/app/deviceToken/save_device_token', params, config) +export const updateDeviceToken = (params, config = {}) => uni.$u.http.post('/app/deviceToken/update_device_token', params, config) \ No newline at end of file diff --git a/booking/bookingConfirm/bookingConfirm.vue b/booking/bookingConfirm/bookingConfirm.vue index eb3915b..873a96b 100644 --- a/booking/bookingConfirm/bookingConfirm.vue +++ b/booking/bookingConfirm/bookingConfirm.vue @@ -868,7 +868,7 @@ } // 保存失敗彈出錯誤提示框 else { - var message = resBook.errorCode != null && resBook.errorCode != "" ? resBook.errorCode : + var message = resBook.errorCode ? resBook.errorCode : resBook.message; this.buttonStr = this.$t("common.ok"); this.iconPath = '../../static/images/ico_err.png'; @@ -1151,7 +1151,7 @@ this.showDirBtn = true; this.showMsgBox = true; } else { - var message = res.errorCode != "" ? res.errorCode : res.message; + var message = res.errorCode ? res.errorCode : res.message; this.buttonStr = this.$t("common.ok"); this.iconPath = '../../static/images/ico_err.png'; this.msgStr = this.$t("common.saveFail") + ". " + this.$t("common.errorMsg") + ": " + @@ -1451,7 +1451,7 @@ this.showDirBtn = true; this.showMsgBox = true; } else { - var message = res.errorCode != "" ? res.errorCode : res.message; + var message = res.errorCode ? res.errorCode : res.message; this.buttonStr = this.$t("common.ok"); this.iconPath = '../../static/images/ico_err.png'; this.msgStr = this.$t("common.saveFail") + ". " + this.$t("common.errorMsg") + ": " + diff --git a/booking/bookingDetail/bookingDetail.vue b/booking/bookingDetail/bookingDetail.vue index 1585e29..1032860 100644 --- a/booking/bookingDetail/bookingDetail.vue +++ b/booking/bookingDetail/bookingDetail.vue @@ -185,7 +185,7 @@ - {{$t("approval.pendingResponse")}}: {{bookingData.approver || '-'}} + {{$t("approval.pendingResponse")}}: {{bookingData.approverName || '-'}} @@ -219,13 +219,15 @@ {{$t("bookingDetail.saveImage")}} - {{$t("bookingDetail.extension")}} + {{$t("bookingDetail.extension")}} + {{$t("bookingDetail.extension")}} {{$t("bookingDetail.saveImage")}} {{$t("common.misCharge").toUpperCase()}} - {{$t("bookingDetail.extension")}} + {{$t("bookingDetail.extension")}} + {{$t("bookingDetail.extension")}} @@ -666,6 +668,15 @@ return false; } }, + isExtendBooker(){ + return this.userData.userId == this.bookingData.createdBy; + }, + showExtendBookerPopup(){ + uni.showToast({ + title: this.$t("bookingDetail.onlyBookerCanExtend"), + icon: "none" + }); + }, showOtherPopup(){ uni.showToast({ title:this.$t("bookingDetail.cannotCancel"), @@ -920,7 +931,7 @@ if( ( dayjs(day.date).isAfter(startDate) || dayjs(day.date).isSame(startDate,'day')) && ( dayjs(day.date).isBefore(endDate) ||dayjs(day.date).isSame(endDate,'day')) ){ // console.log(cdate) - + var operaStatus = this.bookingData.lastOperaStatus; var checkExp = (operaStatus.toUpperCase()==='CHECKED_IN')||(operaStatus.toUpperCase()==='DUE_OUT'); if((this.bookingData.expDate==null||this.bookingData.expDate=='')&&checkExp){ @@ -1003,7 +1014,7 @@ const res = await changeMiscCharge(params); if(res.success!==null && res.success == true){ this.iconPath = '../../static/images/ico_suc.png'; - this.popMsgStr = this.$t("bookingDetail.changeMiscChargeSuccess"); + this.popMsgStr = this.$t("bookingDetail.changeMisChargeSuccess"); this.showMsgBox = true; this.showETAMsg = false; diff --git a/booking/bookingRecord/bookingRecord.vue b/booking/bookingRecord/bookingRecord.vue index a224f35..0b071cb 100644 --- a/booking/bookingRecord/bookingRecord.vue +++ b/booking/bookingRecord/bookingRecord.vue @@ -44,8 +44,8 @@ - - + + @@ -72,6 +72,9 @@ {{$t("common.checkOutDate")}}: {{ record.checkoutDate }} + {{$t("bookingRecord.sharer").toUpperCase()}} @@ -204,11 +207,17 @@ this.pullDownRefresh(); }, methods: { + normalizeBookingList(res){ + if(Array.isArray(res)) return res; + if(res && Array.isArray(res.data)) return res.data; + if(res && res.data && Array.isArray(res.data.records)) return res.data.records; + if(res && Array.isArray(res.records)) return res.records; + return null; + }, updateHotelBookingList(res){ - if(Array.isArray(res) && res.length > 0){ - this.bookingList = res; - }else{ - this.bookingList = []; + const list = this.normalizeBookingList(res); + if(list){ + this.bookingList = list; } }, updateLimoBookingList(res) { @@ -246,39 +255,62 @@ // 數據方法 async getDataByPage(){ if(this.userData.canViewBooking==false) return; - const previousTask = this.currentTask; + const previousRequest = this.currentTask; const requestId = ++this.getDataByPageRequestId; - if(previousTask){ - try{ - previousTask.abort(); - }catch(err){ - } - } - - // 一次页面加载会同时发起 Hotel 和 Limo 请求,统一保存并取消它们。 const requestTasks = []; + let finishRequest; + const requestFinished = new Promise(resolve => { + finishRequest = resolve; + }); const requestController = { + requestId, + finished: requestFinished, + isAborted: false, + addTask: task => { + if(!task || typeof task.abort !== 'function') return; + if(requestController.isAborted || requestId !== this.getDataByPageRequestId){ + try{ + task.abort(); + }catch(err){ + } + return; + } + requestTasks.push(task); + }, abort: () => { - requestTasks.forEach(task => { - if(task && typeof task.abort === 'function'){ - try{ - task.abort(); - }catch(err){ - } + if(requestController.isAborted) return; + requestController.isAborted = true; + requestTasks.splice(0).forEach(task => { + try{ + task.abort(); + }catch(err){ } }); - } - }; - const requestConfig = { - getTask: task => { - if(requestId === this.getDataByPageRequestId){ - requestTasks.push(task); - }else if(task && typeof task.abort === 'function'){ - task.abort(); - } - } + }, + finish: () => finishRequest() }; this.currentTask = requestController; + + if(previousRequest && typeof previousRequest.abort === 'function'){ + previousRequest.abort(); + // 等旧请求的 abort 回调先完成,避免 App 端取消动作影响紧接着的新请求。 + if(previousRequest.finished){ + await Promise.race([ + previousRequest.finished, + new Promise(resolve => setTimeout(resolve, 50)) + ]); + }else{ + await new Promise(resolve => setTimeout(resolve, 0)); + } + } + if(requestId !== this.getDataByPageRequestId){ + requestController.finish(); + return; + } + + const requestConfig = { + getTask: task => requestController.addTask(task) + }; let params = {}; uni.showLoading({ title: this.$t("common.loading") @@ -314,6 +346,7 @@ uni.$u.toast(e.errMsg,5000); await this.writeLog(this.userData.userId,"save_booking","","[APP][bookingDetail.vue][getDataByPage][Catch Exception]"+e.errMsg,"[RequestData]" +JSON.stringify(params),"",1,false); }finally{ + requestController.finish(); if(requestId === this.getDataByPageRequestId){ if(this.currentTask === requestController){ this.currentTask = null; @@ -382,10 +415,14 @@ return bookingType+': Limo'; }, getRecordStatusText(record){ - if(this.isHotelRecord(record)){ - return this.getStatusText(record); - }else{ - return record.status.replace("_"," "); + try{ + if(this.isHotelRecord(record)){ + return this.getStatusText(record); + } + if(record.status == null) return ''; + return String(record.status).replace("_"," "); + }catch(e){ + return ''; } }, getRecordStatusClass(record){ @@ -478,8 +515,8 @@ userId: this.userData.userId }; const [resHotel, resLimo] = await Promise.all([ - getBookings(bookingParams, requestConfig), - getLimoBookings(bookingParams, requestConfig) + getBookings(bookingParams, requestConfig).catch(() => null), + getLimoBookings(bookingParams, requestConfig).catch(() => null) ]); if(requestId !== this.getDataByPageRequestId) return; this.updateHotelBookingList(resHotel); @@ -924,4 +961,36 @@ .hz-book-btn-wrap--single { width: 95%; } + .hz-page { + overflow-x: hidden; + } + .hz-record-list, + .hz-record-item, + .hz-record-card { + box-sizing: border-box; + max-width: 100%; + min-width: 0; + } + .hz-record-card { + align-items: stretch; + overflow: hidden; + width: 100%; + } + .hz-record-card ::v-deep .hz-flex-row, + .hz-record-card ::v-deep .hz-w-50, + .hz-record-card ::v-deep .hz-w-55, + .hz-record-card ::v-deep .hz-w-100, + .hz-record-card ::v-deep .hz-booking-type-wrap, + .hz-record-card ::v-deep .hz-font-md { + box-sizing: border-box; + max-width: 100%; + min-width: 0; + } + .hz-record-card ::v-deep .hz-w-55 { + flex: 1; + width: auto; + } + .hz-record-card ::v-deep .hz-font-md { + word-break: break-word; + } diff --git a/booking/newBooking/newBooking.vue b/booking/newBooking/newBooking.vue index 8b1b544..09119f2 100644 --- a/booking/newBooking/newBooking.vue +++ b/booking/newBooking/newBooking.vue @@ -143,7 +143,7 @@ - {{$t("newBooking.deposit")}} + {{$t("newBooking.deposit")}}* - {{$t("newBooking.postCharge")}} + {{$t("newBooking.postCharge")}}* { const clientId = uni.getStorageSync("clientId") config.header.Authorization = token; config.header.ClientId = clientId; - // #ifdef APP-PLUS + // #ifdef APP-PLUS || H5 config.header.Origin = config.custom.origin; // #endif if(config.url.indexOf('refresh_token')==-1 ){ @@ -100,7 +100,7 @@ module.exports = (vm) => { return data === undefined ? {} : data }, (error) => { console.log(error) - if( error.errMsg=="request:ok") { + if(error.errMsg=="request:ok") { error.errMsg= "request:fail"; if(error.data!=undefined){ if(error.data.message!=undefined){ diff --git a/locale/en.json b/locale/en.json index 58b3f33..2666a13 100644 --- a/locale/en.json +++ b/locale/en.json @@ -120,7 +120,9 @@ "newBooking.extension":"Extension", "newBooking.preference":"Note:Selected preference is not guaranteed!", "newBooking.deposit":"Deposit", + "newBooking.alertDeposit":"Deposit must be selected", "newBooking.postCharge":"Post Charge", + "newBooking.alertPostCharge":"Post charge must be selected", "newBooking.waiveDeposit":"Waive Deposit", "newBooking.collectDeposit":"Collect Deposit", "newBooking.yesPost":"Yes Post", @@ -214,6 +216,7 @@ "bookingDetail.cancelBooking":"CANCEL BOOKING", "bookingDetail.ETA":"ETA", "bookingDetail.extension":"EXTENSION", + "bookingDetail.onlyBookerCanExtend":"Only booker can extend booking.", "bookingDetail.backToBooking":"BACK TO BOOKING", "bookingDetail.cannotExtend":"Reached booking max stay days", "bookingDetail.cancelSuccessful":"Booking is Cancelled", diff --git a/locale/zh-Hant.json b/locale/zh-Hant.json index ce82aa8..0eaa6e2 100644 --- a/locale/zh-Hant.json +++ b/locale/zh-Hant.json @@ -119,7 +119,9 @@ "newBooking.extension": "續房", "newBooking.preference": "注意:特殊需求均無法保證,須視乎實際状況安排", "newBooking.deposit": "押金", + "newBooking.alertDeposit": "必須選擇押金", "newBooking.postCharge": "房賬", + "newBooking.alertPostCharge": "必須選擇房賬", "newBooking.waiveDeposit": "免收押金", "newBooking.collectDeposit": "收取押金", "newBooking.yesPost": "掛房賬", @@ -203,6 +205,7 @@ "approvalRouting.title":"審批路由", "bookingDetail.saveImage": "保存圖片", "bookingDetail.extension": "續房", + "bookingDetail.onlyBookerCanExtend": "只有創建者才可以續房。", "bookingDetail.cancelSuccessful": "取消成功", "bookingDetail.cancelFailed": "取消失敗", "bookingDetail.confirmCancel": "你確定要取消預定嗎?", diff --git a/salessupport/todoList/todoList.vue b/salessupport/todoList/todoList.vue index efc09fd..8bd6a71 100644 --- a/salessupport/todoList/todoList.vue +++ b/salessupport/todoList/todoList.vue @@ -235,7 +235,7 @@ R6M TPD: {{formatNumber(rowRecord.detailData.r6MTPD)}} - R6M Win: {{formatNumber(rowRecord.detailData.r6MWin)}}: + R6M Win: {{formatNumber(rowRecord.detailData.r6MWin)}} R6M RI: {{getPercentFormat(rowRecord.detailData.r6MRIPercentage)}} R6M Theo : {{formatNumber(rowRecord.detailData.r6MTheo)}} @@ -963,12 +963,12 @@ // } }else{ this.iconPath = '../../static/images/ico_err.png'; - if(res.errorCode == 'NO_RECORD'){ + if(res.code == 'NO_RECORD'){ this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ this.$t("todo.notRecord"); - }else if(res.errorCode == 'MISS_PARAMETER'){ + }else if(res.code == 'MISS_PARAMETER'){ this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ this.$t("todo.missParams"); }else{ - this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ res.errorCode; + this.popMsgStr = this.$t("todo.etaFail")+":"+this.$t("common.errorMsg")+":"+ res.code; } } this.showMsgBox = true; @@ -988,7 +988,6 @@ uni.hideLoading(); this.etaTime = ''; } - // 使用父组件的closeAll方法关闭所有滑块 this.$nextTick(() => { const swipeRef = this.$refs.swipeAction; @@ -1600,8 +1599,7 @@ getETALable() { return function(record) { if (this.currentIndex !== 1 && this.currentIndex !== 2) { - console.log(record); - return record.eTA; + return record.eta; } else if (record.bigLossFlag === 1) { return "BIGLOSS"; } else if (record.bigWinFlag === 1) {