Эх сурвалжийг харах

fix: app强制升级配置

liangan 3 долоо хоног өмнө
parent
commit
d14dae1df4
40 өөрчлөгдсөн 3093 нэмэгдсэн , 8 устгасан
  1. 2 2
      manifest.config.ts
  2. 1 1
      package.json
  3. 288 2
      pages.config.ts
  4. 3 1
      src/App.vue
  5. 2 2
      src/manifest.json
  6. 15 0
      src/pages.json
  7. 123 0
      src/uni_modules/uni-upgrade-center-app/changelog.md
  8. 122 0
      src/uni_modules/uni-upgrade-center-app/package.json
  9. 547 0
      src/uni_modules/uni-upgrade-center-app/pages/uni-app-x/upgrade-popup.uvue
  10. 677 0
      src/uni_modules/uni-upgrade-center-app/pages/upgrade-popup.vue
  11. 1 0
      src/uni_modules/uni-upgrade-center-app/readme.md
  12. BIN
      src/uni_modules/uni-upgrade-center-app/static/app/app_update_close.png
  13. BIN
      src/uni_modules/uni-upgrade-center-app/static/app/bg_top.png
  14. 1 0
      src/uni_modules/uni-upgrade-center-app/uniCloud/database/db_init.json
  15. 120 0
      src/uni_modules/uni-upgrade-center-app/utils/call-check-version.ts
  16. 184 0
      src/uni_modules/uni-upgrade-center-app/utils/check-update-nvue.js
  17. 228 0
      src/uni_modules/uni-upgrade-center-app/utils/check-update.ts
  18. 46 0
      src/uni_modules/uni-upgrade-center-app/utils/utils.ts
  19. 10 0
      src/uni_modules/uts-openSchema/changelog.md
  20. 83 0
      src/uni_modules/uts-openSchema/package.json
  21. 59 0
      src/uni_modules/uts-openSchema/readme.md
  22. 3 0
      src/uni_modules/uts-openSchema/utssdk/app-android/config.json
  23. 27 0
      src/uni_modules/uts-openSchema/utssdk/app-android/index.uts
  24. 20 0
      src/uni_modules/uts-openSchema/utssdk/app-harmony/index.uts
  25. 3 0
      src/uni_modules/uts-openSchema/utssdk/app-ios/config.json
  26. 20 0
      src/uni_modules/uts-openSchema/utssdk/app-ios/index.uts
  27. 2 0
      src/uni_modules/uts-openSchema/utssdk/interface.uts
  28. 12 0
      src/uni_modules/uts-openSchema/utssdk/web/index.uts
  29. 28 0
      src/uni_modules/uts-progressNotification/changelog.md
  30. 85 0
      src/uni_modules/uts-progressNotification/package.json
  31. 71 0
      src/uni_modules/uts-progressNotification/readme.md
  32. 11 0
      src/uni_modules/uts-progressNotification/utssdk/app-android/AndroidManifest.xml
  33. 62 0
      src/uni_modules/uts-progressNotification/utssdk/app-android/TransparentActivity.uts
  34. 19 0
      src/uni_modules/uts-progressNotification/utssdk/app-android/callbacks.uts
  35. 3 0
      src/uni_modules/uts-progressNotification/utssdk/app-android/config.json
  36. 2 0
      src/uni_modules/uts-progressNotification/utssdk/app-android/constant.uts
  37. 156 0
      src/uni_modules/uts-progressNotification/utssdk/app-android/index.uts
  38. 11 0
      src/uni_modules/uts-progressNotification/utssdk/app-android/res/values/notification_progress_styles.xml
  39. 46 0
      src/uni_modules/uts-progressNotification/utssdk/interface.uts
  40. 0 0
      src/uni_modules/uts-progressNotification/utssdk/unierror.uts

+ 2 - 2
manifest.config.ts

