更新记录
1.1.3(2026-03-25)
- 提供插件内
config.js,集中配置应用 ID 与更新服务地址 - 文档补充页面集成步骤与启动页两种 WGT 方案说明
平台兼容性
uni-app(4.11)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | - | - | √ | - | - | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | × | √ |
isir-version-update
App 热更新组件,支持 APK 全包更新(弹窗提示 + 下载安装)和 WGT 热更新(后台静默下载下次安装,或在启动页内检查→下载→安装→重启),含 ThinkPHP8 完整后端 + 企业级管理后台。
功能特性
- APK 全包更新:弹窗提示用户,显示更新日志、下载进度、自动安装
- WGT 热更新:① 后台静默下载,下次启动安装(
wgt-installermixin);② 启动页一条龙检查/下载/安装(launch-wgt-flow.js) - 强制更新模式:隐藏关闭按钮,用户必须更新
- 下载失败自动重试(最多 3 次)
- WGT 版本码本地管理,无需依赖
appWgtVersion - 含 ThinkPHP8 后端(API + 管理后台 + 建表 SQL)
- 零第三方依赖,不依赖 uview-plus 等 UI 库
快速开始
第 1 步:导入插件
在 HBuilderX 插件市场导入,或手动将 uni_modules/isir-version-update 目录复制到你的项目 src/uni_modules/ 下。
第 2 步:部署后端
- 将
server/database_init.sql导入你的 MySQL 数据库 - 将
server/thinkphp8/AppUpdate.php复制到 ThinkPHP8 项目的app/controller/目录 - 将
server/thinkphp8/CrossDomain.php复制到app/middleware/目录 - 将
server/thinkphp8/route.php中的路由配置合并到你的route/app.php - 在
config/middleware.php中注册跨域中间件:return [ 'alias' => [ 'cross' => \app\middleware\CrossDomain::class, ], ]; - 将
server/admin/appUpdate.html复制到public/admin/目录,访问http://你的域名/admin/appUpdate.html即可打开管理后台
第 3 步:修改插件内 config.js(必做)
插件根目录 uni_modules/isir-version-update/config.js 导出三项常量,安装插件后请先改为你自己的值(与后台应用 app_id、更新服务域名一致):
| 导出项 | 含义 |
|---|---|
APP_UPDATE_APP_ID |
应用唯一标识 |
APP_UPDATE_SERVER_URL |
更新服务站点根地址(如 https://api.example.com,不要带 /appUpdate/check) |
APP_UPDATE_WGT_INIT_CODE |
首次安装时的本地 WGT 数字版本码,默认 10001 |
业务页面里统一写法:
import {
APP_UPDATE_APP_ID,
APP_UPDATE_SERVER_URL,
APP_UPDATE_WGT_INIT_CODE,
} from '@/uni_modules/isir-version-update/config.js'
从插件市场升级本插件时:HBuilderX 可能覆盖
uni_modules内文件,升级前请备份config.js,升级后检查并恢复你的appId/serverUrl。
若你不希望使用 config.js,也可在模板里继续写死 appId、serverUrl(与下面「页面集成」一致即可)。
第 4 步:pages.json 建议
- 将 启动页(若使用
launch-wgt-flow或wgt-installer)放在pages数组第一项,保证冷启动先进入启动页。 - 主界面(Tab 首页、不带 Tab 的首屏)需能 常驻或尽早 挂载
<isir-version-update />,否则 APK 全包更新 不会在恰当的时机检查(WGT 若走启动页一条龙,可与组件的skipSilentWgtCheck配合,见下表)。
第 5 步:页面集成说明(在哪些页面写什么)
以下为 uni-app App(Android / iOS) 推荐集成表;H5 / 小程序不会执行原生更新逻辑。
5.1 总览
| 页面角色 | pages.json 中典型路径 |
必做? | 要放什么 |
|---|---|---|---|
| 启动页 | 如 pages/splash/index、pages/Launchpage/index |
二选一方案下必做其一 | 方式 B:mounted 里 await runLaunchWgtFlow({ appId, serverUrl, wgtInitCode } ← 来自 config.js,下同),并用 onStatus / onProgress 绑定你的加载 UI;方式 A:mixins: [wgtInstaller],实现 onWgtSkip / onWgtFail |
| 主包首页 | 如 pages/index/index(含 Tab 时多为第一个 tab 容器页) |
建议必做 | <isir-version-update />:传入与 config.js 一致的 appId、serverUrl、wgtInitCode。若启动页已用 方式 B,请加 :skipSilentWgtCheck="true",避免 WGT 查两次 |
| 其它业务子页 | 任意 | 选做 | 一般不要重复挂载组件,除非你需要独立 Tab 无首页容器 |
5.2 主包首页(APK 弹窗 + 可选 WGT 静默)
组件支持 easycom;若未配置 easycom,需 import 注册(见插件内组件路径)。
仅使用方式 A(启动页 mixin)时:首页 不要 设 skipSilentWgtCheck,以便组件在后台 静默下载 WGT,下次启动由启动页 安装。
<template>
<view>
<isir-version-update
:app-id="APP_UPDATE_APP_ID"
:server-url="APP_UPDATE_SERVER_URL"
:wgt-init-code="APP_UPDATE_WGT_INIT_CODE"
/>
<!-- 下方为你的首页内容 -->
</view>
</template>
<script>
import {
APP_UPDATE_APP_ID,
APP_UPDATE_SERVER_URL,
APP_UPDATE_WGT_INIT_CODE,
} from '@/uni_modules/isir-version-update/config.js'
export default {
data() {
return {
APP_UPDATE_APP_ID,
APP_UPDATE_SERVER_URL,
APP_UPDATE_WGT_INIT_CODE,
}
},
}
</script>
使用方式 B(启动页 runLaunchWgtFlow)时:首页组件加上 skipSilentWgtCheck,只负责 APK 与弹窗 UI:
<isir-version-update
:app-id="APP_UPDATE_APP_ID"
:server-url="APP_UPDATE_SERVER_URL"
:wgt-init-code="APP_UPDATE_WGT_INIT_CODE"
:skip-silent-wgt-check="true"
/>
5.3 启动页:方式 B(runLaunchWgtFlow)最小示例
在 mounted(Vue2)或 onMounted(Vue3) 中调用;不要在 result.waitingRestart === true 时再 uni.reLaunch(即将重启)。
import { runLaunchWgtFlow } from '@/uni_modules/isir-version-update/js_sdk/launch-wgt-flow.js'
import {
APP_UPDATE_APP_ID,
APP_UPDATE_SERVER_URL,
APP_UPDATE_WGT_INIT_CODE,
} from '@/uni_modules/isir-version-update/config.js'
// 在 methods 中:
async startSplashFlow() {
const result = await runLaunchWgtFlow({
appId: APP_UPDATE_APP_ID,
serverUrl: APP_UPDATE_SERVER_URL,
wgtInitCode: APP_UPDATE_WGT_INIT_CODE,
onStatus: (t) => { this.wgtStatusText = t },
: (n) => { this.wgtProgress = n },
})
if (result.waitingRestart) return
// 无更新或失败:再执行你的 uni.reLaunch 到登录页/首页
}
附录:方式 A(mixin)完整模板
与 第 5.1 表一致:选用方式 A 时,在启动页混入 wgtInstaller,并在 首页 挂载组件且 不要 使用 skipSilentWgtCheck。
<template>
<view class="splash" v-if="wgtInstalling">
<text>{{ wgtStatusText }}</text>
<view class="progress-bar">
<view class="progress-fill" :style="{ width: wgtProgress + '%' }"></view>
</view>
</view>
</template>
<script>
import wgtInstaller from '@/uni_modules/isir-version-update/js_sdk/wgt-installer.js'
export default {
mixins: [wgtInstaller],
methods: {
onWgtSkip() {
uni.reLaunch({ url: '/pages/index/index' })
},
onWgtFail(err) {
console.error('WGT安装失败', err)
}
}
}
</script>
mixin 提供数据: wgtInstalling、wgtProgress、wgtStatusText。
行为: 有待安装包则安装并重启;无则立即 onWgtSkip();失败则 onWgtFail(可选)后仍 onWgtSkip()。
附录:runLaunchWgtFlow(方式 B)流程与返回值
调用示例见 第 5.3 节(参数请使用 config.js 中常量)。
非 APP: Promise 得到 { skipped: true }。
APP: 若有历史 pending_wgt_* 先安装;否则请求 WGT 检查 → 有更新则下载并 plus.runtime.install → 成功后更新本地版本码并 plus.runtime.restart();无更新或失败则 { skipped: true }。
| 返回字段 | 含义 |
|---|---|
waitingRestart |
已安排重启,禁止再执行 uni.reLaunch |
skipped |
未走重启(无更新、失败、或非 APP),继续你的路由逻辑 |
Props 属性
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| appId | String | 是 | - | 应用唯一标识,区分不同 APP 项目 |
| serverUrl | String | 是 | - | 后端服务器地址,如 https://update.example.com |
| autoCheck | Boolean | 否 | true | 组件挂载后是否自动检查更新 |
| skipSilentWgtCheck | Boolean | 否 | false | 为 true 时不在组件内请求 WGT 检查/静默下载,仍会检查 APK;与启动页 launch-wgt-flow 联用时可避免重复 |
| wgtInitCode | Number | 否 | 10001 | WGT 初始版本码,第一次安装 APP 时的默认值 |
Events 事件
| 事件名 | 参数 | 说明 |
|---|---|---|
| has-update | { version, updateInfo, updateType } | 有更新可用 |
| no-update | { currentVersion } | 当前已是最新版本 |
| check-error | { error } | 检查更新失败 |
| download-progress | { type, progress, totalBytesWritten, totalBytesExpectedToWrite } | 下载进度 |
| download-error | { error, retryCount } | 下载失败 |
| install-success | { type } | 安装成功 |
| install-error | { error, type } | 安装失败 |
| wgt-ready | { version, filePath } | WGT 静默下载完成,下次启动生效 |
插件内文件一览
| 路径 | 说明 |
|---|---|
config.js |
全局配置(APP_UPDATE_*),导入插件后修改 |
js_sdk/wgt-installer.js |
启动页 mixin:仅安装待安装 WGT |
js_sdk/launch-wgt-flow.js |
runLaunchWgtFlow:启动页 WGT 检查、下载、安装、重启 |
components/isir-version-update/isir-version-update.vue |
页面组件(APK 弹窗 + WGT 静默逻辑) |
Methods 方法
| 方法名 | 说明 |
|---|---|
| manualCheck() | 手动触发检查更新(通过 ref 调用) |
<isir-version-update ref="updater" appId="xxx" serverUrl="xxx" :autoCheck="false" />
<button @click="$refs.updater.manualCheck()">检查更新</button>
WGT 版本码机制
由于 uni-app 没有原生的 WGT 版本号 API,本插件采用本地存储数字版本码的方案:
- APP 首次安装时,本地存储默认版本码(默认
10001,可通过wgtInitCode自定义) - 后台发布 WGT 时,填写比当前版本码更大的数字(如
10002) - 组件检查更新时,将本地版本码发送给后端比较
- WGT 安装成功后,自动更新本地版本码
后端 API 接口
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /appUpdate/check | 检查更新(前端组件调用) |
| POST | /appUpdate/upload | 上传安装包(管理后台调用) |
| GET | /appUpdate/list | 版本列表 |
| POST | /appUpdate/del | 删除版本 |
| POST | /appUpdate/edit | 编辑版本信息 |
| GET | /appUpdate/detail | 版本详情 |
| POST | /appUpdate/toggleStatus | 切换启用/禁用 |
| GET | /appUpdate/appList | 应用列表 |
| GET | /appUpdate/clientReport | 客户端上报版本 |
管理后台
将 server/admin/appUpdate.html 部署到后端 public/admin/ 目录,访问即可使用企业级管理界面:
- 数据统计卡片(应用数、版本数、APK/WGT 数量)
- 客户端上报版本查看(便于确定下次发版填多大的版本号)
- 版本发布(上传 APK/WGT + 填写版本号和更新日志)
- 版本编辑(修改强制更新、更新日志等)
- 版本启用/禁用/删除
静态资源
组件使用了一张弹窗背景图 static/versionUpdate.png,请将你的更新弹窗背景图放入插件的 static/ 目录中。
如果没有自定义背景图,可以在网上搜索 "app更新弹窗背景" 找一张合适的。建议尺寸:宽 600rpx,高 700rpx 左右。
注意事项
- 本插件仅支持 APP 端(Android/iOS),H5 和小程序环境会自动跳过更新检查
- APK 版本号使用语义化格式(如
1.0.0),WGT 版本码使用纯数字递增(如10001) - 上传的安装包文件存储在后端
public/uploads/app_update/{app_id}/目录下 - 后端需要 PHP 8.0+ 和 ThinkPHP 8.x
发布到 DCloud 插件市场(避免常见报错)
重要: 插件 package.json 的 id、磁盘目录名、components 下子目录名、主 vue 文件名须 完全一致(建议 全小写 + 连字符,如本插件为 isir-version-update),以便通过 easycom 校验并支持普通授权定价。在插件市场创建插件时,插件 ID 请填 isir-version-update(或 你的作者id-version-update,但与包内 id、解压目录名须一致)。
1. components/isir-version-update 不存在 / 插件包格式不正确
多为 zip 根目录多包了一层。正确做法是:解压后 第一层 就应能看到本插件的 package.json 和 components/ 目录(即与 uni_modules 插件目录结构 一致)。
- 错误:zip 里是
uni_modules/isir-version-update/...或src/uni_modules/...,或再多一层空文件夹 - 正确:在资源管理器中进入
uni_modules/isir-version-update,选中该文件夹内全部内容(或选中该文件夹本身用「压缩到 xxx.zip」,保证解压第一层即package.json+components),压缩为 标准 zip,文件名建议英文(如isir-version-update.zip)
更稳妥:在 HBuilderX 中对本插件目录下的 package.json 右键 → 发布到插件市场,由工具打包,避免手工 zip 结构错误。
2. 「仅 easycom 规范的前端组件插件可设置价格」
插件市场当前对 付费 + 自动加密 的前端组件,优先支持符合 easycom 的 uni_modules 组件;传统 uni-app(Vue2)+ 付费加密 可能与 uni-app x + 云端编译加密 规则不完全一致。若持续无法设价:
- 可先 免费发布 验证 zip 与文档;或
- 向 DCloud 插件市场工单 / 官方文档确认 「component-vue + uni-app Vue2」 是否允许与普通授权同价上架;或
- 长期方案:将主组件按官方要求迁移至 uni-app x + easycom(见 付费前端插件说明)
本插件已采用 components/isir-version-update/isir-version-update.vue,安装后可直接 不写 import、在页面使用 <isir-version-update />(与 easycom 一致);示例工程里若仍 import 组件,仅为便于说明,不影响 easycom 能力。
3. 付费插件与 uni_modules.encrypt
package.json 内已配置 uni_modules.encrypt,列出可参与加密的 JS 文件路径(相对于插件根目录)。config.js 未列入加密,便于购买「普通授权」的用户修改自己的 appId / serverUrl;若市场审核要求调整列表,以审核意见为准。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 3
赞赏 0
下载 11612657
赞赏 1885
赞赏
京公网安备:11010802035340号