feat(upgrade): 优化版本更新检测流程并添加问题版本修复机制

This commit is contained in:
2025-12-29 18:07:29 +08:00
parent b2bff1ed54
commit ec869f0395
6 changed files with 94 additions and 47 deletions

View File

@@ -14,6 +14,7 @@ const BASE_URL_MAP = {
}, },
production: { production: {
MAIN: 'https://global.nuttyreading.com/', MAIN: 'https://global.nuttyreading.com/',
// MAIN: 'http://192.168.110.100:9300/pb/', // 张川川
// PAYMENT: 'https://pay.example.com', // 暂时用不到 // PAYMENT: 'https://pay.example.com', // 暂时用不到
// CDN: 'https://cdn.example.com', // 暂时用不到 // CDN: 'https://cdn.example.com', // 暂时用不到
}, },

View File

@@ -2,9 +2,21 @@ import { mainClient, skeletonClient } from '@/api/clients'
import type { IApiResponse } from '@/api/types' import type { IApiResponse } from '@/api/types'
/** /**
* 请求更新包 * 请求备用更新包
*/ */
export async function requestUpdatePackage(type: string, version: string) { export async function requestUpdatePackage(type: string, version: string) {
const res = await skeletonClient.request<IApiResponse>({
url: 'common/apkConfig/getBackupUpdateUrl',
method: 'POST',
data: { type, version }
})
return res
}
/**
* 检测问题版本号及修复更新包
*/
export async function checkProblemVersion(type: string, version: string) {
const res = await skeletonClient.request<IApiResponse>({ const res = await skeletonClient.request<IApiResponse>({
url: 'common/apkConfig/getUpdateUrl', url: 'common/apkConfig/getUpdateUrl',
method: 'POST', method: 'POST',

View File

@@ -101,6 +101,7 @@
<!-- 活动图书模块 --> <!-- 活动图书模块 -->
<view class="activity-block"> <view class="activity-block">
<Skeleton <Skeleton
ref="activityLabelsSkeleton"
theme="image-card" theme="image-card"
:size="Array(5).fill({ height:'28px', width: '18%' })" :size="Array(5).fill({ height:'28px', width: '18%' })"
:request="getActivityLabels" :request="getActivityLabels"
@@ -272,6 +273,7 @@ const myBookSkeleton = ref()
const recommendBooksSkeleton = ref() const recommendBooksSkeleton = ref()
// 活动图书 // 活动图书
const activityLabelsSkeleton = ref()
const activityBooksSkeleton = ref() const activityBooksSkeleton = ref()
const activityLabelList = ref<ILabel[]>([]) const activityLabelList = ref<ILabel[]>([])
const currentActivityIndex = ref(0) const currentActivityIndex = ref(0)
@@ -443,6 +445,7 @@ const handleRefresh = async () => {
await Promise.all([ await Promise.all([
myBookSkeleton.value?.reload(), myBookSkeleton.value?.reload(),
recommendBooksSkeleton.value?.reload(), recommendBooksSkeleton.value?.reload(),
activityLabelsSkeleton.value?.reload(),
categoryLevel1LabelSkeleton.value?.reload() categoryLevel1LabelSkeleton.value?.reload()
]) ])
} catch (error) { } catch (error) {

View File

@@ -14,7 +14,8 @@
> >
<text class="label">{{ item.label }}</text> <text class="label">{{ item.label }}</text>
<view class="value-wrapper"> <view class="value-wrapper">
<text class="value">{{ item.value }}</text> <wd-loading v-if="item.id === 4 && !isUpdateAvailable" :size="16" color="#cccccc" />
<text v-else class="value">{{ item.value }}</text>
<wd-icon name="arrow-right" size="16px" color="#aaa" /> <wd-icon name="arrow-right" size="16px" color="#aaa" />
</view> </view>
</view> </view>
@@ -73,7 +74,7 @@ import { useI18n } from 'vue-i18n'
import { useMessage } from '@/uni_modules/wot-design-uni' import { useMessage } from '@/uni_modules/wot-design-uni'
import { makePhoneCall, copyToClipboard } from '@/utils/index' import { makePhoneCall, copyToClipboard } from '@/utils/index'
// #ifdef APP-PLUS // #ifdef APP-PLUS
import update from "@/uni_modules/uni-upgrade-center-app/utils/check-update"; import checkUpdate from "@/uni_modules/uni-upgrade-center-app/utils/check-update";
import { getCurrentVersion } from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version' import { getCurrentVersion } from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version'
// #endif // #endif
@@ -211,11 +212,13 @@ const selectLanguage = (languageCode: string) => {
/** /**
* 检查版本更新 * 检查版本更新
*/ */
const isUpdateAvailable = ref(true)
const checkVersion = async () => { const checkVersion = async () => {
// #ifdef APP-PLUS // #ifdef APP-PLUS
uni.showLoading() if (!isUpdateAvailable.value) return
isUpdateAvailable.value = false
try { try {
const info = await update(); const info = await checkUpdate();
if(info.result.code == 0){ if(info.result.code == 0){
uni.showToast({ uni.showToast({
title:info.result.message, title:info.result.message,
@@ -223,15 +226,14 @@ const checkVersion = async () => {
}) })
} }
} catch (error: any) { } catch (error: any) {
console.error('版本检测失败:', error)
const msg = error?.hasOwnProperty('message') && error.message const msg = error?.hasOwnProperty('message') && error.message
uni.showToast({ uni.showToast({
title: msg || t('user.checkVersionFailed'), title: msg || error || t('global.queryFailed'),
icon: 'none', icon: 'none',
duration: 5000 duration: 5000
}) })
} finally { } finally {
uni.hideLoading() isUpdateAvailable.value = true
} }
// #endif // #endif

View File

@@ -1,4 +1,4 @@
import { requestUpdatePackage } from '@/api/modules/sys' import { requestUpdatePackage, checkProblemVersion } from '@/api/modules/sys'
import { getMaxVersion } from './tools' import { getMaxVersion } from './tools'
import { getFileExtension } from '@/utils' import { getFileExtension } from '@/utils'
@@ -8,19 +8,34 @@ import { getFileExtension } from '@/utils'
export default async function checkUpdate() { export default async function checkUpdate() {
// #ifdef APP-PLUS // #ifdef APP-PLUS
try { try {
const upgradeData = await getUpgradeCheckData() /** ① 先判断是否问题版本 */
const currentVersion = await getCurrentVersion()
if (!currentVersion) {
throw new Error('获取当前版本号失败')
}
// 优先调用 uni-upgrade-center3 秒超时) const problemRes = await checkProblemVersion('10', currentVersion)
if (!!problemRes?.updateUrl) {
console.warn('命中问题版本,使用修复更新包更新')
return handleBackupResponse(problemRes)
}
/** ② 非问题版本,再走 uni-upgrade-center3 秒超时) */
console.log('当前客户端无问题继续uniCloud版本检测')
const upgradeData = await getUpgradeCheckData()
const result = await withTimeout( const result = await withTimeout(
callUpgradeCenter(upgradeData), callUpgradeCenter(upgradeData),
3000 3000
) )
console.log('检查版本更新成功:', result) console.log('uniCloud 检测成功:', result)
return result return result
} catch (err) { } catch (err) {
console.warn('uniCloud更新方案失败启用备用方案:', err?.message) /** ③ uniCloud 异常兜底 */
return await useBackupUpdate() throw '更新检测失败, 如需升级请卸载后重新安装'
// console.warn('uniCloud 更新检测失败,启用备用方案')
// return await useBackupUpdate()
} }
// #endif // #endif
@@ -29,6 +44,24 @@ export default async function checkUpdate() {
// #endif // #endif
} }
/**
* 处理备用更新响应
*/
function handleBackupResponse(res) {
return {
result: {
url: res.updateUrl,
platform: ['Android', 'Ios'],
type: getFileExtension(res.updateUrl),
is_mandatory: true,
is_backup_update: true,
title: "更新",
contents: "当前版本已经弃用,请立即更新",
...res,
}
}
}
/** /**
* 备用更新方案 * 备用更新方案
*/ */
@@ -39,26 +72,17 @@ async function useBackupUpdate() {
throw { message: '获取当前版本号失败' } throw { message: '获取当前版本号失败' }
} }
console.log('当前版本号:', currentVersion) try {
const res = await requestUpdatePackage('10', currentVersion)
const res = await requestUpdatePackage('10', currentVersion) if (!res || !res.updateUrl) {
throw { message: '没有匹配的更新包,当前版本无需升级,如您确定有更新,请卸载本版本后前往应用市场重新安装' }
if (!res || !res.updateUrl) {
throw { message: '没有匹配的更新包,当前版本无需升级,如您确定有更新,请卸载本版本后前往应用市场重新安装' }
}
// 将服务器返回的更新信息转换为 uni-upgrade-center 格式
return {
result: {
...res,
url: res.updateUrl,
platform: ['Android', 'Ios'],
type: getFileExtension(res.updateUrl),
is_mandatory: true,
is_backup_update: true,
title: "更新",
contents: "当前版本已经弃用,请立即更新",
} }
// 将服务器返回的更新信息转换为 uni-upgrade-center 格式
return handleBackupResponse(res)
} catch (err) {
console.warn('备用更新检测失败:', err)
throw err.errMsg || err.message || '备用更新检测失败'
} }
} }
@@ -67,6 +91,11 @@ async function useBackupUpdate() {
*/ */
function callUpgradeCenter(data) { function callUpgradeCenter(data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!uniCloud?.callFunction) {
reject(new Error('uniCloud 未初始化'))
return
}
uniCloud.callFunction({ uniCloud.callFunction({
name: 'uni-upgrade-center', name: 'uni-upgrade-center',
data, data,
@@ -83,7 +112,7 @@ function withTimeout(promise, timeout) {
return Promise.race([ return Promise.race([
promise, promise,
new Promise((_, reject) => new Promise((_, reject) =>
setTimeout(() => reject(new Error('请求超时')), timeout) setTimeout(() => reject(new Error('更新检测超时')), timeout)
) )
]) ])
} }

View File

@@ -17,22 +17,23 @@ export default function() {
platform, // 安装包平台 platform, // 安装包平台
type // 安装包类型 type // 安装包类型
} = e.result; } = e.result;
// 没有更新直接返回查询结果
if (code === 0 && !is_backup_update) return resolve(e)
const hasUpdate = code > 0 || is_backup_update const hasUpdate = code > 0 || is_backup_update
// 如果不是备用更新,需要处理下载链接 // 如果有更新,根据是否静默更新选择不同处理方式
if (!is_backup_update) {
const {
fileList
} = await uniCloud.getTempFileURL({
fileList: [url]
});
e.result.url = fileList[0].tempFileURL;
}
// 此处逻辑仅为实例,可自行编写
if (hasUpdate) { if (hasUpdate) {
resolve(e) // 如果不是备用更新,需要处理下载链接
if (!is_backup_update) {
const {
fileList
} = await uniCloud.getTempFileURL({
fileList: [url]
});
e.result.url = fileList[0].tempFileURL;
}
// 静默更新只有wgt有 // 静默更新只有wgt有
if (is_silently) { if (is_silently) {
@@ -75,10 +76,9 @@ export default function() {
console.error(message) console.error(message)
return reject(e) return reject(e)
} }
return resolve(e)
}).catch(err => { }).catch(err => {
// TODO 云函数报错处理 // TODO 云函数报错处理
console.error(err.message) console.error(err)
reject(err) reject(err)
}) })
}); });