ZaiZai %!s(int64=2) %!d(string=hai) anos
pai
achega
64a5690086

+ 144 - 13
components/hc-update/index.vue

@@ -6,7 +6,7 @@
                 <view class="relative flex">
                     <view class="flex-1 text-white hc-p">
                         <view class="text-34">发现新版本</view>
-                        <view class="mt-2">v1.0.0</view>
+                        <view class="mt-2">v{{versionData.versionNumber}}</view>
                     </view>
                     <view class="relative top--60 right-40">
                         <c-lottie src='/static/update/2.json' width="240rpx" height='240rpx' :loop="true"/>
@@ -15,41 +15,172 @@
             </view>
             <view class="update-content-bar hc-p">
                 <scroll-view scroll-y>
-                    <view>更新内容: </view>
-                    <view class="mt-2 text-gray-6">1111</view>
+                    <view class="text-gray-5 text-26">{{versionData.updateDate}}</view>
+                    <view class="mt-1">本次更新升级内容:</view>
+                    <view class="mt-3 text-gray-6" style="white-space: pre;">{{versionData.updateContent}}</view>
                 </scroll-view>
             </view>
             <view class="update-action-bar">
-                <view class="hc-flex hc-p">
-                    <button class="cu-btn bg-blue-5 text-white flex-1 mr-2">立即更新</button>
-                    <button class="cu-btn bg-gray-4 text-white flex-1 ml-2">下次再说</button>
+                <view class="relative hc-p" v-if="isDownload">
+                    <view class="hc-flex justify-between mb-1">
+                        <view class="text-24 text-gray-5">已下载:{{downloaded}}</view>
+                        <view class="text-24 text-gray-5">总大小:{{totalFileSize}}</view>
+                    </view>
+                    <uv-line-progress :percentage="downloadNum"/>
                 </view>
+                <template v-else>
+                    <view class="hc-flex hc-p" v-if="versionData.constraintUpdate !== 1">
+                        <button class="cu-btn bg-blue-5 text-white flex-1 mr-2" @click="updateClick">立即更新</button>
+                        <button class="cu-btn bg-gray-4 text-white flex-1 ml-2" @click="nextTap">下次再说</button>
+                    </view>
+                    <view class="hc-flex hc-p" v-else>
+                        <button class="cu-btn bg-blue-5 text-white flex-1" @click="updateClick">立即更新</button>
+                    </view>
+                </template>
             </view>
         </view>
     </view>
 </template>
 
 <script setup>
-import {onMounted, ref} from "vue";
+import {onMounted, ref, watch} from "vue";
 import {getVersionData} from "~api/other";
+import website from '@/config/index';
+import {getObjValue} from "js-fast-way";
+import {filterSize} from "@/utils/utils";
+import {errorToast, successToast} from "@/utils/tools";
+import {useAppStore} from "@/store";
 
 //初始变量
+const store = useAppStore()
 const isShow = ref(false)
-const appInfo = ref({version: '', wgt: ''})
+const onUpdate = ref(store.onUpdate)
+const appUpdate = ref(store.appUpdate)
+const appInfo = ref({osName: '', version: ''})
 
 //渲染完成
 onMounted(() => {
-    const {appVersion, appWgtVersion} = uni.getSystemInfoSync();
-    appInfo.value = {version: appVersion, wgt: appWgtVersion}
+    const {appVersion, appWgtVersion, osName} = uni.getSystemInfoSync();
+    let version = appVersion
+    if (appVersion === appWgtVersion) {
+        version = appVersion
+    } else if (!appVersion && appWgtVersion) {
+        version = appWgtVersion
+    } else if (appVersion && !appWgtVersion) {
+        version = appVersion
+    } else if (appVersion > appWgtVersion) {
+        version = appVersion
+    } else if (appVersion < appWgtVersion) {
+        version = appWgtVersion
+    }
+    appInfo.value = {osName: osName, version: version}
+    appUpdate.value.appVersion = version
     getVersionDataApi()
 })
 
