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.

284 lines
8.4 KiB

2 weeks ago
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)
5 months ago
}
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))
}
2 weeks ago
appendInviteParams(query, params, true)
5 months ago
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)
}
2 weeks ago
const inviteQuery = []
appendInviteParams(inviteQuery, params, false)
if (inviteQuery.length > 0) {
targetPath += '&' + inviteQuery.join('&')
}
5 months ago
return targetPath
}
2 months ago
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 ''
}
5 months ago
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 || {}
2 weeks ago
rememberInviteParams(query)
5 months ago
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)
}
1 month ago
// 同一次分享进入只跳转一次。小程序切回前台、关闭图片预览都会再次触发 onShow,
// 且 App.onShow 仍可能带上最初的分享参数。
const handledShareTargets = Object.create(null)
export function stageShareEnter(options) {
2 weeks ago
rememberInviteParams(options && options.query)
1 month ago
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
}
5 months ago
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)
}