jsy-app/components/custom-app-update/custom-app-update.vue
2025-02-11 17:55:20 +08:00

278 lines
6.1 KiB
Vue

<template>
<u-popup ref="popupRef" :show="showPop" :mask-click-able="false" mode="center" :overlay="true"
:closeOnClickOverlay="false" :safeAreaInsetBottom="false">
<view class="upgrade-popup">
<image class="header-bg" src="../../static/images/chengxushengji.png" mode="widthFix"></image>
<view class="main">
<view class="version">发现新版本{{ versionName }}</view>
<view class="content" v-if="versionDesc">
<text class="title">更新内容</text>
<view class="desc" v-html="versionDesc"></view>
</view>
<!--下载状态-进度条显示 -->
<view v-show="showPercent" class="progress">
<progress :percent="percent.progress" :show-info="true" stroke-width="15" />
<view style="font-size: 14px; text-align: center; margin: 14px 0">
下载中,请稍后({{ percent.totalBytesWritten }}/{{ percent.totalBytesExpectedToWrite }})</view>
</view>
<!-- 强制更新 -->
<view class="footer" v-if="isForceUpdate">
<view class="btn upgrade force" @click="handleUpgrade">立即更新</view>
</view>
<!-- 可选择更新 -->
<view class="footer" v-if="!isForceUpdate">
<view class="btn close" @click="handleClose">以后再说</view>
<view class="btn upgrade" @click="handleUpgrade">立即更新</view>
</view>
</view>
</view>
</u-popup>
</template>
<script setup>
import store from "@/store"
import {
ref,
reactive,
onMounted
} from "vue"
import {
onLaunch,
onShow,
onLoad
} from "@dcloudio/uni-app"
import {
getNewAppVersion
} from '@/api/index.js'
const showPop = ref(false)
const versionName = ref(null) //版本名称
const versionDesc = ref(null) //更新说明
const downloadUrl = ref(null) //APP下载链接
const isForceUpdate = ref(false) //是否强制更新
const showPercent = ref(false) //是否显示进度条
const percent = reactive({
progress: 0, //下载进度
totalBytesWritten: 0, //已经下载的数据长度
totalBytesExpectedToWrite: 0 //预期需要下载的数据总长度
})
// 使用 defineExpose 暴露给父组件调用
defineExpose({
show,
});
function show() {
// #ifdef APP-PLUS
const _version = getApp().version.newV;
if (_version) {
showPop.value = true;
versionName.value = _version.versionName;
versionDesc.value = null;
downloadUrl.value = _version.versionUrl;
isForceUpdate.value = _version.isForceUpdate;
} else {
showPop.value = false
}
// #endif
}
function hide() {
showPop.value = false
}
function handleUpgrade() {
if (uni.getSystemInfoSync().platform == "android") {
var downloadTask = uni.downloadFile({
url: downloadUrl.value,
success: downloadResult => {
if (downloadResult.statusCode === 200) {
console.log("下载成功")
plus.runtime.install(
downloadResult.tempFilePath, {
force: false
},
function() {
console.log("install success")
plus.runtime.restart()
},
function(e) {
console.error("install fail")
}
)
}
},
fail: () => {
uni.showToast({
title: "默认",
icon: "none",
duration: "下载失败,请检查网络连接"
})
}
})
showPercent.value = true
downloadTask.onProgressUpdate(res => {
percent.progress = res.progress
percent.totalBytesWritten = convertBytesToMb(res.totalBytesWritten) + " Mb"
percent.totalBytesExpectedToWrite = convertBytesToMb(res.totalBytesExpectedToWrite) + " Mb"
})
}
}
//关闭返回
function handleClose() {
hide()
}
function convertBytesToMb(bytes) {
const megabytes = bytes / (1024 * 1024) // 1 MB = 1024 * 1024 bytes
const roundedMb = Math.round(megabytes * 10) / 10 // 保留一位小数
return roundedMb
}
</script>
<style lang="scss" scoped>
.upgrade-popup {
width: 580rpx;
height: auto;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #fff;
border-radius: 20rpx;
box-sizing: border-box;
border: 1px solid #eee;
}
.header-bg {
width: 240rpx;
display: block;
margin: auto;
margin-bottom: 10px;
margin-top: -112rpx;
}
.main {
padding: 10rpx 30rpx 30rpx;
box-sizing: border-box;
.version {
font-size: 36rpx;
color: #026df7;
font-weight: 700;
width: 100%;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
letter-spacing: 1px;
}
.content {
margin-top: 60rpx;
.title {
font-size: 28rpx;
font-weight: 700;
color: #000000;
}
.desc {
box-sizing: border-box;
margin-top: 20rpx;
font-size: 28rpx;
color: #6a6a6a;
max-height: 80vh;
overflow-y: auto;
}
}
.progress {
width: 100%;
flex-shrink: 0;
margin: auto;
text-align: center;
margin-top: 20px;
}
.footer {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
flex-shrink: 0;
margin-top: 100rpx;
.btn {
width: 246rpx;
display: flex;
justify-content: center;
align-items: center;
position: relative;
z-index: 999;
height: 96rpx;
box-sizing: border-box;
font-size: 32rpx;
border-radius: 10rpx;
letter-spacing: 2rpx;
&.force {
width: 500rpx;
}
&.close {
border: 1px solid #e0e0e0;
margin-right: 25rpx;
color: #000;
}
&.upgrade {
background-color: #026df7;
color: white;
}
}
.progress-view {
width: 510rpx;
height: 90rpx;
display: flex;
position: relative;
align-items: center;
border-radius: 6rpx;
background-color: #dcdcdc;
display: flex;
justify-content: flex-start;
padding: 0px;
box-sizing: border-box;
border: none;
overflow: hidden;
&.active {
background-color: #026df7;
}
.progress {
height: 100%;
background-color: #026df7;
padding: 0px;
box-sizing: border-box;
border: none;
border-top-left-radius: 10rpx;
border-bottom-left-radius: 10rpx;
}
.txt {
font-size: 28rpx;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
}
}
}
}
</style>