Files
zkxw/mobile-h5/utils/market-h5.js
T
2026-10-13 15:18:01 +08:00

131 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { OA_H5_ORIGIN } from './config.js'
const MODULES = [
['presign', '预签约订单'],
['protocol', '协议单'],
['payment-chase', '催缴信息'],
['payment', '缴费信息'],
['freight', '运费信息']
]
const ROLE_GROUPS = [
['specialist', '专员'],
['manager', '经理']
]
const MARKET_CLOSE_ACTIONS = new Set(['market-close', 'market-done'])
/**
* 从绝对地址解析 origin(scheme + host[:port])。
* 微信小程序运行时没有可用的 URL 构造函数,不能用 new URL().origin。
*/
export function resolveHttpOrigin(value) {
const match = String(value || '')
.trim()
.match(/^(https?:\/\/[^/?#]+)/i)
return match ? match[1] : ''
}
const MARKET_H5_ORIGIN = resolveHttpOrigin(OA_H5_ORIGIN)
export const MARKET_ENTRIES = Object.freeze(
Object.fromEntries(
ROLE_GROUPS.flatMap(([role, roleLabel]) =>
MODULES.map(([module, title]) => [
role + '-' + module,
Object.freeze({
path: '/market/' + role + '/' + module,
title: title + '(' + roleLabel + ')',
groupTitle: '市场部'
})
])
)
)
)
function trimTrailingSlash(value) {
return String(value || '').replace(/\/$/, '')
}
function isSafeMiniProgramPath(value) {
const raw = String(value || '').trim()
if (!raw || raw.includes('\\') || raw.includes('#')) return false
let decoded = raw
try {
decoded = decodeURIComponent(raw)
} catch (_) {
return false
}
const pathname = decoded.split('?')[0]
if (!/^\/pages\/[A-Za-z0-9_./-]+$/.test(pathname)) return false
return pathname.split('/').every((part) => part !== '.' && part !== '..')
}
export function resolveMarketEntry(entry) {
const key = String(entry || '').trim()
return Object.prototype.hasOwnProperty.call(MARKET_ENTRIES, key)
? MARKET_ENTRIES[key]
: null
}
export function resolveMarketReturnPath(query) {
const fromQuery = String((query && query.returnPath) || '').trim()
if (isSafeMiniProgramPath(fromQuery)) return fromQuery
try {
const pages = typeof getCurrentPages === 'function' ? getCurrentPages() : []
if (pages && pages.length >= 2) {
const previous = pages[pages.length - 2]
const route =
'/' + String((previous && previous.route) || '').replace(/^\//, '')
if (isSafeMiniProgramPath(route)) return route
}
} catch (_) {
/* ignore */
}
return '/pages/index/index'
}
export function resolveMarketBackFallback(returnPath) {
return isSafeMiniProgramPath(returnPath)
? String(returnPath).trim()
: '/pages/index/index'
}
export function isMarketCloseAction(action) {
const value = String(action || '').trim()
return value !== '' && MARKET_CLOSE_ACTIONS.has(value)
}
export function isTrustedMarketCloseMessage(event, expectedWindow) {
if (!event || event.origin !== MARKET_H5_ORIGIN) return false
if (expectedWindow && event.source !== expectedWindow) return false
const payload = event.data
return (
!!payload &&
payload.source === 'zkxw-oa-h5' &&
isMarketCloseAction(payload.action)
)
}
export function canOpenMarketWebview(unloaded, token) {
return !unloaded && String(token || '').trim() !== ''
}
export function buildMarketH5Url({ entry, token, returnPath } = {}) {
const resolved = resolveMarketEntry(entry)
if (!resolved) return ''
const params = []
const authToken = String(token || '').trim()
if (authToken) {
params.push('token=' + encodeURIComponent(authToken))
}
const safeReturnPath = resolveMarketBackFallback(returnPath)
params.push('returnPath=' + encodeURIComponent(safeReturnPath))
return (
trimTrailingSlash(OA_H5_ORIGIN) +
resolved.path +
'?' +
params.join('&')
)
}