chore: initial import
This commit is contained in:
386
utils/booking-helper.js
Normal file
386
utils/booking-helper.js
Normal file
@@ -0,0 +1,386 @@
|
||||
import { getCurrentLanguage } from './i18n'
|
||||
|
||||
function getBookingText(key = '', language = getCurrentLanguage()) {
|
||||
const isEn = language === 'en'
|
||||
const map = {
|
||||
pendingReview: isEn ? 'Pending Review' : '审核中',
|
||||
approved: isEn ? 'Approved' : '已通过',
|
||||
waitingCheckin: isEn ? 'Waiting Check-in' : '待入住',
|
||||
rejected: isEn ? 'Rejected' : '已驳回',
|
||||
processing: isEn ? 'Processing' : '处理中',
|
||||
contractSigned: isEn ? 'Signed' : '已签署'
|
||||
}
|
||||
return map[key] || ''
|
||||
}
|
||||
|
||||
function parseJsonStringMaybe(value) {
|
||||
if (typeof value !== 'string') {
|
||||
return value
|
||||
}
|
||||
|
||||
const trimmed = value.trim()
|
||||
if (!trimmed) {
|
||||
return value
|
||||
}
|
||||
|
||||
const looksLikeJson = (
|
||||
(trimmed.startsWith('{') && trimmed.endsWith('}'))
|
||||
|| (trimmed.startsWith('[') && trimmed.endsWith(']'))
|
||||
)
|
||||
|
||||
if (!looksLikeJson) {
|
||||
return value
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(trimmed)
|
||||
} catch (error) {
|
||||
console.warn('[orderSearchedMePage] JSON parse failed:', error)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
function parseResponsePayload(response) {
|
||||
const basePayload = response && response.data ? response.data : response
|
||||
return parseJsonStringMaybe(basePayload)
|
||||
}
|
||||
|
||||
function collectObjectArray(value, depth = 0) {
|
||||
if (!value || depth > 6) {
|
||||
return []
|
||||
}
|
||||
|
||||
const normalizedValue = parseJsonStringMaybe(value)
|
||||
|
||||
if (Array.isArray(normalizedValue)) {
|
||||
if (normalizedValue.some(item => item && typeof item === 'object' && !Array.isArray(item))) {
|
||||
return normalizedValue
|
||||
}
|
||||
|
||||
for (let index = 0; index < normalizedValue.length; index += 1) {
|
||||
const nestedList = collectObjectArray(normalizedValue[index], depth + 1)
|
||||
if (nestedList.length) {
|
||||
return nestedList
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
if (typeof normalizedValue !== 'object') {
|
||||
return []
|
||||
}
|
||||
|
||||
const candidateKeys = [
|
||||
'data',
|
||||
'list',
|
||||
'rows',
|
||||
'items',
|
||||
'records',
|
||||
'result',
|
||||
'payload',
|
||||
'$values'
|
||||
]
|
||||
|
||||
for (let index = 0; index < candidateKeys.length; index += 1) {
|
||||
const key = candidateKeys[index]
|
||||
if (!Object.prototype.hasOwnProperty.call(normalizedValue, key)) {
|
||||
continue
|
||||
}
|
||||
const nestedList = collectObjectArray(normalizedValue[key], depth + 1)
|
||||
if (nestedList.length) {
|
||||
return nestedList
|
||||
}
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
export function parseOrderListResponse(response) {
|
||||
const payload = parseResponsePayload(response)
|
||||
const orderList = collectObjectArray(payload)
|
||||
|
||||
if (!orderList.length) {
|
||||
console.warn('[orderSearchedMePage] unsupported response structure:', payload)
|
||||
} else {
|
||||
console.log('[orderSearchedMePage] parsed order count:', orderList.length)
|
||||
}
|
||||
|
||||
return orderList
|
||||
}
|
||||
|
||||
export function parseOrderDetailResponse(response) {
|
||||
const payload = parseResponsePayload(response)
|
||||
|
||||
if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
|
||||
return payload
|
||||
}
|
||||
|
||||
const orderList = collectObjectArray(payload)
|
||||
return Array.isArray(orderList) && orderList.length ? orderList[0] : {}
|
||||
}
|
||||
|
||||
export function formatOrderDateTime(value) {
|
||||
if (!value) {
|
||||
return '--'
|
||||
}
|
||||
const date = new Date(value)
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return String(value).replace('T', ' ').slice(0, 16) || '--'
|
||||
}
|
||||
const pad = item => String(item).padStart(2, '0')
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
|
||||
}
|
||||
|
||||
export function formatOrderDate(value) {
|
||||
if (!value) {
|
||||
return '--'
|
||||
}
|
||||
const date = new Date(value)
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return String(value).slice(0, 10) || '--'
|
||||
}
|
||||
const pad = item => String(item).padStart(2, '0')
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
|
||||
}
|
||||
|
||||
function normalizeStatusKey(order = {}) {
|
||||
const rawStatus = String(order.status || order.orderStatus || '').trim()
|
||||
if (['pending_review', 'approved_wait_assign', 'assigned_wait_room', 'rejected', 'contract_signed'].includes(rawStatus)) {
|
||||
return rawStatus
|
||||
}
|
||||
|
||||
const contractStatus = Number(order.contractStatus)
|
||||
if (contractStatus === 1) {
|
||||
return 'contract_signed'
|
||||
}
|
||||
|
||||
const approvalStatus = Number(
|
||||
order.approvalStatus !== undefined
|
||||
? order.approvalStatus
|
||||
: order.auditStatus !== undefined
|
||||
? order.auditStatus
|
||||
: order.statusCode
|
||||
)
|
||||
|
||||
if (approvalStatus === -1 || /reject|refuse|驳回/i.test(rawStatus)) {
|
||||
return 'rejected'
|
||||
}
|
||||
if (approvalStatus === 0 || /pending|review|审核中|待审批/i.test(rawStatus)) {
|
||||
return 'pending_review'
|
||||
}
|
||||
if (
|
||||
order.roomNo ||
|
||||
order.roomCode ||
|
||||
order.roomName ||
|
||||
order.checkinDate ||
|
||||
order.startDate ||
|
||||
order.start
|
||||
) {
|
||||
return 'assigned_wait_room'
|
||||
}
|
||||
return 'approved_wait_assign'
|
||||
}
|
||||
|
||||
function resolveStatusText(order = {}, statusKey, language = getCurrentLanguage()) {
|
||||
|
||||
const contractStatus = Number(order.contractStatus)
|
||||
if (contractStatus === 1 && order.contractStatusDesc && language !== 'en') {
|
||||
return order.contractStatusDesc
|
||||
}
|
||||
|
||||
if (language !== 'en' && order.approvalStatusDesc) {
|
||||
return order.approvalStatusDesc
|
||||
}
|
||||
if (language !== 'en' && order.statusDesc) {
|
||||
return order.statusDesc
|
||||
}
|
||||
const map = {
|
||||
pending_review: getBookingText('pendingReview', language),
|
||||
approved_wait_assign: getBookingText('approved', language),
|
||||
assigned_wait_room: getBookingText('waitingCheckin', language),
|
||||
rejected: getBookingText('rejected', language),
|
||||
contract_signed: getBookingText('contractSigned', language)
|
||||
}
|
||||
return map[statusKey] || getBookingText('processing', language)
|
||||
}
|
||||
|
||||
function resolveTagType(statusKey) {
|
||||
if (statusKey === 'rejected') {
|
||||
return 'rejected'
|
||||
}
|
||||
if (statusKey === 'pending_review') {
|
||||
return 'pending'
|
||||
}
|
||||
if (statusKey === 'contract_signed') {
|
||||
return 'approved'
|
||||
}
|
||||
return 'approved'
|
||||
}
|
||||
|
||||
function getBuildingFloorText(order = {}, language = getCurrentLanguage()) {
|
||||
const isEn = language === 'en'
|
||||
const building = [
|
||||
isEn
|
||||
? (order.buildingNameEn || order.buildingEn || order.buildingSectionNameEn || order.buildingName || order.building || order.buildingSectionName || '')
|
||||
: (order.buildingName || order.building || order.buildingSectionName || ''),
|
||||
isEn
|
||||
? (order.floorNameEn || order.floorEn || order.floorName || order.floor || '')
|
||||
: (order.floorName || order.floor || '')
|
||||
].filter(Boolean).join(' ')
|
||||
return building || '--'
|
||||
}
|
||||
|
||||
function getRoomTypeText(order = {}, language = getCurrentLanguage()) {
|
||||
const isEn = language === 'en'
|
||||
if (isEn) {
|
||||
return order.roomTypeNameEn || order.styleNameEn || order.roomNameEn || order.roomTypeName || order.styleNameZh || order.roomType || order.roomName || '--'
|
||||
}
|
||||
return order.roomTypeName || order.styleNameZh || order.roomType || order.roomName || '--'
|
||||
}
|
||||
|
||||
function getOrderNo(order = {}) {
|
||||
return order.orderNo || order.no || order.code || '--'
|
||||
}
|
||||
|
||||
export function getOrderStatusCode(order = {}) {
|
||||
const candidates = [
|
||||
order.orderStatus,
|
||||
order.statusCode,
|
||||
order.status
|
||||
]
|
||||
|
||||
for (let index = 0; index < candidates.length; index += 1) {
|
||||
const value = candidates[index]
|
||||
if (value === '' || value === null || value === undefined) {
|
||||
continue
|
||||
}
|
||||
const numericValue = Number(value)
|
||||
if (Number.isFinite(numericValue)) {
|
||||
return numericValue
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export function getOrderTime(order = {}) {
|
||||
const checkInPeriod = order.checkInPeriod || {}
|
||||
const candidates = [
|
||||
order.updateTime,
|
||||
order.createTime,
|
||||
order.createdAt,
|
||||
order.startDate,
|
||||
order.start,
|
||||
order.checkinDate,
|
||||
checkInPeriod.start
|
||||
]
|
||||
|
||||
const timestamp = candidates
|
||||
.map(value => new Date(value || 0).getTime())
|
||||
.find(value => Number.isFinite(value) && value > 0)
|
||||
|
||||
return timestamp || 0
|
||||
}
|
||||
|
||||
export function sortOrdersByLatest(orderList = []) {
|
||||
return [...orderList].sort((prev, next) => getOrderTime(next) - getOrderTime(prev))
|
||||
}
|
||||
|
||||
function hasStayFields(order = {}) {
|
||||
return !!(
|
||||
order.roomNo
|
||||
|| order.roomCode
|
||||
|| order.slotCode
|
||||
|| order.contractNo
|
||||
|| order.actualCheckInTime
|
||||
|| order.checkinTime
|
||||
)
|
||||
}
|
||||
|
||||
export function isRejectedBookingOrder(order = {}) {
|
||||
const statusKey = normalizeStatusKey(order)
|
||||
const statusCode = getOrderStatusCode(order)
|
||||
return statusKey === 'rejected' || statusCode === -1
|
||||
}
|
||||
|
||||
export function isCheckedInOrder(order = {}) {
|
||||
const statusCode = getOrderStatusCode(order)
|
||||
if (statusCode !== null) {
|
||||
return statusCode > 0
|
||||
}
|
||||
|
||||
const contractStatus = Number(order.contractStatus)
|
||||
if (contractStatus === 1) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (isRejectedBookingOrder(order)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return hasStayFields(order)
|
||||
}
|
||||
|
||||
export function isCurrentBookingOrder(order = {}) {
|
||||
if (isRejectedBookingOrder(order) || isCheckedInOrder(order)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const statusCode = getOrderStatusCode(order)
|
||||
if (statusCode === 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
const statusKey = normalizeStatusKey(order)
|
||||
return ['pending_review', 'approved_wait_assign', 'assigned_wait_room', 'contract_signed'].includes(statusKey)
|
||||
}
|
||||
|
||||
export function normalizeBookingOrder(order = {}, language = getCurrentLanguage()) {
|
||||
const statusKey = normalizeStatusKey(order)
|
||||
const statusCode = getOrderStatusCode(order)
|
||||
const checkInPeriod = order.checkInPeriod || {}
|
||||
const startDate = order.startDate || order.start || order.checkinDate || checkInPeriod.start
|
||||
const endDate = order.endDate || order.end || order.checkoutDate || checkInPeriod.end
|
||||
return {
|
||||
...order,
|
||||
orderNo: getOrderNo(order),
|
||||
roomTypeText: getRoomTypeText(order, language),
|
||||
buildingFloorText: getBuildingFloorText(order, language),
|
||||
startDateText: formatOrderDate(startDate),
|
||||
endDateText: formatOrderDate(endDate),
|
||||
createdAtText: formatOrderDateTime(order.createTime || order.updateTime || order.createdAt),
|
||||
roomNoText: language === 'en'
|
||||
? (order.roomNoEn || order.roomCodeEn || order.roomNameEn || order.roomNo || order.roomCode || order.roomName || '--')
|
||||
: (order.roomNo || order.roomCode || order.roomName || order.roomNoEn || order.roomCodeEn || order.roomNameEn || '--'),
|
||||
areaText: language === 'en'
|
||||
? (order.areaNameEn || order.campusNameEn || order.areaName || order.campusName || '--')
|
||||
: (order.areaName || order.campusName || '--'),
|
||||
rejectReasonText: order.rejectReason || order.approveReason || order.remark || '',
|
||||
startDate,
|
||||
endDate,
|
||||
status: statusKey,
|
||||
statusCode,
|
||||
statusKey,
|
||||
statusText: resolveStatusText(order, statusKey, language),
|
||||
tagType: resolveTagType(statusKey)
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeBookingList(orderList = [], language = getCurrentLanguage()) {
|
||||
return sortOrdersByLatest(orderList).map(item => normalizeBookingOrder(item, language))
|
||||
}
|
||||
|
||||
export function normalizeBookingDetail(order = {}, language = getCurrentLanguage()) {
|
||||
if (!order || typeof order !== 'object' || Array.isArray(order)) {
|
||||
return null
|
||||
}
|
||||
return normalizeBookingOrder(order, language)
|
||||
}
|
||||
|
||||
export function pickCurrentStayOrder(orderList = []) {
|
||||
return sortOrdersByLatest(orderList).find(item => isCheckedInOrder(item)) || null
|
||||
}
|
||||
|
||||
export function pickCurrentBooking(orderList = []) {
|
||||
return sortOrdersByLatest(orderList).find(item => isCurrentBookingOrder(item)) || null
|
||||
}
|
||||
Reference in New Issue
Block a user