mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-09-20 20:02:02 +08:00
feat(distribution): 增强分销功能与界面优化
- 新增银行卡管理页面,支持用户查看与管理银行卡。 - 实现添加、删除及设置默认银行卡功能。 - 优化邀请与加入页面,展示邀请人信息并改进用户提示。 - 更新海报与二维码生成逻辑,提升用户体验。 - 重构多个组件,提高可读性与可维护性。
This commit is contained in:
190
utils/distributionBind.js
Normal file
190
utils/distributionBind.js
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* 分销海报 / 商品分享扫码绑客(统一入口)
|
||||
*/
|
||||
import storage from '@/utils/storage.js'
|
||||
import store from '@/store'
|
||||
import { getGoodsDistribution } from '@/api/distribution.js'
|
||||
import { getMpScene } from '@/api/goods.js'
|
||||
|
||||
const PENDING_KEY = 'pending_distribution_id'
|
||||
|
||||
/** 本次冷启动内已尝试绑定的分销员 ID,避免重复请求 */
|
||||
const launchBoundIds = new Set()
|
||||
|
||||
let flushing = false
|
||||
|
||||
export function clearPendingDistributionId() {
|
||||
try {
|
||||
uni.removeStorageSync(PENDING_KEY)
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
export function setPendingDistributionId(distributionId) {
|
||||
if (!distributionId) return
|
||||
try {
|
||||
uni.setStorageSync(PENDING_KEY, String(distributionId))
|
||||
} catch (e) {
|
||||
console.warn('set pending distributionId failed', e)
|
||||
}
|
||||
}
|
||||
|
||||
export function getPendingDistributionId() {
|
||||
try {
|
||||
return uni.getStorageSync(PENDING_KEY) || ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
export function resetLaunchBindCache() {
|
||||
launchBoundIds.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析葵花码 scene:支持 shortLinkId 或明文 bind,{distributionId}
|
||||
*/
|
||||
export async function resolveDistributionIdFromScene(scene) {
|
||||
if (!scene) return ''
|
||||
const raw = decodeURIComponent(String(scene)).trim()
|
||||
if (!raw) return ''
|
||||
|
||||
if (raw.startsWith('bind,')) {
|
||||
const id = raw.split(',')[1]
|
||||
return id ? String(id).trim() : ''
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getMpScene(raw)
|
||||
const params = res?.data?.success ? String(res.data.result || '').trim() : ''
|
||||
if (params.startsWith('bind,')) {
|
||||
const id = params.split(',')[1]
|
||||
return id ? String(id).trim() : ''
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('resolve distribution scene failed', error)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function parseRecruitIdFromParams(params) {
|
||||
if (!params) return ''
|
||||
const text = String(params).trim()
|
||||
if (text.startsWith('recruit_')) {
|
||||
const id = text.substring('recruit_'.length)
|
||||
return id ? String(id).trim() : ''
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析图文邀请卡 scene:支持 shortLinkId 或明文 recruit_{distributionId}
|
||||
*/
|
||||
export async function resolveRecruitDistributionIdFromScene(scene) {
|
||||
if (!scene) return ''
|
||||
const raw = decodeURIComponent(String(scene)).trim()
|
||||
if (!raw) return ''
|
||||
|
||||
const direct = parseRecruitIdFromParams(raw)
|
||||
if (direct) return direct
|
||||
|
||||
try {
|
||||
const res = await getMpScene(raw)
|
||||
const params = res?.data?.success ? String(res.data.result || '').trim() : ''
|
||||
return parseRecruitIdFromParams(params)
|
||||
} catch (error) {
|
||||
console.warn('resolve recruit scene failed', error)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
const CLEAR_PENDING_CODES = new Set([22000, 22001])
|
||||
|
||||
function shouldClearPendingOnFailure(res) {
|
||||
const code = res?.data?.code
|
||||
if (code != null && CLEAR_PENDING_CODES.has(Number(code))) {
|
||||
return true
|
||||
}
|
||||
const message = String(res?.data?.message || '')
|
||||
if (message.includes('分销员不存在') || message.includes('分销功能关闭')) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试绑定分销员:已登录直接请求;未登录写入 pending
|
||||
*/
|
||||
export async function tryBindDistribution(distributionId, options = {}) {
|
||||
const id = String(distributionId || '').trim()
|
||||
if (!id) return
|
||||
|
||||
const force = options.force === true
|
||||
if (!force && launchBoundIds.has(id)) {
|
||||
return
|
||||
}
|
||||
launchBoundIds.add(id)
|
||||
|
||||
if (!storage.getAccessToken()) {
|
||||
setPendingDistributionId(id)
|
||||
store.state.distributionId = id
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getGoodsDistribution(id)
|
||||
if (res?.data?.success) {
|
||||
clearPendingDistributionId()
|
||||
store.state.distributionId = id
|
||||
return
|
||||
}
|
||||
if (shouldClearPendingOnFailure(res)) {
|
||||
clearPendingDistributionId()
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('bind distribution failed', error)
|
||||
const res = error?.data ? error : error?.response?.data ? { data: error.response.data } : null
|
||||
if (res && shouldClearPendingOnFailure(res)) {
|
||||
clearPendingDistributionId()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录成功后补绑 pending
|
||||
*/
|
||||
export async function flushPendingBind() {
|
||||
if (flushing) return
|
||||
const pendingId = getPendingDistributionId()
|
||||
if (!pendingId || !storage.getAccessToken()) {
|
||||
return
|
||||
}
|
||||
flushing = true
|
||||
try {
|
||||
launchBoundIds.delete(pendingId)
|
||||
await tryBindDistribution(pendingId, { force: true })
|
||||
} finally {
|
||||
flushing = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* App onLaunch:有 scene 则解析绑客;无 scene 清除 pending
|
||||
*/
|
||||
export async function handleAppLaunchScene(options) {
|
||||
resetLaunchBindCache()
|
||||
|
||||
const scene = options?.query?.scene
|
||||
if (!scene) {
|
||||
clearPendingDistributionId()
|
||||
return
|
||||
}
|
||||
|
||||
const distributionId = await resolveDistributionIdFromScene(scene)
|
||||
if (!distributionId) {
|
||||
return
|
||||
}
|
||||
|
||||
await tryBindDistribution(distributionId)
|
||||
}
|
||||
Reference in New Issue
Block a user