396 lines
12 KiB
JavaScript
396 lines
12 KiB
JavaScript
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 safeOrder = order || {}
|
|
const rawStatus = String(safeOrder.status || safeOrder.orderStatus || '').trim()
|
|
if (['pending_review', 'approved_wait_assign', 'assigned_wait_room', 'rejected', 'contract_signed'].includes(rawStatus)) {
|
|
return rawStatus
|
|
}
|
|
|
|
const contractStatus = Number(safeOrder.contractStatus)
|
|
if (contractStatus === 1) {
|
|
return 'contract_signed'
|
|
}
|
|
|
|
const approvalStatus = Number(
|
|
safeOrder.approvalStatus !== undefined
|
|
? safeOrder.approvalStatus
|
|
: safeOrder.auditStatus !== undefined
|
|
? safeOrder.auditStatus
|
|
: safeOrder.statusCode
|
|
)
|
|
|
|
if (approvalStatus === -1 || /reject|refuse|驳回/i.test(rawStatus)) {
|
|
return 'rejected'
|
|
}
|
|
if (approvalStatus === 0 || /pending|review|审核中|待审批/i.test(rawStatus)) {
|
|
return 'pending_review'
|
|
}
|
|
if (
|
|
safeOrder.roomNo ||
|
|
safeOrder.roomCode ||
|
|
safeOrder.roomName ||
|
|
safeOrder.checkinDate ||
|
|
safeOrder.startDate ||
|
|
safeOrder.start
|
|
) {
|
|
return 'assigned_wait_room'
|
|
}
|
|
return 'approved_wait_assign'
|
|
}
|
|
|
|
function resolveStatusText(order = {}, statusKey, language = getCurrentLanguage()) {
|
|
const safeOrder = order || {}
|
|
|
|
const contractStatus = Number(safeOrder.contractStatus)
|
|
if (contractStatus === 1 && safeOrder.contractStatusDesc && language !== 'en') {
|
|
return safeOrder.contractStatusDesc
|
|
}
|
|
|
|
if (language !== 'en' && safeOrder.approvalStatusDesc) {
|
|
return safeOrder.approvalStatusDesc
|
|
}
|
|
if (language !== 'en' && safeOrder.statusDesc) {
|
|
return safeOrder.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 safeOrder = order || {}
|
|
const isEn = language === 'en'
|
|
const building = [
|
|
isEn
|
|
? (safeOrder.buildingNameEn || safeOrder.buildingEn || safeOrder.buildingSectionNameEn || safeOrder.buildingName || safeOrder.building || safeOrder.buildingSectionName || '')
|
|
: (safeOrder.buildingName || safeOrder.building || safeOrder.buildingSectionName || ''),
|
|
isEn
|
|
? (safeOrder.floorNameEn || safeOrder.floorEn || safeOrder.floorName || safeOrder.floor || '')
|
|
: (safeOrder.floorName || safeOrder.floor || '')
|
|
].filter(Boolean).join(' ')
|
|
return building || '--'
|
|
}
|
|
|
|
function getRoomTypeText(order = {}, language = getCurrentLanguage()) {
|
|
const safeOrder = order || {}
|
|
const isEn = language === 'en'
|
|
if (isEn) {
|
|
return safeOrder.roomTypeNameEn || safeOrder.styleNameEn || safeOrder.roomNameEn || safeOrder.roomTypeName || safeOrder.styleNameZh || safeOrder.roomType || safeOrder.roomName || '--'
|
|
}
|
|
return safeOrder.roomTypeName || safeOrder.styleNameZh || safeOrder.roomType || safeOrder.roomName || '--'
|
|
}
|
|
|
|
function getOrderNo(order = {}) {
|
|
const safeOrder = order || {}
|
|
return safeOrder.orderNo || safeOrder.no || safeOrder.code || '--'
|
|
}
|
|
|
|
export function getOrderStatusCode(order = {}) {
|
|
const safeOrder = order || {}
|
|
const candidates = [
|
|
safeOrder.orderStatus,
|
|
safeOrder.statusCode,
|
|
safeOrder.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 safeOrder = order || {}
|
|
const checkInPeriod = safeOrder.checkInPeriod || {}
|
|
const candidates = [
|
|
safeOrder.updateTime,
|
|
safeOrder.createTime,
|
|
safeOrder.createdAt,
|
|
safeOrder.startDate,
|
|
safeOrder.start,
|
|
safeOrder.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 = {}) {
|
|
const safeOrder = order || {}
|
|
return !!(
|
|
safeOrder.roomNo
|
|
|| safeOrder.roomCode
|
|
|| safeOrder.slotCode
|
|
|| safeOrder.contractNo
|
|
|| safeOrder.actualCheckInTime
|
|
|| safeOrder.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 safeOrder = order || {}
|
|
const statusKey = normalizeStatusKey(safeOrder)
|
|
const statusCode = getOrderStatusCode(safeOrder)
|
|
const checkInPeriod = safeOrder.checkInPeriod || {}
|
|
const startDate = safeOrder.startDate || safeOrder.start || safeOrder.checkinDate || checkInPeriod.start
|
|
const endDate = safeOrder.endDate || safeOrder.end || safeOrder.checkoutDate || checkInPeriod.end
|
|
return {
|
|
...safeOrder,
|
|
orderNo: getOrderNo(safeOrder),
|
|
roomTypeText: getRoomTypeText(safeOrder, language),
|
|
buildingFloorText: getBuildingFloorText(safeOrder, language),
|
|
startDateText: formatOrderDate(startDate),
|
|
endDateText: formatOrderDate(endDate),
|
|
createdAtText: formatOrderDateTime(safeOrder.createTime || safeOrder.updateTime || safeOrder.createdAt),
|
|
roomNoText: language === 'en'
|
|
? (safeOrder.roomNoEn || safeOrder.roomCodeEn || safeOrder.roomNameEn || safeOrder.roomNo || safeOrder.roomCode || safeOrder.roomName || '--')
|
|
: (safeOrder.roomNo || safeOrder.roomCode || safeOrder.roomName || safeOrder.roomNoEn || safeOrder.roomCodeEn || safeOrder.roomNameEn || '--'),
|
|
areaText: language === 'en'
|
|
? (safeOrder.areaNameEn || safeOrder.campusNameEn || safeOrder.areaName || safeOrder.campusName || '--')
|
|
: (safeOrder.areaName || safeOrder.campusName || '--'),
|
|
rejectReasonText: safeOrder.rejectReason || safeOrder.approveReason || safeOrder.remark || '',
|
|
startDate,
|
|
endDate,
|
|
status: statusKey,
|
|
statusCode,
|
|
statusKey,
|
|
statusText: resolveStatusText(safeOrder, 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
|
|
}
|