@@ -24,8 +24,8 @@ export default defineManifestConfig({
   'name': VITE_APP_TITLE,
   'appid': VITE_UNI_APPID,
   'description': '',
-  'versionName': '1.0.0',
-  'versionCode': '100',
+  'versionName': '1.1.0',
+  'versionCode': '110',
   'transformPx': false,
   'locale': VITE_FALLBACK_LOCALE === 'bn' ? 'bn' : 'en', // 此app需默认英文
   'fallbackLocale': 'en',

+ 1 - 1
package.json

@@ -4,7 +4,7 @@
   "version": "3.2.0",
   "packageManager": "pnpm@10.10.0",
   "description": "BandhuBuy - APP",
-  "update-time": "2025-09-05",
+  "update-time": "2025-09-09",
   "author": {
     "name": "feige996",
     "zhName": "菲鸽",

+ 288 - 2
pages.config.ts

@@ -16,8 +16,7 @@ export default defineUniPages({
     custom: {
       '^fg-(.*)': '@/components/fg-$1/fg-$1.vue',
       '^wd-(.*)': 'wot-design-uni/components/wd-$1/wd-$1.vue',
-      '^(?!z-paging-refresh|z-paging-load-more)z-paging(.*)':
-        'z-paging/components/z-paging$1/z-paging$1.vue',
+      '^(?!z-paging-refresh|z-paging-load-more)z-paging(.*)': 'z-paging/components/z-paging$1/z-paging$1.vue',
     },
   },
   /**
@@ -57,4 +56,291 @@ export default defineUniPages({
       },
     ],
   },
+  pages: [
+    {
+      path: 'pages/index/index',
+      type: 'home',
+      layout: 'tabbar',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/bestSellers/bestSellers',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/forgotPassword/forgotPassword',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/income/income',
+      type: 'page',
+      layout: 'tabbar',
+      needLogin: true,
+      style: {
+        navigationBarTitleText: '%income.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/login/login',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/mine/addressBook',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%addressBook.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/mine/addressBookOperate',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%addressBook.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/mine/mine',
+      type: 'page',
+      layout: 'tabbar',
+      needLogin: true,
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/mine/myFavorite',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%mine.pages.myFavorite.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/mine/myProfile',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%myProfile.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/mine/setting',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%setting.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/mine/share',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+        navigationBarTitleText: '%mine.pages.share.title%',
+      },
+    },
+    {
+      path: 'pages/missionCenter/missionCenter',
+      type: 'page',
+      layout: 'default',
+      needLogin: true,
+      style: {
+        navigationBarTitleText: '%missionCenter.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/myOrders/myOrders',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%myOrders.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/myOrders/orderDetail',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%orderDetail.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/notifications/notifications',
+      type: 'page',
+      layout: 'default',
+      needLogin: true,
+      style: {
+        navigationBarTitleText: '%notifications.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/productDetail/checkOut',
+      type: 'page',
+      layout: 'default',
+      needLogin: true,
+      style: {
+        navigationBarTitleText: '%checkout.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/productDetail/productDetail',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/referEarn/referEarn',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/register/register',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/search/search',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/topChampions/topChampions',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+      },
+    },
+    {
+      path: 'pages/vipMembership/vipMembership',
+      type: 'page',
+      layout: 'default',
+      needLogin: true,
+      style: {
+        navigationBarTitleText: '%vipMembership.title%',
+        navigationBarBackgroundColor: '#FFFFFF',
+      },
+    },
+    {
+      path: 'pages/wallet/myWallet',
+      type: 'page',
+      layout: 'default',
+      needLogin: true,
+      style: {
+        navigationBarTitleText: '%wallet.myWallet.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/wallet/recharge',
+      type: 'page',
+      layout: 'default',
+      style: {
+        'navigationBarTitleText': '%wallet.recharge.title%',
+        'navigationBarBackgroundColor': '#fff',
+        'app-plus': {
+          titleNView: {
+            buttons: [
+              {
+                text: 'Record',
+                fontSize: '28rpx',
+                width: '85px',
+              },
+            ],
+          },
+        },
+      },
+    },
+    {
+      path: 'pages/wallet/rechargeRecord',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%wallet.rechargeRecord.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/wallet/withdraw',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationStyle: 'custom',
+        navigationBarTitleText: '%wallet.withdraw.title%',
+      },
+    },
+    {
+      path: 'pages/wallet/withdrawRecord',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%wallet.withdrawRecord.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/webLink/webLink',
+      type: 'page',
+      layout: 'default',
+      needLogin: true,
+      style: {
+        navigationBarTitleText: '',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'uni_modules/uni-upgrade-center-app/pages/upgrade-popup',
+      style: {
+        'disableScroll': true,
+        'app-plus': {
+          backgroundColorTop: 'transparent',
+          background: 'transparent',
+          titleNView: false,
+          scrollIndicator: false,
+          popGesture: 'none',
+          animationType: 'fade-in',
+          animationDuration: 200,
+        },
+      },
+    },
+  ],
 })

+ 3 - 1
src/App.vue

@@ -2,7 +2,7 @@
 import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
 import { usePageAuth } from '@/hooks/usePageAuth'
 import { useUserStore } from '@/store'
-
+import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update'
 import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
 
 const mtpushModule = uni.requireNativePlugin('EL-MTPush')
@@ -85,6 +85,8 @@ onLaunch(() => {
       })
     })
   }
+  // app更新
+  checkUpdate()
 })
 onShow(() => {
   console.log('App Show')

+ 2 - 2
src/manifest.json

@@ -2,8 +2,8 @@
   "name": "BandhuBuy",
   "appid": "__UNI__D38110B",
   "description": "",
-  "versionName": "1.0.0",
-  "versionCode": "100",
+  "versionName": "1.1.0",
+  "versionCode": "110",
   "transformPx": false,
   "app-plus": {
     "usingComponents": true,

+ 15 - 0
src/pages.json

@@ -314,6 +314,21 @@
         "navigationBarTitleText": "",
         "navigationBarBackgroundColor": "#fff"
       }
+    },
+    {
+      "path": "uni_modules/uni-upgrade-center-app/pages/upgrade-popup",
+      "style": {
+        "disableScroll": true,
+        "app-plus": {
+          "backgroundColorTop": "transparent",
+          "background": "transparent",
+          "titleNView": false,
+          "scrollIndicator": false,
+          "popGesture": "none",
+          "animationType": "fade-in",
+          "animationDuration": 200
+        }
+      }
     }
   ],
   "subPackages": []

+ 123 - 0
src/uni_modules/uni-upgrade-center-app/changelog.md

@@ -0,0 +1,123 @@
+## 0.9.7(2025-07-28)
+- 修复 使用腾讯云时,wgt 更新报错的Bug
+- 改进 uni-app-x 平台弹窗该用 script setup 实现
+## 0.9.6(2025-04-01)
+- 新增 升级中心适配鸿蒙 uni-app x **需要 HBuilderX 4.61+**
+## 0.9.5(2025-02-06)
+- 新增 完善下载失败时的处理逻辑
+## 0.9.4(2024-12-28)
+- 修复 腾讯云在使用扩展存储时报错的 Bug
+## 0.9.3(2024-12-23)
+- 修复 升级中心在大屏上的显示效果
+## 0.9.2(2024-11-06)
+- 更新 部分 ts 类型
+## 0.9.1(2024-11-01)
+- 更新 支持 HarmonyOS Next 设备整包更新、wgt 更新。需要 `HBuilderX 4.32+` [详情](https://doc.dcloud.net.cn/uniCloud/upgrade-center.html#uni-upgrade-center-app-harmonyos)
+## 0.9.0(2024-10-30)
+- **重要更新** 在 uni-app x 项目中弃用之前弹窗方案使用[dialogPage](https://doc.dcloud.net.cn/uni-app-x/api/dialog-page.html)实现,需要 `HBuilderX 4.31+`
+## 0.8.5(2024-10-26)
+- 优化 去除不必要代码
+## 0.8.4(2024-10-26)
+- 修复  uni-app x 项目升级到 4.31 alpha 后中间有空隙的Bug
+## 0.8.3(2024-07-31)
+- 修复 部分类型报错
+## 0.8.2(2024-07-15)
+- 更新 static 下的静态图片放入 static/app 目录下,防止编译除 app 平台以外的平台时带入
+## 0.8.1(2024-04-28)
+- 修复 在 HX 4.0.3+ uni-app x 项目运行到 Android 调不起安装的Bug
+## 0.8.0(2024-04-15)
+- 修复 更新弹窗 data 中新增初始化字段
+## 0.7.9(2024-03-15)
+- 移除无用代码
+- 调整 is_silently 类型为可为 null
+## 0.7.8(2024-01-04)
+- 新增 移除无用代码
+## 0.7.7(2024-01-04)
+- 新增 uni-app x 项目中新增 @show 回调
+## 0.7.6(2023-12-21)
+- 修复 iOS使用升级中心云打包时报错(使用新版的 [uts-progressNotification](https://ext.dcloud.net.cn/plugin?name=uts-progressNotification) 插件,如果之前下载过请删除 `uts-progressNotification\utssdk\app-ios` 文件夹)
+## 0.7.5(2023-12-12)
+- 新增 通知栏进度条使用 uts-progressNotification 插件
+- 新增 依赖 uni-installApk、uts-progressNotification。使用前要安装插件三方依赖
+## 0.7.4(2023-11-29)
+- 修复 uni-app-x 项目中由上版引发的无法升级的Bug
+## 0.7.3(2023-11-27)
+- 修复 在 uni-app x 中无更新时报错的Bug
+## 0.7.2(2023-11-20)
+- 新增 插件根目录 utils 文件夹中新增 check-update-nvue.js 文件(vue2 的 nvue 页面请引用该文件)
+## 0.7.1(2023-11-17)
+- 修复 运行至浏览器 ts 语法报错
+## 0.7.0(2023-11-10)
+- 新增 兼容 uni-app x 项目 [详情](https://uniapp.dcloud.net.cn/uniCloud/upgrade-center.html)
+## 0.6.5(2023-10-27)
+- 修复 安装 wgt 报错 manifest.json 文件不存在的Bug
+## 0.6.4(2023-09-01)
+chore: 优化代码结构
+## 0.6.3(2023-08-30)
+- 修复 下载 wgt 时如果后缀名不正确,重命名后安装
+## 0.6.2(2022-11-21)
+- 处理 cloudfunctions 目录
+## 0.6.1(2022-08-17)
+- 修复 后台添加应用市场,但都没有启用的情况下报错的Bug (需要 uni-admin 1.9.3+)
+## 0.6.0(2022-07-19)
+- 新增 支持多应用商店配置(需要 uni-admin 1.9.3+)
+## 0.4.1(2022-05-27)
+- 修复 上版引出的报错问题
+## 0.4.0(2022-05-27)
+- 新增 Android 支持跳转手机自带商店,填写升级包地址时请填写跳转商店链接
+- 新增 改为云对象调用方式,使用更直观
+## 0.3.3(2022-04-14)
+- 修复  调用 check-update,当 code 为 0 时没有回调
+## 0.3.2(2022-01-12)
+- 优化显示逻辑
+## 0.3.1(2021-11-24)
+- 修复 vue3 上图片不显示的Bug
+## 0.3.0(2021-11-18)
+- 移除 wgt 安装成功后提示,防止重启过快弹框不消失
+## 0.2.2(2021-08-25)
+- 兼容vue3.0
+## 0.2.1(2021-07-26)
+- 修复  使用腾讯云并手动填写地址时,导致下载链接失效的bug
+## 0.2.0(2021-07-13)
+- 更新文档  关于报错local_storage_key 为空,请不要将页面路径设置为pages.json中第一项
+## 0.1.9(2021-06-28)
+- 更新文档
+- 修复  wgt安装失败时,按钮状态不对
+## 0.1.8(2021-06-16)
+- 修复  跳转安装时,导致上次下载的apk还没安装就被删掉的bug
+## 0.1.7(2021-06-03)
+- 修改  移除static中的图片
+## 0.1.6(2021-06-03)
+- 修改  下载更新按钮使用CSS渐变色
+## 0.1.5(2021-04-22)
+- 更新check-update函数。现在返回一个Promise,有更新时成功回调,其他情况错误回调
+## 0.1.4(2021-04-13)
+- 更新文档。明确云函数调用结果
+## 0.1.3(2021-04-13)
+- 解耦云函数与弹框处理。utils中新增 call-check-version.js,可用于单独检测是否有更新
+## 0.1.2(2021-04-07)
+- 更新版本对比函数 compare
+## 0.1.1(2021-04-07)
+- 修复 腾讯云空间下载链接不能下载问题
+## 0.1.0(2021-04-07)
+- 新增使用uni.showModal提示升级示例
+- 修改iOS升级提示方式
+## 0.0.7(2021-04-02)
+- 修复在iOS上打开弹框报错
+## 0.0.6(2021-04-01)
+- 兼容旧版本安卓
+## 0.0.5(2021-04-01)
+- 修复低版本安卓上进度条错位
+## 0.0.4(2021-04-01)
+- 更新readme
+- 修复check-update语法错误
+## 0.0.3(2021-04-01)
+- 新增前台更新弹框,详见readme
+- 更新前台检查更新方法
+
+## 0.0.2(2021-03-29)
+- 更新文档
+- 移除 dependencies
+
+## 0.0.1(2021-03-25)
+- 升级中心前台检查更新

+ 122 - 0
src/uni_modules/uni-upgrade-center-app/package.json

@@ -0,0 +1,122 @@
+{
+  "id": "uni-upgrade-center-app",
+  "displayName": "升级中心 uni-upgrade-center - App",
+  "version": "0.9.7",
+  "description": "uni升级中心 - 客户端检查更新",
+  "keywords": [
+    "uniCloud",
+    "update",
+    "升级",
+    "wgt"
+],
+  "repository": "https://gitee.com/dcloud/uni-upgrade-center/tree/master/uni_modules/uni-upgrade-center-app",
+  "engines": {
+    "HBuilderX": "^4.31",
+    "uni-app": "^4.35",
+    "uni-app-x": "^4.35"
+  },
+  "dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "unicloud-template-page",
+    "darkmode": "x",
+    "i18n": "x",
+    "widescreen": "x"
+  },
+  "uni_modules": {
+    "dependencies": [
+      "uts-progressNotification",
+      "uts-openSchema"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "√",
+        "aliyun": "√",
+        "alipay": "√"
+      },
+      "client": {
+        "uni-app": {
+          "vue": {
+            "vue2": "√",
+            "vue3": "√"
+          },
+          "web": {
+            "safari": "-",
+            "chrome": "-"
+          },
+          "app": {
+            "vue": "√",
+            "nvue": {
+                "extVersion": "0.8.3",
+                "minVersion": ""
+            },
+            "android": {
+                "extVersion": "0.8.3",
+                "minVersion": "21"
+            },
+            "ios": {
+                "extVersion": "0.8.3",
+                "minVersion": "12"
+            },
+            "harmony": {
+                "extVersion": "0.9.1",
+                "minVersion": ""
+            }
+          },
+          "mp": {
+            "weixin": "x",
+            "alipay": "x",
+            "toutiao": "x",
+            "baidu": "x",
+            "kuaishou": "x",
+            "jd": "x",
+            "harmony": "x",
+            "qq": "x",
+            "lark": "x"
+          },
+          "quickapp": {
+            "huawei": "x",
+            "union": "x"
+          }
+        },
+        "uni-app-x": {
+          "web": {
+            "safari": "x",
+            "chrome": "x"
+          },
+          "app": {
+            "android": {
+                "extVersion": "0.9.0",
+                "minVersion": "21"
+            },
+            "ios": {
+                "extVersion": "0.9.0",
+                "minVersion": "12"
+            },
+            "harmony": {
+            }
+          },
+          "mp": {
+            "weixin": "x"
+          }
+        }
+      }
+    }
+  }
+}

+ 547 - 0
src/uni_modules/uni-upgrade-center-app/pages/uni-app-x/upgrade-popup.uvue

@@ -0,0 +1,547 @@
+<template>
+  <view class="mask flex-center">
+    <view class="content">
+      <view class="content-top">
+        <text class="content-top-text">{{title}}</text>
+        <image class="content-top-image" mode="widthFix"
+          src="/uni_modules/uni-upgrade-center-app/static/app/bg_top.png"></image>
+      </view>
+
+      <view class="content-space"></view>
+
+      <view class="content-body">
+        <view class="content-body-title">
+          <text class="text title">{{subTitle}}</text>
+          <text class="text version">v{{version}}</text>
+        </view>
+        <view class="body">
+          <scroll-view class="box-des-scroll" scroll-y="true">
+            <text class="text box-des">
+              {{contents}}
+            </text>
+          </scroll-view>
+        </view>
+        <view class="footer flex-center">
+          <template v-if="isiOS || isHarmony">
+            <button class="content-button" style="border: none;color: #fff;" type="primary" plain
+              @click="jumpToAppStore">
+              {{downLoadBtnTextiOS}}
+            </button>
+          </template>
+          <template v-else>
+            <template v-if="!downloadSuccess">
+              <view class="progress-box flex-column" v-if="downloading">
+                <progress class="progress" :percent="downLoadPercent" activeColor="#3DA7FF" :show-info="true"
+                  :stroke-width="10" />
+                <view style="width:100%;display: flex;justify-content: space-around;flex-direction: row;">
+                  <text class="text" style="font-size: 14px;">{{downLoadingText}}</text>
+                  <text class="text" style="font-size: 14px;">({{downloadedSize}}/{{packageFileSize}}M)</text>
+                </view>
+              </view>
+
+              <button v-else class="content-button" @click="updateApp">
+                {{downLoadBtnText}}
+              </button>
+            </template>
+
+            <button v-else-if="downloadSuccess && !installed" class="content-button" :loading="installing"
+              :disabled="installing" @click="installPackage">
+              {{installing ? '正在安装……' : '下载完成,立即安装'}}
+            </button>
+
+            <button v-else-if="installed" class="content-button" @click="installPackage">
+              安装未完成,点击安装
+            </button>
+          </template>
+        </view>
+      </view>
+
+      <view class="content-bottom">
+        <image v-if="!is_mandatory" class="close-img" mode="widthFix"
+          src="/uni_modules/uni-upgrade-center-app/static/app/app_update_close.png" @click="closeUpdate">
+        </image>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup lang="uts">
+  import { openSchema as utsOpenSchema } from '@/uni_modules/uts-openSchema'
+  import { UniUpgradeCenterResult, StoreListItem } from '../../utils/call-check-version'
+  import { platform_iOS, platform_Android, platform_Harmony } from '../../utils/utils'
+  // #ifdef APP-ANDROID
+  import { createNotificationProgress, cancelNotificationProgress, finishNotificationProgress } from '@/uni_modules/uts-progressNotification'
+  import { type CreateNotificationProgressOptions, type FinishNotificationProgressOptions } from '@/uni_modules/uts-progressNotification/utssdk/interface.uts'
+  // #endif
+
+  const requiredKey = ['version', 'url', 'type']
+  let downloadTask : DownloadTask | null = null;
+  let openSchemePromise : Promise<boolean> | null = null;
+
+  const openSchema = (url : string) : Promise<boolean> => new Promise<boolean>((resolve, reject) => {
+    try {
+      utsOpenSchema(url)
+      resolve(true)
+    } catch (e) {
+      reject(false)
+    }
+  })
+
+  // 从之前下载安装
+  const installForBeforeFilePath = ref<string>('')
+
+  // 安装
+  const installed = ref<boolean>(false)
+  const installing = ref<boolean>(false)
+
+  // 下载
+  const downloadSuccess = ref<boolean>(false)
+  const downloading = ref<boolean>(false)
+
+  const downLoadPercent = ref<number>(0)
+  const downloadedSize = ref<number>(0)
+  const packageFileSize = ref<number>(0)
+
+  // 要安装的本地包地址
+  const tempFilePath = ref<string>('')
+
+  // 默认安装包信息
+  const title = ref<string>('更新日志')
+  const contents = ref<string>('')
+  const version = ref<string>('')
+  const is_mandatory = ref<boolean>(false)
+  const url = ref<string>("")
+  const platform = ref<string[]>([])
+  const store_list = ref<StoreListItem[] | null>(null)
+
+  // 可自定义属性
+  const subTitle = ref<string>('发现新版本')
+  const downLoadBtnTextiOS = ref<string>('立即跳转更新')
+  const downLoadBtnText = ref<string>('立即下载更新')
+  const downLoadingText = ref<string>('安装包下载中,请稍后')
+
+  const isiOS = computed(() : boolean => platform.value.includes(platform_iOS))
+  const isHarmony = computed(() : boolean => platform.value.includes(platform_Harmony))
+  const isAndroid = computed(() : boolean => platform.value.includes(platform_Android))
+  const needNotificationProgress = computed(() : boolean => isAndroid.value && !is_mandatory.value)
+
+  function getCurrentDialogPage() : UniPage | null {
+    const pages = getCurrentPages()
+    if (pages.length > 0) {
+      const dialogPages = pages[pages.length - 1].getDialogPages()
+      if (dialogPages.length > 0) {
+        return dialogPages[dialogPages.length - 1]
+      }
+    }
+    return null
+  }
+
+  function closePopup() {
+    downloadSuccess.value = false
+    downloading.value = false
+    downLoadPercent.value = 0
+    downloadedSize.value = 0
+    packageFileSize.value = 0
+    tempFilePath.value = ''
+
+    installing.value = false
+    installed.value = false
+
+    uni.closeDialogPage({
+      dialogPage: getCurrentDialogPage(),
+      fail(e) {
+        console.log('e: ', e);
+      }
+    })
+  }
+
+  function askAbortDownload() {
+    uni.showModal({
+      title: '是否取消下载?',
+      cancelText: '否',
+      confirmText: '是',
+      success: res => {
+        if (res.confirm) {
+          if (downloadTask !== null) downloadTask!.abort()
+          if (needNotificationProgress.value) {
+            // #ifdef APP-ANDROID
+            cancelNotificationProgress();
+            // #endif
+          }
+          closePopup()
+        }
+      }
+    });
+  }
+
+  function closeUpdate() {
+    if (downloading.value && !needNotificationProgress.value) {
+      askAbortDownload()
+      return;
+    }
+    closePopup()
+  }
+
+  function jumpToAppStore() {
+    openSchema(url.value)
+  }
+
+  function show(localPackageInfo : UniUpgradeCenterResult | null) {
+    if (localPackageInfo === null) return;
+    for (let key in localPackageInfo) {
+      if (requiredKey.indexOf(key) != -1 && localPackageInfo[key] === null) {
+        console.error(`参数 ${key} 必填,请检查后重试`)
+        closePopup()
+        return;
+      }
+    }
+    title.value = localPackageInfo.title
+    url.value = localPackageInfo.url
+    contents.value = localPackageInfo.contents
+    is_mandatory.value = localPackageInfo.is_mandatory
+    platform.value = localPackageInfo.platform
+    version.value = localPackageInfo.version
+    store_list.value = localPackageInfo.store_list
+  }
+
+  function checkStoreScheme() : Promise<boolean> | null {
+    if (store_list.value !== null) {
+      const storeList : StoreListItem[] = store_list.value!.filter((item : StoreListItem) : boolean => item.enable)
+      if (storeList.length > 0) {
+        if (openSchemePromise === null) {
+          openSchemePromise = Promise.reject() as Promise<boolean>
+        }
+        storeList
+          .sort((cur : StoreListItem, next : StoreListItem) : number => next.priority - cur.priority)
+          .map((item : StoreListItem) : string => item.scheme)
+          .reduce((promise : Promise<boolean>, cur : string) : Promise<boolean> => {
+            openSchemePromise = promise.catch<boolean>(() : Promise<boolean> => openSchema(cur))
+            return openSchemePromise!
+          }, openSchemePromise!)
+        return openSchemePromise!
+      }
+    }
+    return null
+  }
+
+  function installPackage() {
+    installing.value = true;
+    // #ifdef APP
+    uni.installApk({
+      filePath: tempFilePath.value,
+      success: _ => {
+        installing.value = false;
+        installed.value = true;
+      },
+      fail: err => {
+        console.error('installApk fail', err);
+        // 安装失败需要重新下载安装包
+        installing.value = false;
+        installed.value = false;
+        uni.showModal({
+          title: '更新失败,请重新下载',
+          content: `uni.installApk 错误码 ${err.errCode}`,
+          showCancel: false
+        });
+      }
+    });
+    // 安装跳出覆盖安装,此处直接返回上一页
+    if (!is_mandatory.value) {
+      uni.navigateBack()
+    }
+    // #endif
+  }
+
+  function downloadFail() {
+    const errMsg = '下载失败,请点击重试'
+    downloadSuccess.value = false;
+    downloading.value = false;
+    downLoadPercent.value = 0;
+    downloadedSize.value = 0;
+    packageFileSize.value = 0;
+    downLoadBtnText.value = errMsg
+    downloadTask = null;
+    if (needNotificationProgress.value) {
+      // #ifdef APP-ANDROID
+      finishNotificationProgress({
+        title: '升级包下载失败',
+        content: '请重新检查更新',
+        onClick() { }
+      } as FinishNotificationProgressOptions);
+      // #endif
+    }
+  }
+
+  function downLoadComplete() {
+    downloadSuccess.value = true;
+    downloading.value = false;
+    downLoadPercent.value = 0
+    downloadedSize.value = 0
+    packageFileSize.value = 0
+    downloadTask = null;
+    if (needNotificationProgress.value) {
+      // #ifdef APP-ANDROID
+      finishNotificationProgress({
+        title: "安装升级包",
+        content: "下载完成",
+        onClick() { }
+      } as FinishNotificationProgressOptions)
+      installPackage();
+      // #endif
+      return
+    }
+    // 强制更新,直接安装
+    if (is_mandatory.value) {
+      installPackage();
+    }
+  }
+
+  function downloadPackage() {
+    //下载包
+    downloadTask = uni.downloadFile({
+      url: url.value,
+      success: res => {
+        if (res.statusCode == 200) {
+          tempFilePath.value = res.tempFilePath
+          downLoadComplete()
+        } else {
+          console.log('downloadFile err: ', res);
+          downloadFail()
+        }
+      },
+      fail: err => {
+        console.log('downloadFile err: ', err);
+        downloadFail()
+      }
+    });
+    if (downloadTask !== null) {
+      downloading.value = true;
+      if (needNotificationProgress.value) {
+        closePopup()
+      }
+      downloadTask!.onProgressUpdate(res => {
+        downLoadPercent.value = parseFloat(res.progress.toFixed(0));
+        downloadedSize.value = parseFloat((res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2));
+        packageFileSize.value = parseFloat((res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2));
+        if (needNotificationProgress.value) {
+          // #ifdef APP-ANDROID
+          createNotificationProgress({
+            title: "升级中心正在下载安装包……",
+            content: `${downLoadPercent.value}%`,
+            progress: downLoadPercent.value,
+            onClick: () => {
+              if (!downloadSuccess.value) {
+                askAbortDownload()
+              }
+            }
+          } as CreateNotificationProgressOptions)
+          // #endif
+        }
+      });
+    }
+  }
+
+  function updateApp() {
+    const checkStoreSchemeResult = checkStoreScheme()
+    if (checkStoreSchemeResult !== null) {
+      checkStoreSchemeResult
+        .then(_ => { })
+        .catch(() => { downloadPackage() })
+        .finally(() => {
+          openSchemePromise = null
+        })
+    } else { downloadPackage() }
+  }
+
+  onUnload(() => {
+    if (needNotificationProgress.value) {
+      // #ifdef APP-ANDROID
+      cancelNotificationProgress()
+      // #endif
+    }
+  })
+
+  onLoad((onLoadOptions : OnLoadOptions) => {
+    const local_storage_key : string | null = onLoadOptions['local_storage_key']
+    if (local_storage_key == null) {
+      console.error('local_storage_key为空,请检查后重试')
+      closePopup()
+      return;
+    };
+    const localPackageInfo = uni.getStorageSync(local_storage_key);
+    if (localPackageInfo == null) {
+      console.error('安装包信息为空,请检查后重试')
+      closePopup()
+      return;
+    };
+    show(JSON.parse<UniUpgradeCenterResult>(JSON.stringify(localPackageInfo)) as UniUpgradeCenterResult)
+  })
+
+  onBackPress((options : OnBackPressOptions) : boolean | null => {
+    if (is_mandatory.value) return true
+    if (!needNotificationProgress.value) {
+      if (downloadTask !== null) {
+        downloadTask!.abort()
+      }
+    }
+    return false
+  })
+</script>
+
+<style>
+  .flex-center {
+    /* #ifndef APP-NVUE | UNI-APP-X */
+    display: flex;
+    /* #endif */
+    justify-content: center;
+    align-items: center;
+  }
+
+  .mask {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, .65);
+  }
+
+  .content {
+    position: relative;
+    top: 0;
+    width: 600rpx;
+    background-color: transparent;
+  }
+
+  .text {
+    font-family: Source Han Sans CN;
+  }
+
+  .content-top {
+    width: 100%;
+    border-bottom-color: #fff;
+    border-bottom-width: 15px;
+    border-bottom-style: solid;
+  }
+
+  .content-space {
+    width: 100%;
+    height: 120px;
+    background-color: #fff;
+    position: absolute;
+    top: 30%;
+    z-index: -1;
+  }
+
+  .content-top-image {
+    width: 100%;
+    position: relative;
+    bottom: -10%;
+  }
+
+  .content-top-text {
+    font-size: 22px;
+    font-weight: bold;
+    color: #F8F8FA;
+    position: absolute;
+    width: 65%;
+    top: 50%;
+    left: 25px;
+    z-index: 1;
+  }
+
+  .content-body {
+    box-sizing: border-box;
+    padding: 0 25px;
+    width: 100%;
+    background-color: #fff;
+    border-bottom-left-radius: 15px;
+    border-bottom-right-radius: 15px;
+  }
+
+  .content-body-title {
+    flex-direction: row;
+    align-items: center;
+  }
+
+  .content-body-title .version {
+    padding-left: 10px;
+    color: #fff;
+    font-size: 10px;
+    margin-left: 5px;
+    padding: 2px 4px;
+    border-radius: 10px;
+    background: #50aefd;
+  }
+
+  .title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #3DA7FF;
+    line-height: 38px;
+  }
+
+  .footer {
+    height: 75px;
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+  }
+
+  .box-des-scroll {
+    box-sizing: border-box;
+    padding: 0 15px;
+    height: 100px;
+  }
+
+  .box-des {
+    font-size: 13px;
+    color: #000000;
+    line-height: 25px;
+  }
+
+  .progress-box {
+    width: 100%;
+  }
+
+  .progress {
+    width: 90%;
+    height: 20px;
+  }
+
+  .content-bottom {
+    height: 75px;
+  }
+
+  .close-img {
+    width: 35px;
+    height: 35px;
+    z-index: 1000;
+    position: relative;
+    bottom: -30%;
+    left: 50%;
+    margin-left: -17px;
+  }
+
+  .content-button {
+    width: 100%;
+    height: 40px;
+    line-height: 40px;
+
+    font-size: 15px;
+    font-weight: 400;
+    border-radius: 20px;
+    border: none;
+    color: #fff;
+
+    text-align: center;
+
+    background-color: #1785ff;
+  }
+
+  .flex-column {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
+</style>

+ 677 - 0
src/uni_modules/uni-upgrade-center-app/pages/upgrade-popup.vue

@@ -0,0 +1,677 @@
+<template>
+	<view class="mask flex-center" v-if="shown">
+		<view class="content botton-radius">
+			<view class="content-top">
+				<text class="content-top-text">{{ title }}</text>
+				<image class="content-top" style="top: 0" width="100%" height="100%" src="/uni_modules/uni-upgrade-center-app/static/app/bg_top.png"></image>
+			</view>
+			<view class="content-header"></view>
+			<view class="content-body">
+				<view class="title">
+					<text>{{ subTitle }}</text>
+					<text class="content-body-version">{{ version }}</text>
+				</view>
+				<view class="body">
+					<scroll-view class="box-des-scroll" scroll-y="true">
+						<text class="box-des">
+							{{ contents }}
+						</text>
+					</scroll-view>
+				</view>
+				<view class="footer flex-center">
+					<template v-if="isApplicationStore">
+						<button class="content-button" style="border: none; color: #fff" plain @click="jumpToApplicationStore">
+							{{ downLoadBtnTextiOS }}
+						</button>
+					</template>
+					<template v-else>
+						<template v-if="!downloadSuccess">
+							<view class="progress-box flex-column" v-if="downloading">
+								<progress class="progress" :percent="downLoadPercent" activeColor="#3DA7FF" show-info stroke-width="10" />
+								<view style="width: 100%; font-size: 28rpx; display: flex; justify-content: space-around">
+									<text>{{ downLoadingText }}</text>
+									<text>({{ downloadedSize }}/{{ packageFileSize }}M)</text>
+								</view>
+							</view>
+
+							<button v-else class="content-button" style="border: none; color: #fff" plain @click="updateApp">
+								{{ downLoadBtnText }}
+							</button>
+						</template>
+						<button
+							v-else-if="downloadSuccess && !installed"
+							class="content-button"
+							style="border: none; color: #fff"
+							plain
+							:loading="installing"
+							:disabled="installing"
+							@click="installPackage"
+						>
+							{{ installing ? '正在安装……' : '下载完成,立即安装' }}
+						</button>
+						<button
+							v-else-if="installed && !isWGT"
+							class="content-button"
+							style="border: none; color: #fff"
+							plain
+							:loading="installing"
+							:disabled="installing"
+							@click="installPackage"
+						>
+							安装未完成,点击安装
+						</button>
+
+						<button v-else-if="installed && isWGT" class="content-button" style="border: none; color: #fff" plain @click="restart">安装完毕,点击重启</button>
+					</template>
+				</view>
+			</view>
+
+			<image v-if="!is_mandatory" class="close-img" src="/uni_modules/uni-upgrade-center-app/static/app/app_update_close.png" @click.stop="closeUpdate"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+// #ifdef APP-PLUS
+import { createNotificationProgress, cancelNotificationProgress, finishNotificationProgress } from '@/uni_modules/uts-progressNotification';
+// #endif
+import { compare, platform_iOS, platform_Android, platform_Harmony } from '../utils/utils'
+const localFilePathKey = 'UNI_ADMIN_UPGRADE_CENTER_LOCAL_FILE_PATH';
+
+let downloadTask = null;
+let openSchemePromise;
+
+export default {
+    emits: ['close', 'show'],
+	data() {
+		return {
+			// 从之前下载安装
+			installForBeforeFilePath: '',
+
+			// 安装
+			installed: false,
+			installing: false,
+
+			// 下载
+			downloadSuccess: false,
+			downloading: false,
+
+			downLoadPercent: 0,
+			downloadedSize: 0,
+			packageFileSize: 0,
+
+			tempFilePath: '', // 要安装的本地包地址
+
+			// 默认安装包信息
+			title: '更新日志',
+			contents: '',
+			version: '',
+			is_mandatory: false,
+			url: '',
+			platform: [],
+			store_list: null,
+
+			// 可自定义属性
+			subTitle: '发现新版本',
+			downLoadBtnTextiOS: '立即跳转更新',
+			downLoadBtnText: '立即下载更新',
+			downLoadingText: '安装包下载中,请稍后',
+
+			// #ifdef APP-PLUS
+			shown: true,
+			// #endif
+			// #ifdef APP-HARMONY
+			shown: false,
+			// #endif
+		};
+	},
+	onLoad({ local_storage_key }) {
+		if (!local_storage_key) {
+			console.error('local_storage_key为空,请检查后重试');
+			uni.navigateBack();
+			return;
+		}
+
+		const localPackageInfo = uni.getStorageSync(local_storage_key);
+		if (!localPackageInfo) {
+			console.error('安装包信息为空,请检查后重试');
+			uni.navigateBack();
+			return;
+		}
+
+		this.setLocalPackageInfo(localPackageInfo)
+	},
+	onBackPress() {
+		// 强制更新不允许返回
+		if (this.is_mandatory) return true;
+		if (!this.needNotificationProgress) downloadTask && downloadTask.abort();
+	},
+	onHide() {
+		openSchemePromise = null;
+	},
+	computed: {
+		isWGT() {
+			return this.type === 'wgt';
+		},
+		isNativeApp() {
+			return this.type === 'native_app';
+		},
+		isiOS() {
+			return this.platform.indexOf(platform_iOS) !== -1;
+		},
+		isAndroid() {
+			return this.platform.indexOf(platform_Android) !== -1;
+		},
+		isHarmony() {
+			return this.platform.indexOf(platform_Harmony) !== -1;
+		},
+		isApplicationStore() {
+			return !this.isWGT && this.isNativeApp && (
+				this.isiOS ||
+				this.isHarmony
+			)
+			// return this.isiOS || (!this.isiOS && !this.isWGT && this.url.indexOf('.apk') === -1);
+		},
+		needNotificationProgress() {
+			return this.platform.indexOf(platform_iOS) === -1 && !this.is_mandatory && !this.isHarmony;
+		}
+	},
+	methods: {
+		show(shown, localPackageInfo) {
+			// #ifdef APP-HARMONY
+			this.$emit('show')
+			if (localPackageInfo) {
+				this.shown = shown
+				this.setLocalPackageInfo(localPackageInfo)
+			} else {
+				console.error(`安装包信息为空,请检查后重试`);
+			}
+			// #endif
+		},
+		setLocalPackageInfo(localPackageInfo) {
+			const requiredKey = ['version', 'url', 'type'];
+			for (let key in localPackageInfo) {
+				if (requiredKey.indexOf(key) !== -1 && !localPackageInfo[key]) {
+					console.error(`参数 ${key} 必填,请检查后重试`);
+					// #ifdef APP-PLUS
+					uni.navigateBack();
+					// #endif
+					// #ifdef APP-HARMONY
+					this.shown = false
+					// #endif
+					return;
+				}
+			}
+
+			Object.assign(this, localPackageInfo);
+			this.checkLocalStoragePackage();
+		},
+		checkLocalStoragePackage() {
+			// 如果已经有下载好的包,则直接提示安装
+			const localFilePathRecord = uni.getStorageSync(localFilePathKey);
+			if (localFilePathRecord) {
+				const { version, savedFilePath, installed } = localFilePathRecord;
+
+				// 比对版本
+				if (!installed && compare(version, this.version) === 0) {
+					this.downloadSuccess = true;
+					this.installForBeforeFilePath = savedFilePath;
+					this.tempFilePath = savedFilePath;
+				} else {
+					// 如果保存的包版本小 或 已安装过,则直接删除
+					this.deleteSavedFile(savedFilePath);
+				}
+			}
+		},
+		askAbortDownload() {
+			uni.showModal({
+				title: '是否取消下载?',
+				cancelText: '否',
+				confirmText: '是',
+				success: (res) => {
+					if (res.confirm) {
+						downloadTask && downloadTask.abort();
+            if (this.needNotificationProgress) {
+              cancelNotificationProgress();
+            }
+						uni.navigateBack();
+					}
+				}
+			});
+		},
+		async closeUpdate() {
+			if (this.downloading) {
+				if (this.is_mandatory) {
+					return uni.showToast({
+						title: '下载中,请稍后……',
+						icon: 'none',
+						duration: 500
+					});
+				}
+				if (!this.needNotificationProgress) {
+					this.askAbortDownload();
+					return;
+				}
+			}
+
+			if (!this.needNotificationProgress && this.downloadSuccess && this.tempFilePath) {
+				// 包已经下载完毕,稍后安装,将包保存在本地
+				await this.saveFile(this.tempFilePath, this.version);
+			}
+
+			// #ifdef APP-PLUS
+			uni.navigateBack();
+			// #endif
+			// #ifdef APP-HARMONY
+			this.shown = false
+			this.$emit('close')
+			// #endif
+		},
+		updateApp() {
+			this.checkStoreScheme()
+				.catch(() => {
+					this.downloadPackage();
+				})
+				.finally(() => {
+					openSchemePromise = null;
+				});
+		},
+		// 跳转应用商店
+		checkStoreScheme() {
+			const storeList = (this.store_list || []).filter((item) => item.enable);
+			if (storeList && storeList.length) {
+				storeList
+					.sort((cur, next) => next.priority - cur.priority)
+					.map((item) => item.scheme)
+					.reduce((promise, cur, curIndex) => {
+						openSchemePromise = (promise || (promise = Promise.reject())).catch(() => {
+							return new Promise((resolve, reject) => {
+								plus.runtime.openURL(cur, (err) => {
+									reject(err);
+								});
+							});
+						});
+						return openSchemePromise;
+					}, openSchemePromise);
+				return openSchemePromise;
+			}
+
+			return Promise.reject();
+		},
+		downloadPackage() {
+			this.downloading = true;
+			//下载包
+			downloadTask = uni.downloadFile({
+				url: this.url,
+				success: (res) => {
+					if (res.statusCode == 200) {
+						// fix: wgt 文件下载完成后后缀不是 wgt
+						if (this.isWGT && res.tempFilePath.split('.').slice(-1)[0] !== 'wgt') {
+							const failCallback = (e) => {
+								console.log('[FILE RENAME FAIL]:', JSON.stringify(e));
+							};
+							// #ifndef APP-HARMONY
+							plus.io.resolveLocalFileSystemURL(
+								res.tempFilePath,
+								(entry) => {
+									entry.getParent((parent) => {
+										const newName = `new_wgt_${Date.now()}.wgt`;
+										entry.copyTo(
+											parent,
+											newName,
+											(res) => {
+												this.tempFilePath = res.fullPath;
+												this.downLoadComplete();
+											},
+											failCallback
+										);
+									}, failCallback);
+								},
+								failCallback
+							);
+							// #endif
+							// #ifdef APP-HARMONY
+							failCallback({code: -1, message: 'Download content error, is not wgt.'})
+							// #endif
+						} else {
+							this.tempFilePath = res.tempFilePath;
+							this.downLoadComplete();
+						}
+					} else {
+						console.log('下载错误:' + JSON.stringify(res))
+            this.downloadFail()
+					}
+				},
+        fail: (err) => {
+          console.log('下载错误:' + JSON.stringify(err))
+          this.downloadFail()
+        }
+			});
+
+			downloadTask.onProgressUpdate((res) => {
+				this.downLoadPercent = res.progress;
+				this.downloadedSize = (res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2);
+				this.packageFileSize = (res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2);
+
+				if (this.needNotificationProgress && !this.downloadSuccess) {
+					createNotificationProgress({
+						title: '升级中心正在下载安装包……',
+						content: `${this.downLoadPercent}%`,
+						progress: this.downLoadPercent,
+						onClick: () => {
+							this.askAbortDownload();
+						}
+					});
+				}
+			});
+			if (this.needNotificationProgress) {
+				uni.navigateBack();
+			}
+		},
+    downloadFail() {
+      const errMsg = '下载失败,请点击重试'
+
+      this.downloadSuccess = false;
+      this.downloading = false;
+
+      this.downLoadPercent = 0;
+      this.downloadedSize = 0;
+      this.packageFileSize = 0;
+
+      this.downLoadBtnText = errMsg
+
+      downloadTask = null;
+
+      if (this.needNotificationProgress) {
+        finishNotificationProgress({
+          title: '升级包下载失败',
+          content: '请重新检查更新'
+        });
+      }
+    },
+		downLoadComplete() {
+			this.downloadSuccess = true;
+			this.downloading = false;
+
+			this.downLoadPercent = 0;
+			this.downloadedSize = 0;
+			this.packageFileSize = 0;
+
+			downloadTask = null;
+
+			if (this.needNotificationProgress) {
+				finishNotificationProgress({
+					title: '安装升级包',
+					content: '下载完成'
+				});
+
+				this.installPackage();
+				return;
+			}
+
+			// 强制更新,直接安装
+			if (this.is_mandatory) {
+				this.installPackage();
+			}
+		},
+		installPackage() {
+			// #ifdef APP-PLUS || APP-HARMONY
+			// wgt资源包安装
+			if (this.isWGT) {
+				this.installing = true;
+			}
+			plus.runtime.install(
+				this.tempFilePath,
+				{
+					force: false
+				},
+				async (res) => {
+					this.installing = false;
+					this.installed = true;
+
+					// wgt包,安装后会提示 安装成功,是否重启
+					if (this.isWGT) {
+						// 强制更新安装完成重启
+						if (this.is_mandatory) {
+							// #ifdef APP-PLUS
+							uni.showLoading({
+								icon: 'none',
+								title: '安装成功,正在重启……'
+							});
+							// #endif
+
+							setTimeout(() => {
+								// #ifdef APP-PLUS
+								uni.hideLoading();
+								// #endif
+								this.restart();
+							}, 1000);
+						}
+					} else {
+						const localFilePathRecord = uni.getStorageSync(localFilePathKey);
+						uni.setStorageSync(localFilePathKey, {
+							...localFilePathRecord,
+							installed: true
+						});
+					}
+				},
+				async (err) => {
+					// 如果是安装之前的包,安装失败后删除之前的包
+					if (this.installForBeforeFilePath) {
+						await this.deleteSavedFile(this.installForBeforeFilePath);
+						this.installForBeforeFilePath = '';
+					}
+
+					// 安装失败需要重新下载安装包
+					this.installing = false;
+					this.installed = false;
+
+					uni.showModal({
+						title: '更新失败,请重新下载',
+						content: err.message,
+						showCancel: false
+					});
+				}
+			);
+
+			// 非wgt包,安装跳出覆盖安装,此处直接返回上一页
+			if (!this.isWGT && !this.is_mandatory) {
+				uni.navigateBack();
+			}
+			// #endif
+		},
+		restart() {
+			this.installed = false;
+			// #ifdef APP-HARMONY
+			uni.showModal({
+				title: '更新完毕',
+				content: '请手动重启',
+				showCancel: false,
+				success(res) {
+					plus.runtime.quit()
+				}
+			})
+			// #endif
+			// #ifdef APP-PLUS
+			//更新完重启app
+			plus.runtime.restart();
+			// #endif
+		},
+		saveFile(tempFilePath, version) {
+			return new Promise((resolve, reject) => {
+				uni.saveFile({
+					tempFilePath,
+					success({ savedFilePath }) {
+						uni.setStorageSync(localFilePathKey, {
+							version,
+							savedFilePath
+						});
+					},
+					complete() {
+						resolve();
+					}
+				});
+			});
+		},
+		deleteSavedFile(filePath) {
+			uni.removeStorageSync(localFilePathKey);
+			return uni.removeSavedFile({
+				filePath
+			});
+		},
+		jumpToApplicationStore() {
+			plus.runtime.openURL(this.url);
+		}
+	}
+};
+</script>
+
+<style>
+page {
+	background: transparent;
+}
+
+.flex-center {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	justify-content: center;
+	align-items: center;
+}
+
+.mask {
+	position: fixed;
+	left: 0;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	background-color: rgba(0, 0, 0, 0.65);
+}
+
+.botton-radius {
+	border-bottom-left-radius: 30rpx;
+	border-bottom-right-radius: 30rpx;
+}
+
+.content {
+	position: relative;
+	top: 0;
+	width: 600rpx;
+	background-color: #fff;
+	box-sizing: border-box;
+	padding: 0 50rpx;
+	font-family: Source Han Sans CN;
+}
+
+.text {
+	/* #ifndef APP-NVUE */
+	display: block;
+	/* #endif */
+	line-height: 200px;
+	text-align: center;
+	color: #ffffff;
+}
+
+.content-top {
+	position: absolute;
+	top: -195rpx;
+	left: 0;
+	width: 600rpx;
+	height: 270rpx;
+}
+
+.content-top-text {
+	font-size: 45rpx;
+	font-weight: bold;
+	color: #f8f8fa;
+	position: absolute;
+	top: 120rpx;
+	left: 50rpx;
+	z-index: 1;
+}
+
+.content-header {
+	height: 70rpx;
+}
+
+.title {
+	font-size: 33rpx;
+	font-weight: bold;
+	color: #3da7ff;
+	line-height: 38px;
+}
+
+.content-body {
+  width: 100%;
+}
+
+.content-body-version {
+	padding-left: 20rpx;
+	color: #fff;
+	font-size: 20rpx;
+	margin-left: 10rpx;
+	padding: 4rpx 8rpx;
+	border-radius: 20rpx;
+	background: #50aefd;
+}
+
+.footer {
+	height: 150rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-around;
+}
+
+.box-des-scroll {
+	box-sizing: border-box;
+	padding: 0 40rpx;
+	height: 200rpx;
+	text-align: left;
+}
+
+.box-des {
+	font-size: 26rpx;
+	color: #000000;
+	line-height: 50rpx;
+}
+
+.progress-box {
+	width: 100%;
+}
+
+.progress {
+	width: 90%;
+	height: 40rpx;
+	/* border-radius: 35px; */
+}
+
+.close-img {
+	width: 70rpx;
+	height: 70rpx;
+	z-index: 1000;
+	position: absolute;
+	bottom: -120rpx;
+	left: calc(50% - 70rpx / 2);
+}
+
+.content-button {
+	text-align: center;
+	flex: 1;
+	font-size: 30rpx;
+	font-weight: 400;
+	color: #ffffff;
+	border-radius: 40rpx;
+	margin: 0 18rpx;
+
+	height: 80rpx;
+	line-height: 80rpx;
+
+	background: linear-gradient(to right, #1785ff, #3da7ff);
+}
+
+.flex-column {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+}
+</style>

+ 1 - 0
src/uni_modules/uni-upgrade-center-app/readme.md

@@ -0,0 +1 @@
+文档已移至 [uni-upgrade-center](https://uniapp.dcloud.net.cn/uniCloud/upgrade-center.html)

BIN
src/uni_modules/uni-upgrade-center-app/static/app/app_update_close.png


BIN
src/uni_modules/uni-upgrade-center-app/static/app/bg_top.png


+ 1 - 0
src/uni_modules/uni-upgrade-center-app/uniCloud/database/db_init.json

@@ -0,0 +1 @@
+{}

+ 120 - 0
src/uni_modules/uni-upgrade-center-app/utils/call-check-version.ts

@@ -0,0 +1,120 @@
+export type StoreListItem = {
+	enable : boolean
+	id : string
+	name : string
+	scheme : string
+	priority : number // 优先级
+}
+
+export type UniUpgradeCenterResult = {
+	_id : string
+	appid : string
+	name : string
+	title : string
+	contents : string
+	url : string // 安装包下载地址
+	platform : Array<string> // Array<'Android' | 'iOS' | 'Harmony'>
+	version : string // 版本号 1.0.0
+	uni_platform : string // "android" | "ios" | 'harmony'
+	stable_publish : boolean // 是否是稳定版
+	is_mandatory : boolean // 是否强制更新
+	is_silently : boolean | null	// 是否静默更新
+	create_env : string // "upgrade-center"
+	create_date : number
+	message : string
+	code : number
+
+	type : string // "native_app" | "wgt"
+	store_list : StoreListItem[] | null
+	min_uni_version : string | null  // 升级 wgt 的最低 uni-app 版本
+}
+
+export default function () : Promise<UniUpgradeCenterResult> {
+	// #ifdef APP
+	return new Promise<UniUpgradeCenterResult>((resolve, reject) => {
+		const systemInfo = uni.getSystemInfoSync()
+		const appId = systemInfo.appId
+		const appVersion = systemInfo.appVersion //systemInfo.appVersion
+		// #ifndef UNI-APP-X
+		if (typeof appId === 'string' && typeof appVersion === 'string' && appId.length > 0 && appVersion.length > 0) {
+			plus.runtime.getProperty(appId, function (widgetInfo) {
+				if (widgetInfo.version) {
+					let data = {
+						action: 'checkVersion',
+						appid: appId,
+						appVersion: appVersion,
+						wgtVersion: widgetInfo.version
+					}
+					uniCloud.callFunction({
+						name: 'uni-upgrade-center',
+						data,
+						success: (e) => {
+							resolve(e.result as UniUpgradeCenterResult)
+						},
+						fail: (error) => {
+							reject(error)
+						}
+					})
+				} else {
+					reject('widgetInfo.version is EMPTY')
+				}
+			})
+		} else {
+			reject('plus.runtime.appid is EMPTY')
+		}
+		// #endif
+		// #ifdef UNI-APP-X
+		if (typeof appId === 'string' && typeof appVersion === 'string' && appId.length > 0 && appVersion.length > 0) {
+			let data = {
+				action: 'checkVersion',
+				appid: appId,
+				appVersion: appVersion,
+				is_uniapp_x: true,
+				wgtVersion: '0.0.0.0.0.1'
+			}
+			try {
+				uniCloud.callFunction({
+					name: 'uni-upgrade-center',
+					data: data
+				}).then(res => {
+					const code = res.result['code']
+					const codeIsNumber = ['Int', 'Long', 'number'].includes(typeof code)
+					if (codeIsNumber) {
+					  if ((code as number) == 0) {
+					    reject({
+					      code: res.result['code'],
+					      message: res.result['message']
+					    })
+					  } else if ((code as number) < 0) {
+					    reject({
+					      code: res.result['code'],
+					      message: res.result['message']
+					    })
+					  } else {
+              const result = JSON.parse<UniUpgradeCenterResult>(JSON.stringify(res.result)) as UniUpgradeCenterResult
+              resolve(result)
+            }
+					}
+				}).catch<void>((err : any | null) => {
+					const error = err as UniCloudError
+					if (error.errMsg == '未匹配到云函数[uni-upgrade-center]')
+						error.errMsg = '【uni-upgrade-center-app】未配置uni-upgrade-center,无法升级。参考: https://uniapp.dcloud.net.cn/uniCloud/upgrade-center.html'
+					reject(error.errMsg)
+				})
+			} catch (e) {
+				reject(e.message)
+			}
+		} else {
+			reject('invalid appid or appVersion')
+		}
+		// #endif
+	})
+	// #endif
+	// #ifndef APP
+	return new Promise((resolve, reject) => {
+		reject({
+			message: '请在App中使用'
+		})
+	})
+	// #endif
+}

+ 184 - 0
src/uni_modules/uni-upgrade-center-app/utils/check-update-nvue.js

@@ -0,0 +1,184 @@
+function callCheckVersion() {
+	// #ifdef APP-PLUS
+	return new Promise((resolve, reject) => {
+		plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {
+			let data = {
+				action: 'checkVersion',
+				appid: plus.runtime.appid,
+				appVersion: plus.runtime.version,
+				wgtVersion: widgetInfo.version
+			}
+			uniCloud.callFunction({
+				name: 'uni-upgrade-center',
+				data,
+				success: (e) => {
+					resolve(e)
+				},
+				fail: (error) => {
+					reject(error)
+				}
+			})
+		})
+	})
+	// #endif
+	// #ifndef APP-PLUS
+	return new Promise((resolve, reject) => {})
+	// #endif
+}
+
+// 推荐再App.vue中使用
+const PACKAGE_INFO_KEY = '__package_info__'
+
+export default function() {
+	// #ifdef APP-PLUS
+	return new Promise((resolve, reject) => {
+		callCheckVersion().then(async (e) => {
+			if (!e.result) return;
+			const {
+				code,
+				message,
+				is_silently, // 是否静默更新
+				url, // 安装包下载地址
+				platform, // 安装包平台
+				type // 安装包类型
+			} = e.result;
+
+			// 此处逻辑仅为实例,可自行编写
+			if (code > 0) {
+				// 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回
+				const {
+					fileList
+				} = await uniCloud.getTempFileURL({
+					fileList: [url]
+				});
+				if (fileList[0].tempFileURL)
+					e.result.url = fileList[0].tempFileURL;
+
+				resolve(e)
+
+				// 静默更新,只有wgt有
+				if (is_silently) {
+					uni.downloadFile({
+						url: e.result.url,
+						success: res => {
+							if (res.statusCode == 200) {
+								// 下载好直接安装,下次启动生效
+								plus.runtime.install(res.tempFilePath, {
+									force: false
+								});
+							}
+						}
+					});
+					return;
+				}
+
+				/**
+				 * 提示升级一
+				 * 使用 uni.showModal
+				 */
+				// return updateUseModal(e.result)
+
+				/**
+				 * 提示升级二
+				 * 官方适配的升级弹窗,可自行替换资源适配UI风格
+				 */
+				uni.setStorageSync(PACKAGE_INFO_KEY, e.result)
+				uni.navigateTo({
+					url: `/uni_modules/uni-upgrade-center-app/pages/upgrade-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
+					fail: (err) => {
+						console.error('更新弹框跳转失败', err)
+						uni.removeStorageSync(PACKAGE_INFO_KEY)
+					}
+				})
+				
+				return
+			} else if (code < 0) {
+				// TODO 云函数报错处理
+				console.error(message)
+				return reject(e)
+			}
+			return resolve(e)
+		}).catch(err => {
+			// TODO 云函数报错处理
+			console.error(err.message)
+			reject(err)
+		})
+	});
+	// #endif
+}
+
+/**
+ * 使用 uni.showModal 升级
+ */
+function updateUseModal(packageInfo) {
+	const {
+		title, // 标题
+		contents, // 升级内容
+		is_mandatory, // 是否强制更新
+		url, // 安装包下载地址
+		platform, // 安装包平台
+		type // 安装包类型
+	} = packageInfo;
+
+	let isWGT = type === 'wgt'
+	let isiOS = !isWGT ? platform.includes('iOS') : false;
+	let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'
+
+	return uni.showModal({
+		title,
+		content: contents,
+		showCancel: !is_mandatory,
+		confirmText,
+		success: res => {
+			if (res.cancel) return;
+
+			// 安装包下载
+			if (isiOS) {
+				plus.runtime.openURL(url);
+				return;
+			}
+
+			uni.showToast({
+				title: '后台下载中……',
+				duration: 1000
+			});
+
+			// wgt 和 安卓下载更新
+			downloadTask = uni.downloadFile({
+				url,
+				success: res => {
+					if (res.statusCode !== 200) {
+						console.error('下载安装包失败', err);
+						return;
+					}
+					// 下载好直接安装,下次启动生效
+					plus.runtime.install(res.tempFilePath, {
+						force: false
+					}, () => {
+						if (is_mandatory) {
+							//更新完重启app
+							plus.runtime.restart();
+							return;
+						}
+						uni.showModal({
+							title: '安装成功是否重启?',
+							success: res => {
+								if (res.confirm) {
+									//更新完重启app
+									plus.runtime.restart();
+								}
+							}
+						});
+					}, err => {
+						uni.showModal({
+							title: '更新失败',
+							content: err
+								.message,
+							showCancel: false
+						});
+					});
+				}
+			});
+		}
+	});
+}

+ 228 - 0
src/uni_modules/uni-upgrade-center-app/utils/check-update.ts

@@ -0,0 +1,228 @@
+import callCheckVersion, { UniUpgradeCenterResult } from "./call-check-version"
+import { platform_iOS } from './utils'
+// #ifdef UNI-APP-X
+import { openSchema } from '@/uni_modules/uts-openSchema'
+// #endif
+
+// 推荐再App.vue中使用
+const PACKAGE_INFO_KEY = '__package_info__'
+// #ifdef APP-HARMONY
+export default function (component?: any) : Promise<UniUpgradeCenterResult> {
+// #endif
+// #ifndef APP-HARMONY
+export default function () : Promise<UniUpgradeCenterResult> {
+// #endif
+	return new Promise<UniUpgradeCenterResult>((resolve, reject) => {
+		callCheckVersion().then(async (uniUpgradeCenterResult) => {
+			// NOTE uni-app x 3.96 解构有问题
+			const code = uniUpgradeCenterResult.code
+			const message = uniUpgradeCenterResult.message
+			const url = uniUpgradeCenterResult.url // 安装包下载地址
+        // 此处逻辑仅为示例,可自行编写
+        if (code > 0) {
+          // 腾讯云获取下载链接
+          if (/^cloud:\/\//.test(url)) {
+              const tcbRes = await uniCloud.getTempFileURL({ fileList: [url] });
+              if (typeof tcbRes.fileList[0].tempFileURL !== 'undefined') uniUpgradeCenterResult.url = tcbRes.fileList[0].tempFileURL;
+          }
+
+          /**
+           * 提示升级一
+           * 使用 uni.showModal
+           */
+          // return updateUseModal(uniUpgradeCenterResult)
+
+          // #ifndef UNI-APP-X
+          // 静默更新,只有wgt有
+          if (uniUpgradeCenterResult.is_silently) {
+            uni.downloadFile({
+              url: uniUpgradeCenterResult.url,
+              success: res => {
+                if (res.statusCode == 200) {
+                  // 下载好直接安装,下次启动生效
+                  plus.runtime.install(res.tempFilePath, {
+                    force: false
+                  });
+                }
+              }
+            });
+            return;
+          }
+          // #endif
+
+          /**
+           * 提示升级二
+           * 官方适配的升级弹窗,可自行替换资源适配UI风格
+           */
+          // #ifndef UNI-APP-X
+          // #ifdef APP-PLUS
+          uni.setStorageSync(PACKAGE_INFO_KEY, uniUpgradeCenterResult)
+          uni.navigateTo({
+            url: `/uni_modules/uni-upgrade-center-app/pages/upgrade-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
+            fail: (err) => {
+              console.error('更新弹框跳转失败', err)
+              uni.removeStorageSync(PACKAGE_INFO_KEY)
+            }
+          })
+          // #endif
+          // #ifdef APP-HARMONY
+          if (component) {
+            component.show(true, uniUpgradeCenterResult)
+          } else {
+            reject({
+              code: -1,
+              message: '在 HarmonyOS Next 平台请传递组件使用'
+            })
+          }
+          // #endif
+          // #endif
+          // #ifdef UNI-APP-X
+          uni.setStorageSync(PACKAGE_INFO_KEY, uniUpgradeCenterResult)
+          uni.openDialogPage({
+            url: `/uni_modules/uni-upgrade-center-app/pages/uni-app-x/upgrade-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
+            disableEscBack: true,
+            fail: (err) => {
+              console.error('更新弹框跳转失败', err)
+              uni.removeStorageSync(PACKAGE_INFO_KEY)
+            }
+          })
+          // #endif
+
+          return resolve(uniUpgradeCenterResult)
+        } else if (code < 0) {
+          console.error(message)
+          return reject(uniUpgradeCenterResult)
+        }
+        return resolve(uniUpgradeCenterResult)
+      }).catch((err) => {
+        reject(err)
+      })
+    });
+  }
+
+/**
+ * 使用 uni.showModal 升级
+ */
+function updateUseModal(packageInfo : UniUpgradeCenterResult) : void {
+	// #ifdef APP
+	const {
+		title, // 标题
+		contents, // 升级内容
+		is_mandatory, // 是否强制更新
+		url, // 安装包下载地址
+		type,
+		platform
+	} = packageInfo;
+
+	let isWGT = type === 'wgt'
+	let isiOS = !isWGT ? platform.includes(platform_iOS) : false;
+
+	// #ifndef UNI-APP-X
+	let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'
+	// #endif
+	// #ifdef UNI-APP-X
+	let confirmText = '立即下载更新'
+	// #endif
+
+    return uni.showModal({
+      title,
+      content: contents,
+      showCancel: !is_mandatory,
+      confirmText,
+      success: res => {
+        if (res.cancel) return;
+
+			if (isiOS) {
+				// iOS 平台跳转 AppStore
+				// #ifndef UNI-APP-X
+				plus.runtime.openURL(url);
+				// #endif
+				// #ifdef UNI-APP-X
+				openSchema(url)
+				// #endif
+				return;
+			}
+
+        uni.showToast({
+          title: '后台下载中……',
+          duration: 1000
+        });
+
+			// wgt 和 安卓下载更新
+			uni.downloadFile({
+				url,
+				success: res => {
+					if (res.statusCode !== 200) {
+						console.error('下载安装包失败');
+						return;
+					}
+					// 下载好直接安装,下次启动生效
+          // uni-app x 项目没有 plus5+ 故使用条件编译
+					// #ifndef UNI-APP-X
+					plus.runtime.install(res.tempFilePath, {
+						force: false
+					}, () => {
+						if (is_mandatory) {
+							//更新完重启app
+							// #ifdef APP-PLUS
+							plus.runtime.restart();
+							// #endif
+							// #ifdef APP-HARMONY
+							uni.showModal({
+								title: '安装成功',
+								content: '请手动重启应用',
+								showCancel: false,
+								success: res => {
+									plus.runtime.quit();
+								}
+							});
+							// #endif
+							return;
+						}
+						uni.showModal({
+							title: '安装成功是否重启?',
+							success: res => {
+								if (res.confirm) {
+									//更新完重启app
+									// #ifdef APP-PLUS
+									plus.runtime.restart();
+									// #endif
+									// #ifdef APP-HARMONY
+									plus.runtime.quit();
+									// #endif
+								}
+							}
+						});
+					}, err => {
+						uni.showModal({
+							title: '更新失败',
+							content: err
+								.message,
+							showCancel: false
+						});
+					});
+					// #endif
+
+          // #ifdef UNI-APP-X
+          uni.installApk({
+          	filePath: res.tempFilePath,
+          	success: () => {
+          		uni.showModal({
+          			title: '安装成功请手动重启'
+          		});
+          	},
+          	fail: err => {
+          		uni.showModal({
+          			title: '更新失败',
+          			content: err.errMsg,
+          			showCancel: false
+          		});
+          	}
+          });
+          // #endif
+				}
+			});
+		}
+	});
+	// #endif
+}

+ 46 - 0
src/uni_modules/uni-upgrade-center-app/utils/utils.ts

@@ -0,0 +1,46 @@
+export const platform_iOS: string = 'iOS';
+export const platform_Android: string = 'Android';
+export const platform_Harmony: string = 'Harmony';
+
+/**
+ * 对比版本号,如需要,请自行修改判断规则
+ * 支持比对	("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")	("3.0.0.1", "3.0")	("3.1.1", "3.1.1.1") 之类的
+ * @param {Object} v1
+ * @param {Object} v2
+ * v1 > v2 return 1
+ * v1 < v2 return -1
+ * v1 == v2 return 0
+ */
+export function compare(v_1: string = '0', v_2: string = '0') {
+	const v1: string[] = String(v_1).split('.');
+	const v2: string[] = String(v_2).split('.');
+	const minVersionLens = Math.min(v1.length, v2.length);
+
+	let result = 0;
+	for (let i = 0; i < minVersionLens; i++) {
+		const curV1 = Number(v1[i]);
+		const curV2 = Number(v2[i]);
+
+		if (curV1 > curV2) {
+			result = 1;
+			break;
+		} else if (curV1 < curV2) {
+			result = -1;
+			break;
+		}
+	}
+
+	if (result === 0 && v1.length !== v2.length) {
+		const v1BiggerThenv2 = v1.length > v2.length;
+		const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
+		for (let i = minVersionLens; i < maxLensVersion.length; i++) {
+			const curVersion = Number(maxLensVersion[i]);
+			if (curVersion > 0) {
+				v1BiggerThenv2 ? (result = 1) : (result = -1);
+				break;
+			}
+		}
+	}
+
+	return result;
+}

+ 10 - 0
src/uni_modules/uts-openSchema/changelog.md

@@ -0,0 +1,10 @@
+## 1.1.2(2025-03-20)
+- 更新 支持鸿蒙
+## 1.1.1(2024-12-16)
+- 修复 canOpenURL 在安卓端可能会报类型错误的问题
+## 1.1.0(2024-12-06)
+- 新增 canOpenURL UTS API,可用此API判断url是否可以跳转
+## 1.0.1(2024-11-13)
+- 修复 Android 打开部分 schema 时没有跳转到目标应用的 Bug
+## 1.0.0(2024-04-25)
+- 更新 在 Android 和 iOS 上打开链接的 UTS API

+ 83 - 0
src/uni_modules/uts-openSchema/package.json

@@ -0,0 +1,83 @@
+{
+  "id": "uts-openSchema",
+  "displayName": "uts-openSchema",
+  "version": "1.1.2",
+  "description": "在 Android 和 iOS 上打开链接的 UTS API",
+  "keywords": [
+    "uts-openSchema"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^4.0"
+  },
+  "dcloudext": {
+    "type": "uts",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+            "app-android": "y",
+            "app-ios": "y",
+            "app-harmony": "y"
+        },
+        "H5-mobile": {
+          "Safari": "n",
+          "Android Browser": "n",
+          "微信浏览器(Android)": "n",
+          "QQ浏览器(Android)": "n"
+        },
+        "H5-pc": {
+          "Chrome": "n",
+          "IE": "n",
+          "Edge": "n",
+          "Firefox": "n",
+          "Safari": "n"
+        },
+        "小程序": {
+          "微信": "n",
+          "阿里": "n",
+          "百度": "n",
+          "字节跳动": "n",
+          "QQ": "n",
+          "钉钉": "n",
+          "快手": "n",
+          "飞书": "n",
+          "京东": "n"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        }
+      }
+    }
+  }
+}

+ 59 - 0
src/uni_modules/uts-openSchema/readme.md

@@ -0,0 +1,59 @@
+# uts-openSchema
+
+打开链接,支持:
+
+1. 打开外部 App
+2. 使用浏览器打开链接
+3. 打开地图到指定地点
+4. ...
+
+## 使用
+
+1. 安装此插件
+2. 在要使用的地方 `import` 导入
+  ```ts
+  import { openSchema, canOpenURL } from '@/uni_modules/uts-openSchema'
+  ```
+3. 直接调用 `openSchema` 方法:
+  ```ts
+  // #ifdef UNI-APP-X
+  // 使用外部浏览器打开指定URL
+  openSchema('https://uniapp.dcloud.io/uni-app-x')
+
+  // #ifdef APP-ANDROID
+  // Android 使用应用商店打开指定App
+  openSchema('market://details?id=com.tencent.mm')
+
+  // Android 打开地图坐标
+  // 可以先用canOpenURL判断是否安装了地图软件
+  if (canOpenURL('androidamap://')) {
+    openSchema('androidamap://viewMap?sourceApplication=Hello%20uni-app&poiname=DCloud&lat=39.9631018208&lon=116.3406135236&dev=0')
+  } else {
+    console.log('未安装高德地图')
+  }
+  // #endif -->
+
+  // #ifdef APP-IOS
+  // 打开 AppStore 到搜索页
+  openSchema('itms-apps://search.itunes.apple.com//WebObjects//MZSearch.woa/wa/search?media=software&lterm=')
+
+  // 打开 iOS 地图坐标
+  openSchema('http://maps.apple.com/?q=Mexican+Restaurant&sll=50.894967,4.341626&z=10&t=s')
+  // #endif -->
+
+  // #endif -->
+  ```
+
+### 参数
+
+- openSchema(url: string) // `url`:要打开的链接 `必填` `不为空字符串`
+
+## 相关开发文档
+
+[UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html)
+
+[UTS API插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html)
+
+[UTS 组件插件](https://uniapp.dcloud.net.cn/plugin/uts-component.html)
+
+[Hello UTS](https://gitcode.net/dcloud/hello-uts)

+ 3 - 0
src/uni_modules/uts-openSchema/utssdk/app-android/config.json

@@ -0,0 +1,3 @@
+{
+  "minSdkVersion": "21"
+}

+ 27 - 0
src/uni_modules/uts-openSchema/utssdk/app-android/index.uts

@@ -0,0 +1,27 @@
+import Intent from 'android.content.Intent'
+import Uri from 'android.net.Uri'
+import { OpenSchema, CanOpenURL } from '../interface.uts'
+
+export const openSchema : OpenSchema = function (url : string) {
+  if (canOpenURL(url)) {
+    const context = UTSAndroid.getUniActivity()!
+    const uri = Uri.parse(url)
+    const intent = new Intent(Intent.ACTION_VIEW, uri)
+    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+    intent.setData(uri)
+    context.startActivity(intent)
+  } else {
+    console.error('url param Error:', JSON.stringify(url))
+  }
+}
+
+export const canOpenURL : CanOpenURL = function (url : string) : boolean {
+  if (typeof url === 'string' && url.length > 0) {
+    const context = UTSAndroid.getUniActivity()!
+    const uri = Uri.parse(url)
+    const intent = new Intent(Intent.ACTION_VIEW, uri)
+    return intent.resolveActivity(context.packageManager) != null ? true : false
+  } else {
+    return false
+  }
+}

+ 20 - 0
src/uni_modules/uts-openSchema/utssdk/app-harmony/index.uts

@@ -0,0 +1,20 @@
+import { bundleManager, common } from '@kit.AbilityKit';
+import OpenLinkOptions from '@ohos.app.ability.OpenLinkOptions'
+import { getAbilityContext } from '@dcloudio/uni-runtime'
+import { OpenSchema, CanOpenURL } from '../interface.uts'
+
+
+export const openSchema : OpenSchema = function (url : string) : void {
+  (getAbilityContext() as common.UIAbilityContext)?.openLink(url, {
+    appLinkingOnly: false
+  } as OpenLinkOptions)
+}
+
+
+export const canOpenURL : CanOpenURL = function (url : string) : boolean {
+  try {
+    return bundleManager.canOpenLink(url)
+  } catch (error) {
+    return false
+  }
+}

+ 3 - 0
src/uni_modules/uts-openSchema/utssdk/app-ios/config.json

@@ -0,0 +1,3 @@
+{
+  "deploymentTarget": "12.0"
+}

+ 20 - 0
src/uni_modules/uts-openSchema/utssdk/app-ios/index.uts

@@ -0,0 +1,20 @@
+import { OpenSchema, CanOpenURL } from '../interface.uts'
+
+export const openSchema : OpenSchema = function (url : string) : void {
+  if (canOpenURL(url)) {
+    let uri = new URL(string = url)
+    UIApplication.shared.open(uri!, options = new Map<UIApplication.OpenExternalURLOptionsKey, any>(), completionHandler = null)
+  } else {
+    console.error('url param Error: ', url)
+  }
+}
+
+export const canOpenURL : CanOpenURL = function (url : string) : boolean {
+  if (typeof url == 'string' && url.length > 0) {
+    let uri = new URL(string = url)
+    if (uri != null && UIApplication.shared.canOpenURL(uri!)) {
+      return true
+    }
+  }
+  return false
+}

+ 2 - 0
src/uni_modules/uts-openSchema/utssdk/interface.uts

@@ -0,0 +1,2 @@
+export type OpenSchema = (url : string) => void
+export type CanOpenURL = (url : string) => boolean

+ 12 - 0
src/uni_modules/uts-openSchema/utssdk/web/index.uts

@@ -0,0 +1,12 @@
+import { OpenSchema, CanOpenURL } from '../interface.uts'
+
+export const openSchema : OpenSchema = function (url : string) : void {
+  location.href = url;
+}
+
+export const canOpenURL : CanOpenURL = function (url : string) : boolean {
+  if (url != "") {
+    return true;
+  }
+  return false;
+}

+ 28 - 0
src/uni_modules/uts-progressNotification/changelog.md

@@ -0,0 +1,28 @@
+## 1.1.2(2025-02-10)
+修复某些情况通过点击通知消息无法拉起App的bug
+## 1.1.1(2024-09-03)
+去除TypeScript警告
+## 1.1.0(2024-03-08)
+修复uniapp打包报错问题
+## 1.0.9(2024-02-29)
+去除代码过时警告
+## 1.0.8(2023-12-21)
+去除app-ios目录
+## 1.0.7(2023-12-11)
+去除无用代码
+## 1.0.6(2023-12-11)
+修改文档
+## 1.0.5(2023-12-11)
+1.修改插件名称
+2.修改插件引入方式为import导入
+## 1.0.4(2023-11-30)
+1. createNotificationProgress增加`onClick`回调
+2.修复在小米部分系统上,通知消息会归类于不重要通知的bug
+## 1.0.3(2023-11-28)
+更新截图
+## 1.0.2(2023-11-28)
+修改资源的包名
+## 1.0.1(2023-11-28)
+更新文档
+## 1.0.0(2023-11-28)
+Android通知栏显示进度插件

+ 85 - 0
src/uni_modules/uts-progressNotification/package.json

@@ -0,0 +1,85 @@
+{
+  "id": "uts-progressNotification",
+  "displayName": "uts-progressNotification",
+  "version": "1.1.2",
+  "description": "uts-progressNotification",
+  "keywords": [
+    "progressNotification"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.91"
+  },
+  "dcloudext": {
+    "type": "uts",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "TargetSDKVersion33以上时需配置\n`android.permission.POST_NOTIFICATIONS`"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+            "app-android": {
+                "minVersion": "19"
+            },
+            "app-ios": "n",
+            "app-harmony": "u"
+        },
+        "H5-mobile": {
+          "Safari": "n",
+          "Android Browser": "n",
+          "微信浏览器(Android)": "n",
+          "QQ浏览器(Android)": "n"
+        },
+        "H5-pc": {
+          "Chrome": "n",
+          "IE": "n",
+          "Edge": "n",
+          "Firefox": "n",
+          "Safari": "n"
+        },
+        "小程序": {
+          "微信": "n",
+          "阿里": "n",
+          "百度": "n",
+          "字节跳动": "n",
+          "QQ": "n",
+          "钉钉": "n",
+          "快手": "n",
+          "飞书": "n",
+          "京东": "n"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        }
+      }
+    }
+  }
+}

+ 71 - 0
src/uni_modules/uts-progressNotification/readme.md

@@ -0,0 +1,71 @@
+# uts-progressNotification
+
+## 使用说明
+
+Android平台创建显示进度的通知栏消息
+
+**注意: 需要自定义基座,否则点击通知栏消息不会拉起应用**
+
+### 导入
+
+需要import导入插件
+
+### createNotificationProgress(options : CreateNotificationProgressOptions) : void,
+
+创建显示进度的通知栏消息
+
+参数说明
+
+```
+export type CreateNotificationProgressOptions = {
+	/**
+	 * 通知标题
+	 * @defaultValue 应用名称
+	 */
+	title ?: string | null
+	/**
+	 * 通知内容
+	 */
+	content : string,
+	/**
+	 * 进度
+	 */
+	progress : number,
+	/**
+	 * 点击通知消息回调
+	 * @defaultValue null
+	 */
+	onClick? : (() => void) | null
+}
+```
+
+### finishNotificationProgress(options: FinishNotificationProgressOptions) : void
+
+完成时调用的API,比如下载完成后需要显示下载完成并隐藏进度时调用。
+
+参数说明
+
+
+```
+export type FinishNotificationProgressOptions = {
+	/**
+	 * 通知标题
+	 * @defaultValue 应用名称
+	 */
+	title ?: string | null
+	/**
+	 * 通知内容
+	 */
+	content : string,
+	/**
+	 * 点击通知消息回调
+	 */
+	onClick : () => void
+}
+```
+
+
+### cancelNotificationProgress() : void
+
+取消通知消息显示
+

+ 11 - 0
src/uni_modules/uts-progressNotification/utssdk/app-android/AndroidManifest.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
+	package="uts.sdk.modules.utsProgressNotification">
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
+	<application>
+		<activity android:name="uts.sdk.modules.utsProgressNotification.TransparentActivity"
+			android:theme="@style/DCNotificationProgressTranslucentTheme" android:hardwareAccelerated="true"
+			android:screenOrientation="user" android:exported="true">
+		</activity>
+	</application>
+</manifest>

+ 62 - 0
src/uni_modules/uts-progressNotification/utssdk/app-android/TransparentActivity.uts

@@ -0,0 +1,62 @@
+import Activity from "android.app.Activity";
+import Bundle from 'android.os.Bundle';
+import Build from 'android.os.Build';
+import View from 'android.view.View';
+import Color from 'android.graphics.Color';
+import WindowManager from 'android.view.WindowManager';
+import { getGlobalNotificationProgressCallBack, getGlobalNotificationProgressFinishCallBack, setGlobalNotificationProgressCallBack, setGlobalNotificationProgressFinishCallBack} from './callbacks.uts';
+import { ACTION_DOWNLOAD_FINISH, ACTION_DOWNLOAD_PROGRESS } from "./constant.uts"
+
+
+export class TransparentActivity extends Activity {
+	constructor() {
+		super()
+	}
+
+  @Suppress("DEPRECATION")
+	override onCreate(savedInstanceState : Bundle | null) {
+		super.onCreate(savedInstanceState)
+		this.fullScreen(this)
+		const action = this.getIntent().getAction()
+		if (action == ACTION_DOWNLOAD_FINISH) {
+			setTimeout(() => {
+        getGlobalNotificationProgressFinishCallBack()?.()
+        setGlobalNotificationProgressFinishCallBack(() => { })
+			}, 100)
+			this.overridePendingTransition(0, 0)
+		}
+
+		if (action == ACTION_DOWNLOAD_PROGRESS) {
+			setTimeout(() => {
+				getGlobalNotificationProgressCallBack()?.()
+        setGlobalNotificationProgressCallBack(() => { })
+			}, 100)
+			this.overridePendingTransition(0, 0)
+		}
+
+		setTimeout(() => {
+			this.finish()
+		}, 20)
+	}
+
+
+	@Suppress("DEPRECATION")
+	private fullScreen(activity : Activity) {
+		if (Build.VERSION.SDK_INT >= 19) {
+			if (Build.VERSION.SDK_INT >= 21) {
+				const window = activity.getWindow();
+				const decorView = window.getDecorView();
+				const option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+				decorView.setSystemUiVisibility(option);
+				window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+				window.setStatusBarColor(Color.TRANSPARENT);
+			} else {
+				const window = activity.getWindow();
+				const attributes = window.getAttributes();
+				const flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
+				attributes.flags |= flagTranslucentStatus;
+				window.setAttributes(attributes);
+			}
+		}
+	}
+}

+ 19 - 0
src/uni_modules/uts-progressNotification/utssdk/app-android/callbacks.uts

@@ -0,0 +1,19 @@
+let globalNotificationProgressCallBack : (() => void) | null = () => { }
+let globalNotificationProgressFinishCallBack : (() => void) | null = () => { }
+
+export function setGlobalNotificationProgressCallBack(callBack : (() => void) | null) : void {
+  globalNotificationProgressCallBack = callBack
+}
+
+export function getGlobalNotificationProgressCallBack() : (() => void) | null {
+  return globalNotificationProgressCallBack
+}
+
+
+export function setGlobalNotificationProgressFinishCallBack(callBack : (() => void) | null) : void {
+  globalNotificationProgressFinishCallBack = callBack
+}
+
+export function getGlobalNotificationProgressFinishCallBack() : (() => void) | null {
+  return globalNotificationProgressFinishCallBack
+}

+ 3 - 0
src/uni_modules/uts-progressNotification/utssdk/app-android/config.json

@@ -0,0 +1,3 @@
+{
+  "minSdkVersion": "19"
+}

+ 2 - 0
src/uni_modules/uts-progressNotification/utssdk/app-android/constant.uts

@@ -0,0 +1,2 @@
+export const ACTION_DOWNLOAD_FINISH = "ACTION_DOWNLOAD_FINISH"
+export const ACTION_DOWNLOAD_PROGRESS = "ACTION_DOWNLOAD_PROGRESS"

+ 156 - 0
src/uni_modules/uts-progressNotification/utssdk/app-android/index.uts

@@ -0,0 +1,156 @@
+import Build from 'android.os.Build';
+import Context from 'android.content.Context';
+import NotificationManager from 'android.app.NotificationManager';
+import NotificationChannel from 'android.app.NotificationChannel';
+import Notification from 'android.app.Notification';
+import Intent from 'android.content.Intent';
+import ComponentName from 'android.content.ComponentName';
+import PendingIntent from 'android.app.PendingIntent';
+import { CreateNotificationProgressOptions, FinishNotificationProgressOptions } from '../interface.uts';
+import { ACTION_DOWNLOAD_FINISH, ACTION_DOWNLOAD_PROGRESS } from "./constant.uts"
+
+import { setGlobalNotificationProgressCallBack, setGlobalNotificationProgressFinishCallBack } from './callbacks.uts';
+
+export { TransparentActivity } from './TransparentActivity.uts';
+
+
+const DOWNLOAD_PROGRESS_NOTIFICATION_ID : Int = 7890
+const DC_DOWNLOAD_CHANNEL_ID = "下载文件"
+const DC_DOWNLOAD_CHANNEL_NAME = "用于显示现在进度的渠道"
+
+
+let notificationBuilder : Notification.Builder | null = null
+
+let timeId = -1
+
+let histroyProgress = 0
+
+let isProgress = false
+
+
+
+export function createNotificationProgress(options : CreateNotificationProgressOptions) : void {
+	const { content, progress, onClick } = options
+
+	if (progress == 100) {
+		clearTimeout(timeId)
+		const context = UTSAndroid.getAppContext() as Context
+		realCreateNotificationProgress(options.title ?? getAppName(context), content, progress, onClick)
+		reset()
+		return
+	}
+
+	histroyProgress = progress
+	if (timeId != -1) {
+		return
+	}
+
+	const context = UTSAndroid.getAppContext() as Context
+	if (!isProgress) {
+		realCreateNotificationProgress(options.title ?? getAppName(context), content, histroyProgress, onClick)
+		isProgress = true
+	} else {
+		timeId = setTimeout(() => {
+			realCreateNotificationProgress(options.title ?? getAppName(context), content, histroyProgress, onClick)
+			timeId = -1
+		}, 1000)
+	}
+}
+
+
+export function cancelNotificationProgress() : void {
+	const context = UTSAndroid.getAppContext() as Context
+	const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+	notificationManager.cancel(DOWNLOAD_PROGRESS_NOTIFICATION_ID)
+	reset()
+}
+
+
+function realCreateNotificationProgress(title : string, content : string, progress : number, cb : (() => void) | null) : void {
+  setGlobalNotificationProgressCallBack(cb)
+	const context = UTSAndroid.getAppContext() as Context
+	const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+	createDownloadChannel(notificationManager)
+	const builder = createNotificationBuilder(context)
+	builder.setProgress(100, progress.toInt(), false)
+	builder.setContentTitle(title)
+	builder.setContentText(content)
+	builder.setContentIntent(createPendingIntent(context, ACTION_DOWNLOAD_PROGRESS));
+	notificationManager.notify(DOWNLOAD_PROGRESS_NOTIFICATION_ID, builder.build())
+}
+
+
+export function finishNotificationProgress(options : FinishNotificationProgressOptions) {
+  setGlobalNotificationProgressFinishCallBack(options.onClick)
+	const context = UTSAndroid.getAppContext() as Context
+	const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+	createDownloadChannel(notificationManager)
+	const builder = createNotificationBuilder(context)
+	builder.setProgress(0, 0, false)
+	builder.setContentTitle(options.title ?? getAppName(context))
+	builder.setContentText(options.content)
+	//小米rom setOngoing未false的时候,会被通知管理器归为不重要通知
+	// builder.setOngoing(false)
+	builder.setAutoCancel(true);
+	builder.setContentIntent(createPendingIntent(context, ACTION_DOWNLOAD_FINISH));
+	notificationManager.notify(DOWNLOAD_PROGRESS_NOTIFICATION_ID, builder.build())
+	reset()
+}
+
+function reset() {
+	isProgress = false
+	notificationBuilder = null
+	histroyProgress = 0
+	if (timeId != -1) {
+		clearTimeout(timeId)
+		timeId = -1
+	}
+}
+
+function createPendingIntent(context : Context, action : string) : PendingIntent {
+	const intent = new Intent(action);
+	intent.setComponent(new ComponentName(context.getPackageName(), "uts.sdk.modules.utsProgressNotification.TransparentActivity"));
+	let flags = PendingIntent.FLAG_UPDATE_CURRENT;
+	if (Build.VERSION.SDK_INT >= 23) {
+		flags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE;
+	}
+	return PendingIntent.getActivity(context, DOWNLOAD_PROGRESS_NOTIFICATION_ID, intent, flags);
+}
+
+function createDownloadChannel(notificationManager : NotificationManager) {
+	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+		const channel = new NotificationChannel(
+			DC_DOWNLOAD_CHANNEL_ID,
+			DC_DOWNLOAD_CHANNEL_NAME,
+			NotificationManager.IMPORTANCE_LOW
+		)
+		notificationManager.createNotificationChannel(channel)
+	}
+}
+@Suppress("DEPRECATION")
+function createNotificationBuilder(context : Context) : Notification.Builder {
+	if (notificationBuilder == null) {
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+			notificationBuilder = new Notification.Builder(context, DC_DOWNLOAD_CHANNEL_ID)
+		} else {
+			notificationBuilder = new Notification.Builder(context)
+		}
+		notificationBuilder!.setSmallIcon(context.getApplicationInfo().icon)
+		notificationBuilder!.setOngoing(true)
+		notificationBuilder!.setSound(null)
+	}
+	return notificationBuilder!
+}
+
+@Suppress("DEPRECATION")
+function getAppName(context : Context) : string {
+	let appName = ""
+	try {
+		const packageManager = context.getPackageManager()
+		const applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0)
+		appName = packageManager.getApplicationLabel(applicationInfo) as string
+	} catch (e : Exception) {
+		e.printStackTrace()
+	}
+	return appName
+}

+ 11 - 0
src/uni_modules/uts-progressNotification/utssdk/app-android/res/values/notification_progress_styles.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="DCNotificationProgressTranslucentTheme">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+    </style>
+</resources>

+ 46 - 0
src/uni_modules/uts-progressNotification/utssdk/interface.uts

@@ -0,0 +1,46 @@
+export type CreateNotificationProgressOptions = {
+	/**
+	 * 通知标题
+	 * @defaultValue 应用名称
+	 */
+	title ?: string | null
+	/**
+	 * 通知内容
+	 */
+	content : string,
+	/**
+	 * 进度
+	 */
+	progress : number,
+	/**
+	 * 点击通知消息回调
+	 * @defaultValue null
+	 */
+	onClick? : (() => void) | null
+}
+
+
+export type FinishNotificationProgressOptions = {
+	/**
+	 * 通知标题
+	 * @defaultValue 应用名称
+	 */
+	title ?: string | null
+	/**
+	 * 通知内容
+	 */
+	content : string,
+	/**
+	 * 点击通知消息回调
+	 */
+	onClick : () => void
+}
+
+
+export type CreateNotificationProgress = (options : CreateNotificationProgressOptions) => void;
+
+
+export type CancelNotificationProgress = () => void;
+
+
+export type FinishNotificationProgress = (options: FinishNotificationProgressOptions) => void

+ 0 - 0
src/uni_modules/uts-progressNotification/utssdk/unierror.uts