258 lines
6.4 KiB
JavaScript
258 lines
6.4 KiB
JavaScript
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 }
|