132 lines
3.7 KiB
TypeScript
132 lines
3.7 KiB
TypeScript
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<boolean> {
|
|
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();
|
|
}
|