+//监听
+watch(() => [
+    store.onUpdate
+], ([val]) => {
+    if (val) {
+        const { version } = appInfo.value
+        const { versionNumber } = versionData.value
+        if (versionNumber > version) {
+            isShow.value = true
+        }
+    }
+})
+
 //获取新版本信息
+const versionData = ref({})
 const getVersionDataApi = async () => {
-    await getVersionData({
-        softwareType: 1,
-        versionId: '平台66611'
+    const { osName, version } = appInfo.value
+    const type = osName === 'ios' ? 2 : 1
+    const { data } = await getVersionData({
+        softwareType: type,
+        platform: website.platform
     })
+    const res = getObjValue(data)
+    versionData.value = res
+    appUpdate.value.version = res.versionNumber
+    const toUpdate = appUpdate.value.toUpdate
+    if (res.versionNumber > version) {
+        appUpdate.value.isUpdate = true
+        isShow.value = toUpdate
+    } else {
+        appUpdate.value.isUpdate = false
+        appUpdate.value.toUpdate = false
+    }
+    store.setAppUpdate(appUpdate.value)
+}
+
+//立即强制更新
+const isDownload = ref(false)
+const updateClick = async () => {
+    const {osName} = appInfo.value
+    const {fileType, fileUrl} = versionData.value
+    //ios的完整安装包
+    if (osName === 'ios' && fileType === 0) {
+        plus.runtime.openURL(fileUrl)
+        return false
+    }
+    //其他类型,安卓、ios的热更新包
+    downloadFile(fileUrl)
+}
+
+//下载相关文件资料
+const downloadNum = ref(0)
+const totalFileSize = ref('')
+const downloaded = ref('')
+const downloadFile = (fileUrl) => {
+    isDownload.value = true
+    const downloadTask = uni.downloadFile({
+        url: fileUrl,
+        success: ({statusCode, tempFilePath}) => {
+            if (statusCode === 200) {
+                installAppFile(tempFilePath)
+            } else {
+                errorToast('下载失败,请联系管理员')
+                nextTap()
+            }
+        },
+        fail: () => {
+            errorToast('下载失败,请联系管理员')
+            nextTap()
+        }
+    });
+    downloadTask.onProgressUpdate((res) => {
+        const {totalBytesExpectedToWrite, totalBytesWritten, progress} = getObjValue(res)
+        totalFileSize.value = filterSize(totalBytesExpectedToWrite)
+        downloadNum.value = progress
+        downloaded.value = filterSize(totalBytesWritten)
+    });
+}
+
+//安装相关资源文件
+const installAppFile = (file) => {
+    //0 完整安装包, 1 wgt热更新包
+    const {fileType} = versionData.value
+    plus.runtime.install(file, {
+        force: false
+    }, function() {
+        successToast('本次升级成功')
+        setTimeout(() => {
+            plus.runtime.restart();
+        }, 1500)
+    }, function(e) {
+        console.log(e)
+        errorToast('本次升级失败,请联系管理员')
+        nextTap()
+    });
+}
+
+//下次再说
+const nextTap = () => {
+    appUpdate.value.toUpdate = false
+    store.setAppUpdate(appUpdate.value)
+    isShow.value = false
+    isDownload.value = false
 }
 </script>
 

+ 1 - 0
config/index.js

@@ -1,5 +1,6 @@
 export default {
     title: "数字工程",
+    platform: 'client',         //app的key,用于检测升级
     key: 'uni-app',             //配置主键,目前用于存储
     clientId: 'uni-app',        // 客户端id
     clientSecret: 'app_secret', // 客户端密钥

+ 12 - 7
pages/my/config.vue

@@ -24,7 +24,7 @@
                     <text class="i-ri-pantone-fill text-purple text-32 mr-1"/>
                     <text class="text-gray-4">当前版本</text>
                 </view>
-                <view class="action text-gray-5">v{{appInfo.version}}</view>
+                <view class="action text-gray-5">v{{appInfo.appVersion}}</view>
             </view>
             <view class="cu-item">
                 <view class="content hc-flex">
@@ -32,8 +32,8 @@
                     <text class="text-gray-4">检测升级</text>
                 </view>
                 <view class="action">
-                    <!--view class="cu-tag round bg-blue light">有新版本</view-->
-                    <text class="text-26 text-gray-5">暂无新版本</text>
+                    <view class="cu-tag round bg-blue light" v-if="appInfo.isUpdate">v{{appInfo.version}}</view>
+                    <text class="text-26 text-gray-5" v-else>暂无新版本</text>
                 </view>
             </view>
         </view>
@@ -41,7 +41,7 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, watch} from "vue";
 import {onLoad} from '@dcloudio/uni-app'
 import {useAppStore} from "@/store";
 import userApi from '~api/user/index';
@@ -49,15 +49,20 @@ import userApi from '~api/user/index';
 //初始变量
 const store = useAppStore()
 const userInfo = ref(store.userInfo);
-const appInfo = ref({version: '-', wgt: '-'});
+const appInfo = ref(store.appUpdate)
 
 //渲染完成
 onLoad(() => {
-    const {appVersion, appWgtVersion} = uni.getSystemInfoSync();
-    appInfo.value = {version: appVersion, wgt: appWgtVersion}
     userConfigInfo()
 })
 
+//监听
+watch(() => [
+    store.appUpdate
+], ([val]) => {
+    appInfo.value = val
+})
+
 const toPageClick = (url) => {
     uni.navigateTo({url: url});
 }

+ 24 - 1
store/index.js

@@ -17,7 +17,16 @@ export const useAppStore = defineStore('main', {
         contractId: getStorage('contractId') ?? '',
         isAnimation: getStorage('isAnimation') ?? false,
         //消息数据
-        msgCountData: getStorage('msgCountData') ?? {}
+        msgCountData: getStorage('msgCountData') ?? {},
+        //检测升级
+        appUpdate: getStorage('appUpdate') ?? {
+            appVersion: '',
+            version: '',
+            isUpdate: false,
+            toUpdate: true
+        },
+        //改变值时,触发更新
+        onUpdate: null,
     }),
     actions: {
         //系统信息
@@ -58,6 +67,13 @@ export const useAppStore = defineStore('main', {
             this.msgCountData = value
             setStorage('msgCountData', value)
         },
+        setAppUpdate(value) {
+            this.appUpdate = value
+            setStorage('appUpdate', value)
+        },
+        setOnUpdate(value) {
+            this.onUpdate = value
+        },
         //清除缓存和token
         clearStoreData() {
             //清除状态
@@ -71,6 +87,13 @@ export const useAppStore = defineStore('main', {
             this.projectId = ''
             this.contractId = ''
             this.msgCountData = {}
+            this.appUpdate = {
+                appVersion: '',
+                version: '',
+                isUpdate: false,
+                toUpdate: true
+            }
+            this.onUpdate = null
             clearStorage()
         },
     }

+ 7 - 0
uni_modules/uv-line-progress/changelog.md

@@ -0,0 +1,7 @@
+## 1.0.2(2023-06-20)
+1. 适配height参数携带单位
+## 1.0.1(2023-05-16)
+1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
+2. 优化部分功能
+## 1.0.0(2023-05-10)
+uv-line-progress 线形进度条

+ 29 - 0
uni_modules/uv-line-progress/components/uv-line-progress/props.js

@@ -0,0 +1,29 @@
+export default {
+	props: {
+		// 激活部分的颜色
+		activeColor: {
+			type: String,
+			default: '#19be6b'
+		},
+		inactiveColor: {
+			type: String,
+			default: '#ececec'
+		},
+		// 进度百分比,数值
+		percentage: {
+			type: [String, Number],
+			default: 0
+		},
+		// 是否在进度条内部显示百分比的值
+		showText: {
+			type: Boolean,
+			default: true
+		},
+		// 进度条的高度,单位px
+		height: {
+			type: [String, Number],
+			default: 12
+		},
+		...uni.$uv?.props?.lineProgress
+	}
+}

+ 146 - 0
uni_modules/uv-line-progress/components/uv-line-progress/uv-line-progress.vue

@@ -0,0 +1,146 @@
+<template>
+	<view
+	    class="uv-line-progress"
+	    :style="[$uv.addStyle(customStyle)]"
+	>
+		<view
+		    class="uv-line-progress__background"
+		    ref="uv-line-progress__background"
+		    :style="[{
+				backgroundColor: inactiveColor,
+				height: $uv.addUnit($uv.getPx(height))
+			}]"
+		>
+		</view>
+		<view
+		    class="uv-line-progress__line"
+		    :style="[progressStyle]"
+		> 
+			<slot>
+				<text v-if="showText && percentage >= 10" class="uv-line-progress__text">{{innserPercentage + '%'}}</text>
+			</slot> 
+		</view>
+	</view>
+</template>
+
+<script>
+	import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
+	import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
+	import props from './props.js';
+	// #ifdef APP-NVUE
+	const dom = uni.requireNativePlugin('dom')
+	// #endif
+	/**
+	 * lineProgress 线型进度条
+	 * @description 展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。
+	 * @tutorial https://www.uvui.cn/components/lineProgress.html
+	 * @property {String}			activeColor		激活部分的颜色 ( 默认 '#19be6b' )
+	 * @property {String}			inactiveColor	背景色 ( 默认 '#ececec' )
+	 * @property {String | Number}	percentage		进度百分比,数值 ( 默认 0 )
+	 * @property {Boolean}			showText		是否在进度条内部显示百分比的值 ( 默认 true )
+	 * @property {String | Number}	height			进度条的高度,单位px ( 默认 12 )
+	 * 
+	 * @example <uv-line-progress :percent="70" :show-percent="true"></uv-line-progress>
+	 */
+	export default {
+		name: "uv-line-progress",
+		mixins: [mpMixin, mixin, props],
+		data() {
+			return {
+				lineWidth: 0,
+			}
+		},
+		watch: {
+			percentage(n) {
+				this.resizeProgressWidth()
+			}
+		},
+		computed: {
+			progressStyle() { 
+				let style = {}
+				style.width = this.lineWidth
+				style.backgroundColor = this.activeColor
+				style.height = this.$uv.addUnit(this.$uv.getPx(this.height))
+				return style
+			},
+			innserPercentage() {
+				// 控制范围在0-100之间
+				return this.$uv.range(0, 100, this.percentage)
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				this.$uv.sleep(20).then(() => {
+					this.resizeProgressWidth()
+				})
+			},
+			getProgressWidth() {
+				// #ifndef APP-NVUE
+				return this.$uvGetRect('.uv-line-progress__background')
+				// #endif
+
+				// #ifdef APP-NVUE
+				// 返回一个promise
+				return new Promise(resolve => {
+					dom.getComponentRect(this.$refs['uv-line-progress__background'], (res) => {
+						resolve(res.size)
+					})
+				})
+				// #endif
+			},
+			resizeProgressWidth() {
+				this.getProgressWidth().then(size => {
+					const {
+						width
+					} = size
+					// 通过设置的percentage值,计算其所占总长度的百分比
+					this.lineWidth = width * this.innserPercentage / 100 + 'px'
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
+
+	.uv-line-progress {
+		align-items: stretch;
+		position: relative;
+		@include flex(row);
+		flex: 1;
+		overflow: hidden;
+		border-radius: 100px;
+
+		&__background {
+			background-color: #ececec;
+			border-radius: 100px;
+			flex: 1;
+		}
+
+		&__line {
+			position: absolute;
+			top: 0;
+			left: 0;
+			bottom: 0;
+			align-items: center;
+			@include flex(row);
+			color: #ffffff;
+			border-radius: 100px;
+			transition: width 0.5s ease;
+			justify-content: flex-end;
+		}
+
+		&__text {
+			font-size: 10px;
+			align-items: center;
+			text-align: right;
+			color: #FFFFFF;
+			margin-right: 5px;
+			transform: scale(0.9);
+		}
+	}
+</style>

+ 87 - 0
uni_modules/uv-line-progress/package.json

@@ -0,0 +1,87 @@
+{
+  "id": "uv-line-progress",
+  "displayName": "uv-line-progress 线形进度条  全面兼容小程序、nvue、vue2、vue3等多端",
+  "version": "1.0.2",
+  "description": "uv-line-progress 该组件展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。",
+  "keywords": [
+    "uv-line-progress",
+    "uvui",
+    "uv-ui",
+    "progress",
+    "进度条"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+    	"ads": "无",
+    	"data": "插件不采集任何数据",
+    	"permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uv-ui-tools"
+		],
+    "encrypt": [],
+    "platforms": {
+			"cloud": {
+				"tcb": "y",
+				"aliyun": "y"
+			},
+			"client": {
+				"Vue": {
+					"vue2": "y",
+					"vue3": "y"
+				},
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "y"
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "y",
+					"Edge": "y",
+					"Firefox": "y",
+					"Safari": "y"
+				},
+				"小程序": {
+					"微信": "y",
+					"阿里": "y",
+					"百度": "y",
+					"字节跳动": "y",
+					"QQ": "y",
+					"钉钉": "u",
+					"快手": "u",
+					"飞书": "u",
+					"京东": "u"
+				},
+				"快应用": {
+					"华为": "u",
+					"联盟": "u"
+				}
+			}
+		}
+  }
+}

+ 11 - 0
uni_modules/uv-line-progress/readme.md

@@ -0,0 +1,11 @@
+## LineProgress 线形进度条
+
+> **组件名:uv-line-progress**
+
+展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。
+
+### <a href="https://www.uvui.cn/components/lineProgress.html" target="_blank">查看文档</a>
+
+### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
+
+#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>

+ 7 - 0
uni_modules/uv-ui-tools/changelog.md

@@ -1,3 +1,10 @@
+## 1.1.9(2023-08-27)
+1. 版本升级
+2. 优化
+## 1.1.8(2023-08-24)
+1. 版本升级
+## 1.1.7(2023-08-22)
+1. 版本升级
 ## 1.1.6(2023-08-18)
 uvui版本:1.1.6
 ## 1.0.15(2023-08-14)

+ 0 - 1
uni_modules/uv-ui-tools/index.js

@@ -32,7 +32,6 @@ const $uv = {
 	route,
 	config,
 	test,
-	throttle,
 	date: index.timeFormat, // 另名date
 	...index,
 	colorGradient: colorGradient.colorGradient,

+ 2 - 2
uni_modules/uv-ui-tools/libs/config/config.js

@@ -1,5 +1,5 @@
-// 此版本发布于2023-08-18
-const version = '1.1.6'
+// 此版本发布于2023-08-27
+const version = '1.1.9'
 
 // 开发环境才提示,生产环境不会提示
 if (process.env.NODE_ENV === 'development') {

+ 1 - 1
uni_modules/uv-ui-tools/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uv-ui-tools",
   "displayName": "uv-ui-tools 工具集 全面兼容vue3+2、app、h5、小程序等多端",
-  "version": "1.1.6",
+  "version": "1.1.9",
   "description": "uv-ui-tools,集成工具库,强大的Http请求封装,清晰的文档说明,开箱即用。方便使用,可以全局使用",
   "keywords": [
     "uv-ui-tools,uv-ui组件库,工具集,uvui,uView2.x"

+ 15 - 0
utils/utils.js

@@ -41,3 +41,18 @@ export const chooseVideo = () => {
         });
     })
 }
+
+export const filterSize = (size) => {
+    if (!size) return '';
+    if (size < pow1024(1)) return size + ' B';
+    if (size < pow1024(2)) return (size / pow1024(1)).toFixed(2) + ' KB';
+    if (size < pow1024(3)) return (size / pow1024(2)).toFixed(2) + ' MB';
+    if (size < pow1024(4)) return (size / pow1024(3)).toFixed(2) + ' GB';
+    return (size / pow1024(4)).toFixed(2) + ' TB'
+}
+
+// 求次幂
+function pow1024(num) {
+    return Math.pow(1024, num)
+}
+