46 lines
1.6 KiB
JavaScript
46 lines
1.6 KiB
JavaScript
|
|
/**
|
|||
|
|
* Soul创业派对 - 小程序码 scene 参数统一编解码(海报生成 ↔ 扫码解析闭环)
|
|||
|
|
* 官方以 options.scene 接收扫码参数;后端生成码时会把 & 转为 _,故解析时同时支持 & 和 _
|
|||
|
|
* scene 同时可带两个参数:章节标识(mid/id) + 推荐人(ref)
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const SEP = '_' // 生成时统一用 _,与微信实际存储一致,且不占 32 字符限制
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 编码:生成海报/分享时组 scene 字符串(同时带 mid或id + ref)
|
|||
|
|
* @param {{ mid?: number, id?: string, ref?: string }} opts
|
|||
|
|
* @returns {string} 如 "mid=1_ref=ogpTW5fmXR" 或 "id=1.1_ref=xxx"
|
|||
|
|
*/
|
|||
|
|
function buildScene(opts) {
|
|||
|
|
const parts = []
|
|||
|
|
if (opts.mid != null && opts.mid !== '') parts.push(`mid=${opts.mid}`)
|
|||
|
|
if (opts.id) parts.push(`id=${opts.id}`)
|
|||
|
|
if (opts.ref) parts.push(`ref=${opts.ref}`)
|
|||
|
|
return parts.join(SEP)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 解码:从 options.scene 解析出 mid、id、ref(支持 & 或 _ 分隔)
|
|||
|
|
* @param {string} sceneStr 原始 scene(可能未 decodeURIComponent)
|
|||
|
|
* @returns {{ mid: number, id: string, ref: string }}
|
|||
|
|
*/
|
|||
|
|
function parseScene(sceneStr) {
|
|||
|
|
const res = { mid: 0, id: '', ref: '' }
|
|||
|
|
if (!sceneStr || typeof sceneStr !== 'string') return res
|
|||
|
|
const decoded = decodeURIComponent(String(sceneStr)).trim()
|
|||
|
|
const parts = decoded.split(/[&_]/)
|
|||
|
|
for (const part of parts) {
|
|||
|
|
const eq = part.indexOf('=')
|
|||
|
|
if (eq > 0) {
|
|||
|
|
const k = part.slice(0, eq)
|
|||
|
|
const v = part.slice(eq + 1)
|
|||
|
|
if (k === 'mid') res.mid = parseInt(v, 10) || 0
|
|||
|
|
if (k === 'id' && v) res.id = v
|
|||
|
|
if (k === 'ref' && v) res.ref = v
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return res
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { buildScene, parseScene }
|