You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
8.4 KiB
283 lines
8.4 KiB
const INVITE_CONTEXT_KEY = 'inviteShareContext'
|
|
const INVITE_DEVICE_KEY = 'inviteDeviceId'
|
|
|
|
function isBlank(value) {
|
|
return value === undefined || value === null || String(value).trim() === ''
|
|
}
|
|
|
|
function readCurrentRegionId() {
|
|
try {
|
|
const area = uni.getStorageSync('area')
|
|
if (!area) return ''
|
|
const data = typeof area === 'string' ? JSON.parse(area) : area
|
|
return data && data.id ? String(data.id) : ''
|
|
} catch (e) {
|
|
return ''
|
|
}
|
|
}
|
|
|
|
function appendParam(query, key, value) {
|
|
if (isBlank(value)) return
|
|
query.push(key + '=' + encodeURIComponent(String(value)))
|
|
}
|
|
|
|
export function getInviteDeviceId() {
|
|
let deviceId = ''
|
|
try {
|
|
deviceId = uni.getStorageSync(INVITE_DEVICE_KEY) || ''
|
|
} catch (e) {}
|
|
if (deviceId) return deviceId
|
|
deviceId = 'dev_' + Date.now() + '_' + Math.random().toString(36).slice(2, 12)
|
|
try {
|
|
uni.setStorageSync(INVITE_DEVICE_KEY, deviceId)
|
|
} catch (e) {}
|
|
return deviceId
|
|
}
|
|
|
|
export function getCurrentInviteParams() {
|
|
return {
|
|
inviterId: uni.getStorageSync('id') || '',
|
|
regionId: readCurrentRegionId()
|
|
}
|
|
}
|
|
|
|
export function normalizeInviteParams(params) {
|
|
params = params || {}
|
|
const inviterId = params.inviterId || params.inviteUserId || ''
|
|
const regionId = params.regionId || params.inviteRegionId || ''
|
|
return {
|
|
inviterId: isBlank(inviterId) ? '' : String(inviterId),
|
|
regionId: isBlank(regionId) ? '' : String(regionId)
|
|
}
|
|
}
|
|
|
|
function resolveInviteParams(params, useCurrentFallback) {
|
|
const invite = normalizeInviteParams(params)
|
|
if ((!invite.inviterId || !invite.regionId) && useCurrentFallback) {
|
|
const current = getCurrentInviteParams()
|
|
if (!invite.inviterId) invite.inviterId = current.inviterId
|
|
if (!invite.regionId) invite.regionId = current.regionId
|
|
}
|
|
return invite
|
|
}
|
|
|
|
function appendInviteParams(query, params, useCurrentFallback) {
|
|
const invite = resolveInviteParams(params, useCurrentFallback)
|
|
appendParam(query, 'inviterId', invite.inviterId)
|
|
appendParam(query, 'regionId', invite.regionId)
|
|
}
|
|
|
|
export function rememberInviteParams(params) {
|
|
const invite = normalizeInviteParams(params)
|
|
if (!invite.inviterId || !invite.regionId) return invite
|
|
try {
|
|
uni.setStorageSync(INVITE_CONTEXT_KEY, invite)
|
|
} catch (e) {}
|
|
return invite
|
|
}
|
|
|
|
export function getStoredInviteParams() {
|
|
try {
|
|
const stored = uni.getStorageSync(INVITE_CONTEXT_KEY)
|
|
if (!stored) return { inviterId: '', regionId: '' }
|
|
return normalizeInviteParams(typeof stored === 'string' ? JSON.parse(stored) : stored)
|
|
} catch (e) {
|
|
return { inviterId: '', regionId: '' }
|
|
}
|
|
}
|
|
|
|
export function parseQueryString(queryString) {
|
|
const result = {}
|
|
String(queryString || '').split('&').forEach((item) => {
|
|
if (!item) return
|
|
const pair = item.split('=')
|
|
const key = pair[0]
|
|
if (!key) return
|
|
const value = pair.slice(1).join('=')
|
|
try {
|
|
result[key] = decodeURIComponent(value || '')
|
|
} catch (e) {
|
|
result[key] = value || ''
|
|
}
|
|
})
|
|
return result
|
|
}
|
|
|
|
export function extractInviteParamsFromUrl(url) {
|
|
const value = String(url || '')
|
|
const queryIndex = value.indexOf('?')
|
|
if (queryIndex === -1) return { inviterId: '', regionId: '' }
|
|
return normalizeInviteParams(parseQueryString(value.slice(queryIndex + 1)))
|
|
}
|
|
|
|
export function buildInviteHomeSharePath(params) {
|
|
params = params || {}
|
|
const query = ['shareType=invite']
|
|
if (!isBlank(params.tabIndex)) {
|
|
appendParam(query, 'tabIndex', params.tabIndex)
|
|
}
|
|
appendInviteParams(query, params, true)
|
|
return '/pages/index/index?' + query.join('&')
|
|
}
|
|
|
|
export function buildHomeSharePath(targetPath, params) {
|
|
const inviteQuery = []
|
|
appendInviteParams(inviteQuery, params || {}, true)
|
|
if (!targetPath) {
|
|
return inviteQuery.length > 0 ? '/pages/index/index?' + inviteQuery.join('&') : '/pages/index/index'
|
|
}
|
|
let finalTargetPath = targetPath
|
|
if (inviteQuery.length > 0) {
|
|
finalTargetPath += (finalTargetPath.indexOf('?') === -1 ? '?' : '&') + inviteQuery.join('&')
|
|
}
|
|
return '/pages/index/index?targetPath=' + encodeURIComponent(finalTargetPath)
|
|
}
|
|
|
|
export function buildGroupHomeSharePath(params) {
|
|
params = params || {}
|
|
const query = [
|
|
'shareType=group',
|
|
'type=shop',
|
|
'shopId=' + encodeURIComponent(params.shopId || ''),
|
|
'groupId=' + encodeURIComponent(params.groupId || ''),
|
|
'targetMembers=' + encodeURIComponent(params.targetMembers || 2),
|
|
'isFaceToFace=' + encodeURIComponent(params.isFaceToFace || 0)
|
|
]
|
|
if (params.orderScene) {
|
|
query.push('orderScene=' + encodeURIComponent(params.orderScene))
|
|
}
|
|
appendInviteParams(query, params, true)
|
|
return '/pages/index/index?' + query.join('&')
|
|
}
|
|
|
|
export function buildGroupTargetPath(params) {
|
|
params = params || {}
|
|
if (!params.shopId || !params.groupId) return ''
|
|
let targetPath = '/package2/group/groupBuySingle?type=shop' +
|
|
'&shopId=' + encodeURIComponent(params.shopId) +
|
|
'&groupId=' + encodeURIComponent(params.groupId) +
|
|
'&targetMembers=' + encodeURIComponent(params.targetMembers || 2) +
|
|
'&isFaceToFace=' + encodeURIComponent(params.isFaceToFace || 0)
|
|
if (params.orderScene) {
|
|
targetPath += '&orderScene=' + encodeURIComponent(params.orderScene)
|
|
}
|
|
const inviteQuery = []
|
|
appendInviteParams(inviteQuery, params, false)
|
|
if (inviteQuery.length > 0) {
|
|
targetPath += '&' + inviteQuery.join('&')
|
|
}
|
|
return targetPath
|
|
}
|
|
|
|
export function buildGroupShopTargetPath(shopId) {
|
|
if (!shopId) return ''
|
|
return '/package2/group/groupBuySingle?type=shop&shopId=' + encodeURIComponent(shopId)
|
|
}
|
|
|
|
export function resolveMiniCodeSceneTarget(scene) {
|
|
let value = String(scene || '').trim()
|
|
if (!value) return ''
|
|
try {
|
|
value = decodeURIComponent(value)
|
|
} catch (e) {}
|
|
if (!value) return ''
|
|
if (value.indexOf('groupShop:') === 0) {
|
|
return buildGroupShopTargetPath(value.replace('groupShop:', ''))
|
|
}
|
|
if (/^s[A-Za-z0-9_-]{1,31}$/.test(value)) {
|
|
return buildGroupShopTargetPath(value.slice(1))
|
|
}
|
|
return ''
|
|
}
|
|
|
|
export function normalizeShareTargetPath(value) {
|
|
let targetPath = String(value || '')
|
|
if (targetPath.indexOf('%2F') === 0 || targetPath.indexOf('%2f') === 0) {
|
|
try {
|
|
targetPath = decodeURIComponent(targetPath)
|
|
} catch (e) {}
|
|
}
|
|
if (!targetPath || targetPath.charAt(0) !== '/') return ''
|
|
if (targetPath.indexOf('/pages/index/index') === 0) return ''
|
|
return targetPath
|
|
}
|
|
|
|
export function resolveHomeShareTarget(query) {
|
|
query = query || {}
|
|
rememberInviteParams(query)
|
|
if (query.shareType === 'group') {
|
|
return buildGroupTargetPath(query)
|
|
}
|
|
if (query.targetPath) {
|
|
return normalizeShareTargetPath(query.targetPath)
|
|
}
|
|
return ''
|
|
}
|
|
|
|
export function isShareEnterScene(options) {
|
|
if (!options || options.scene == null) return false
|
|
const scene = Number(options.scene)
|
|
return scene === 1007 || scene === 1008 || scene === 1044 || scene === 1154
|
|
}
|
|
|
|
export function getEnterShareTarget(options) {
|
|
if (!options) {
|
|
try {
|
|
if (uni.getEnterOptionsSync) {
|
|
options = uni.getEnterOptionsSync()
|
|
} else if (uni.getLaunchOptionsSync) {
|
|
options = uni.getLaunchOptionsSync()
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
if (!isShareEnterScene(options)) return ''
|
|
return resolveHomeShareTarget(options && options.query)
|
|
}
|
|
|
|
// 同一次分享进入只跳转一次。小程序切回前台、关闭图片预览都会再次触发 onShow,
|
|
// 且 App.onShow 仍可能带上最初的分享参数。
|
|
const handledShareTargets = Object.create(null)
|
|
|
|
export function stageShareEnter(options) {
|
|
rememberInviteParams(options && options.query)
|
|
const targetPath = resolveMiniCodeSceneTarget(options && options.query && options.query.scene) || getEnterShareTarget(options)
|
|
if (!targetPath) return { targetPath: '', alreadyHandled: false }
|
|
if (handledShareTargets[targetPath]) return { targetPath: '', alreadyHandled: true }
|
|
return { targetPath: targetPath, alreadyHandled: false }
|
|
}
|
|
|
|
export function isShareTargetHandled(targetPath) {
|
|
return !!(targetPath && handledShareTargets[targetPath])
|
|
}
|
|
|
|
export function completeShareEnter(targetPath) {
|
|
if (targetPath) handledShareTargets[targetPath] = true
|
|
}
|
|
|
|
export function reopenShareEnter(targetPath) {
|
|
if (targetPath) delete handledShareTargets[targetPath]
|
|
}
|
|
|
|
let suppressShareRedirectOnce = false
|
|
|
|
export function suppressNextShareRedirect() {
|
|
suppressShareRedirectOnce = true
|
|
}
|
|
|
|
export function consumeShareRedirectSuppression() {
|
|
if (!suppressShareRedirectOnce) return false
|
|
suppressShareRedirectOnce = false
|
|
return true
|
|
}
|
|
|
|
export function getCurrentEnterShareTarget() {
|
|
let options = null
|
|
try {
|
|
if (uni.getEnterOptionsSync) {
|
|
options = uni.getEnterOptionsSync()
|
|
} else if (uni.getLaunchOptionsSync) {
|
|
options = uni.getLaunchOptionsSync()
|
|
}
|
|
} catch (e) {}
|
|
return getEnterShareTarget(options)
|
|
}
|
|
|