import Taro from '@tarojs/taro'; import { fetchClientConfig } from './pay-wechat'; /** 与 package.json version 同步,供服务端 minClientVersion 比对 */ export const APP_VERSION = '3.5.4'; export const APP_VERSION_LABEL = `v${APP_VERSION}`; function parseSemver(v: string): number[] { return v.split('.').map((n) => parseInt(n, 10) || 0); } export function compareSemver(a: string, b: string): number { const pa = parseSemver(a); const pb = parseSemver(b); const len = Math.max(pa.length, pb.length); for (let i = 0; i < len; i += 1) { const da = pa[i] ?? 0; const db = pb[i] ?? 0; if (da !== db) return da - db; } return 0; } function exitMiniProgramIfSupported() { if (process.env.TARO_ENV !== 'weapp') return; if (typeof Taro.exitMiniProgram !== 'function') return; void Taro.exitMiniProgram({}); } /** 微信 CDN 有新包时引导 applyUpdate;返回是否已触发更新流程 */ function tryWeappForceUpdate(min: string): Promise { if (process.env.TARO_ENV !== 'weapp' || typeof Taro.getUpdateManager !== 'function') { return Promise.resolve(false); } return new Promise((resolve) => { const manager = Taro.getUpdateManager(); let settled = false; const finish = (updated: boolean) => { if (settled) return; settled = true; resolve(updated); }; manager.onCheckForUpdate((res) => { if (!res.hasUpdate) { finish(false); return; } manager.onUpdateReady(() => { void Taro.showModal({ title: '版本过低', content: `当前 ${APP_VERSION_LABEL} 低于要求版本 v${min},已检测到新版本,请立即更新后继续使用。`, showCancel: false, confirmText: '立即更新', success: (r) => { if (r.confirm) { manager.applyUpdate(); finish(true); } else { finish(false); } }, fail: () => finish(false), }); }); manager.onUpdateFailed(() => finish(false)); }); setTimeout(() => finish(false), 4000); }); } async function enforceMinClientVersion(min: string) { const updated = await tryWeappForceUpdate(min); if (updated) return; await Taro.showModal({ title: '版本过低', content: `当前 ${APP_VERSION_LABEL} 低于要求版本 v${min},请更新至最新版本后继续使用。`, showCancel: false, confirmText: '我知道了', }); exitMiniProgramIfSupported(); } export async function checkClientVersionGate() { try { const config = await fetchClientConfig(); const min = config.minClientVersion?.trim(); if (min && compareSemver(APP_VERSION, min) < 0) { await enforceMinClientVersion(min); } } catch { /* 配置拉取失败不阻塞启动 */ } } export function setupWeappUpdateManager() { if (process.env.TARO_ENV !== 'weapp') return; if (typeof Taro.getUpdateManager !== 'function') return; const manager = Taro.getUpdateManager(); manager.onCheckForUpdate((res) => { if (!res.hasUpdate) return; manager.onUpdateReady(() => { void Taro.showModal({ title: '更新提示', content: '新版本已准备好,是否重启应用?', confirmText: '立即更新', success: (r) => { if (r.confirm) manager.applyUpdate(); }, }); }); manager.onUpdateFailed(() => { void Taro.showModal({ title: '更新失败', content: '新版本下载失败,请删除小程序后重新搜索打开。', showCancel: false, }); }); }); } export function initClientVersionChecks() { setupWeappUpdateManager(); void checkClientVersionGate(); }