chore: initial import

This commit is contained in:
liangjian
2026-06-29 09:42:53 +08:00
commit 9fea127de1
241 changed files with 82767 additions and 0 deletions

386
utils/booking-helper.js Normal file
View 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
}