const RESERVATION_FLOW_STEP = { APPLICATION: 1, INSPECTION: 2, CONTRACT: 3, BILL: 4, CHECKIN: 5 } function getLanguage(language) { return language === 'en' ? 'en' : 'zh' } function parseJsonStringMaybe(value) { if (typeof value !== 'string') { return value } const text = value.trim() if (!text) { return value } const isJsonLike = ( (text.startsWith('{') && text.endsWith('}')) || (text.startsWith('[') && text.endsWith(']')) ) if (!isJsonLike) { return value } try { return JSON.parse(text) } catch (error) { return value } } function normalizeArray(value) { if (Array.isArray(value)) { return value } return [] } export function parseReservationFlowResponse(response) { const rawPayload = response && response.data ? response.data : response const payload = parseJsonStringMaybe(rawPayload) if (Array.isArray(payload)) { return payload } if (payload && Array.isArray(payload.data)) { return payload.data } if (payload && payload.data && Array.isArray(payload.data.data)) { return payload.data.data } return [] } export function getReservationOrderNo(source = {}) { const candidates = [ source.orderNo, source.OrderNo, source.reservationOrderNo, source.searchedOrderNo, source.bookingOrderNo ] for (let index = 0; index < candidates.length; index += 1) { const value = String(candidates[index] || '').trim() if (value) { return value } } return '' } export function getReservationCurrentNode(flow = {}) { const nodes = normalizeArray(flow && flow.flowNodes) .filter(item => item && typeof item === 'object') .sort((a, b) => Number(a.sort || 0) - Number(b.sort || 0)) if (!nodes.length) { return null } const currentNodes = nodes.filter(item => item.isCurrent) if (currentNodes.length) { const currentCheckinNode = currentNodes.find(item => ( Number(item.step || 0) === RESERVATION_FLOW_STEP.CHECKIN && String(item.refNo || '').trim() )) if (currentCheckinNode) { return currentCheckinNode } // 后端偶发会把前序节点也标记成 isCurrent,优先取排序最靠后的当前节点 return currentNodes[currentNodes.length - 1] } const checkinNode = nodes.find(item => ( Number(item.step || 0) === RESERVATION_FLOW_STEP.CHECKIN && String(item.refNo || '').trim() )) if (checkinNode) { return checkinNode } return nodes[nodes.length - 1] } export function getReservationCurrentFlow(flowList = []) { const flows = normalizeArray(flowList) .filter(item => item && typeof item === 'object') .map(item => ({ flow: item, currentNode: getReservationCurrentNode(item) })) .filter(item => item.currentNode) if (!flows.length) { return null } const compareNode = (target) => { const node = target.currentNode || {} const step = Number(node.step || 0) const sort = Number(node.sort || 0) const refNo = String(node.refNo || '').trim() const isCurrent = !!node.isCurrent const isCheckinWithRefNo = step === RESERVATION_FLOW_STEP.CHECKIN && !!refNo return [ isCheckinWithRefNo ? 1 : 0, isCurrent ? 1 : 0, step, sort ] } return flows .sort((a, b) => { const aScore = compareNode(a) const bScore = compareNode(b) for (let index = 0; index < aScore.length; index += 1) { if (aScore[index] !== bScore[index]) { return bScore[index] - aScore[index] } } return 0 })[0].flow } export function hasEffectiveReservationFlow(flow = {}) { const currentNode = getReservationCurrentNode(flow) if (!currentNode) { return false } const step = Number(currentNode.step || 0) const refNo = String(currentNode.refNo || '').trim() // 当前步骤为申请单(1)且没有 refNo 时,视为尚未提交预约单 if (step === 1 && !refNo) { return false } return step > 0 } export function buildReservationFlowMap(flowList = []) { return normalizeArray(flowList) .filter(item => item && typeof item === 'object') .reduce((result, item) => { const orderNo = getReservationOrderNo(item) if (!orderNo) { return result } result[orderNo] = { ...item, orderNo, currentNode: getReservationCurrentNode(item) } return result }, {}) } export function attachReservationFlow(item = {}, flowMap = {}) { const orderNo = getReservationOrderNo(item) const matchedFlow = orderNo ? flowMap[orderNo] : null return { ...item, reservationOrderNo: orderNo, reservationFlow: matchedFlow || null, reservationCurrentNode: matchedFlow && matchedFlow.currentNode ? matchedFlow.currentNode : null } } export function getReservationStepMeta(step, language = 'zh') { const currentLanguage = getLanguage(language) const map = { [RESERVATION_FLOW_STEP.INSPECTION]: { label: currentLanguage === 'en' ? 'Inspection' : '验房', actionText: currentLanguage === 'en' ? 'View Inspection' : '查看验房' }, [RESERVATION_FLOW_STEP.BILL]: { label: currentLanguage === 'en' ? 'Bill' : '账单', actionText: currentLanguage === 'en' ? 'Go to Payment' : '去支付' }, [RESERVATION_FLOW_STEP.CONTRACT]: { label: currentLanguage === 'en' ? 'Contract' : '合同', actionText: currentLanguage === 'en' ? 'Go to Contract' : '去签约' }, [RESERVATION_FLOW_STEP.CHECKIN]: { label: currentLanguage === 'en' ? 'Check-in' : '入住', actionText: currentLanguage === 'en' ? 'Go to Check-in' : '去入住' } } return map[Number(step)] || { label: currentLanguage === 'en' ? 'Current Step' : '当前步骤', actionText: currentLanguage === 'en' ? 'View Current Step' : '查看当前步骤' } } export function getReservationCurrentStepText(source = {}, language = 'zh') { const node = source && source.reservationCurrentNode ? source.reservationCurrentNode : getReservationCurrentNode(source) if (!node) { return '' } return String(node.stepDesc || '').trim() || getReservationStepMeta(node.step, language).label } export function getReservationCurrentActionText(source = {}, language = 'zh') { const node = source && source.reservationCurrentNode ? source.reservationCurrentNode : getReservationCurrentNode(source) if (!node) { return '' } return getReservationStepMeta(node.step, language).actionText } export { RESERVATION_FLOW_STEP }