557 lines
13 KiB
Vue
557 lines
13 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="update-dialog-mask" v-if="show" @tap.stop="handleMaskClick">
|
|||
|
|
<view class="update-dialog-container" @tap.stop>
|
|||
|
|
<!-- 火箭图标 -->
|
|||
|
|
<view class="rocket-container">
|
|||
|
|
<view class="rocket-wrapper">
|
|||
|
|
<!-- 火箭 SVG 图片 -->
|
|||
|
|
<image class="rocket-svg" :src="rocketBase64" mode="aspectFit"></image>
|
|||
|
|
|
|||
|
|
<!-- 火焰效果 -->
|
|||
|
|
<view class="flame-container">
|
|||
|
|
<view class="flame flame-1"></view>
|
|||
|
|
<view class="flame flame-2"></view>
|
|||
|
|
<view class="flame flame-3"></view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 星星装饰 -->
|
|||
|
|
<view class="star star-1"></view>
|
|||
|
|
<view class="star star-2"></view>
|
|||
|
|
<view class="star star-3"></view>
|
|||
|
|
<view class="star star-4"></view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 内容区域 -->
|
|||
|
|
<view class="dialog-content">
|
|||
|
|
|
|||
|
|
<!-- 强制更新提示 -->
|
|||
|
|
<view class="force-notice" v-if="forceUpdate">
|
|||
|
|
<text class="force-notice-icon">⚠️</text>
|
|||
|
|
<text class="force-notice-text">本次为重要更新,需要立即升级</text>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 更新内容 -->
|
|||
|
|
<view class="update-content">
|
|||
|
|
<text class="update-item" v-for="(item, index) in updateList" :key="index">{{ index + 1 }}.{{ item }}</text>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 下载进度 -->
|
|||
|
|
<view class="progress-container" v-if="downloading">
|
|||
|
|
<view class="progress-bar">
|
|||
|
|
<view class="progress-fill" :style="{width: downloadProgress + '%'}"></view>
|
|||
|
|
</view>
|
|||
|
|
<text class="progress-text">{{ downloadProgress }}%</text>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 按钮 -->
|
|||
|
|
<view class="button-container" v-if="!downloading">
|
|||
|
|
<button class="update-button" @tap="handleUpdate">即刻升级</button>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 下载中按钮 -->
|
|||
|
|
<view class="button-container" v-else>
|
|||
|
|
<button class="update-button downloading">下载中...</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 关闭按钮 -->
|
|||
|
|
<view class="close-button" @tap="handleClose" v-if="!forceUpdate && !downloading">
|
|||
|
|
<text class="close-icon">×</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
export default {
|
|||
|
|
name: 'UpdateDialog',
|
|||
|
|
props: {
|
|||
|
|
show: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false
|
|||
|
|
},
|
|||
|
|
version: {
|
|||
|
|
type: String,
|
|||
|
|
default: ''
|
|||
|
|
},
|
|||
|
|
updateContent: {
|
|||
|
|
type: String,
|
|||
|
|
default: ''
|
|||
|
|
},
|
|||
|
|
downloadUrl: {
|
|||
|
|
type: String,
|
|||
|
|
default: ''
|
|||
|
|
},
|
|||
|
|
forceUpdate: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
downloading: false,
|
|||
|
|
downloadProgress: 0,
|
|||
|
|
downloadTask: null,
|
|||
|
|
// 火箭 SVG 的 base64 图片
|
|||
|
|
rocketBase64: 'data:image/svg+xml;base64,PHN2ZyB0PSIxNzYxODA0ODYyMzIwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIwNDAiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNMzk1LjI2NCAzMDQuMTI4Yy03MC42NTYgOTIuMTYtMTQ1LjQwOCAxOTQuNTYtMTg5LjQ0IDMwNC4xMjgtNS4xMiAxMi4yODggNi4xNDQgMjMuNTUyIDE4LjQzMiAyMC40OEwzNTguNCA1OTAuODQ4TTYyOC43MzYgMzA0LjEyOGM3MC42NTYgOTIuMTYgMTQ1LjQwOCAxOTQuNTYgMTg5LjQ0IDMwNC4xMjggNS4xMiAxMi4yODgtNi4xNDQgMjMuNTUyLTE4LjQzMiAyMC40OEw2NjUuNiA1OTAuODQ4IiBmaWxsPSIjRjc5ODM5IiBwLWlkPSIyMDQxIj48L3BhdGg+PHBhdGggZD0iTTY3Ni44NjQgNzExLjY4SDM0NS4wODhDMzE4LjQ2NCA2MjQuNjQgMzEyLjMyIDUzMi40OCAzMzEuNzc2IDQ0My4zOTJjMjIuNTI4LTEwMS4zNzYgNzAuNjU2LTE5Ny42MzIgMTQwLjI4OC0yNzcuNTA0bDcuMTY4LTguMTkyYzE2LjM4NC0xOS40NTYgNDYuMDgtMTkuNDU2IDYyLjQ2NCAwbDcuMTY4IDguMTkyYzcwLjY1NiA3OS44NzIgMTE3Ljc2IDE3Ni4xMjggMTQwLjI4OCAyNzcuNTA0IDIwLjQ4IDg5LjA4OCAxNC4zMzYgMTgxLjI0OC0xMi4yODggMjY4LjI4OHoiIGZpbGw9IiMwMDRGRkYiIHAtaWQ9IjIwNDIiPjwvcGF0aD48cGF0aCBkPSJNNDY3Ljk2OCA2NzUuODRjLTUxLjIgMC05NS4yMzItMzcuODg4LTEwMi40LTg4LjA2NC04LjE5Mi02MC40MTYtNi4xNDQtMTIwLjgzMiA2LjE0NC0xODAuMjI0IDIxLjUwNC05NS4yMzIgNjQuNTEyLTE4NS4zNDQgMTI2Ljk3Ni0yNjIuMTQ0LTguMTkyIDIuMDQ4LTE1LjM2IDYuMTQ0LTIwLjQ4IDEyLjI4OGwtNy4xNjggOC4xOTJDNDAyLjQzMiAyNDUuNzYgMzU0LjMwNCAzNDAuOTkyIDMzMS43NzYgNDQzLjM5MiAzMTIuMzIgNTMyLjQ4IDMxOC40NjQgNjI0LjY0IDM0NS4wODggNzExLjY4aDMzMS43NzZjNC4wOTYtMTIuMjg4IDcuMTY4LTIzLjU1MiAxMC4yNC0zNS44NEg0NjcuOTY4eiIgZmlsbD0iIzFENkZGRiIgcC1pZD0iMjA0MyI+PC9wYXRoPjxwYXRoIGQ9Ik0zODEuOTUyIDcyMS45MmgyMzYuNTQ0Vjc3OC4yNEgzODEuOTUyeiIgZmlsbD0iIzAwNEZGRiIgcC1pZD0iMjA0NCI+PC9wYXRoPjxwYXRoIGQ9Ik01MTQuNjk5Mjc2MjUgNDc0LjA2MzEyNjMxSDUwOC42MTAyMTEyM2wzLjA0NDUzMjUxIDIuODg3NTk3ODV6IiBmaWxsPSIjZmZmZmZmIiBwLWlkPSIyMDQ1Ij48L3BhdGg+PHBhdGggZD0iTTQzMC4wOCA0MjcuMDA4YTgwLjg5NiA3OS44NzIgMCAxIDAgMTYxLjc5MiAwIDgwLjg5NiA3OS44NzIgMCAxIDAgLTE2MS43OTIgMFoiIGZpbGw9IiNFOUYzRkIiIHAtaWQ9IjIwNDYiPjwvcGF0aD48L3N2Zz4='
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
computed: {
|
|||
|
|
updateList() {
|
|||
|
|
if (!this.updateContent) {
|
|||
|
|
return ['修复已知问题', '优化用户体验', '提升系统稳定性'];
|
|||
|
|
}
|
|||
|
|
// 将更新内容按换行或分号分割
|
|||
|
|
return this.updateContent.split(/[\n;;]/).filter(item => item.trim());
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
handleMaskClick() {
|
|||
|
|
if (!this.forceUpdate && !this.downloading) {
|
|||
|
|
this.handleClose();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
handleClose() {
|
|||
|
|
if (this.forceUpdate || this.downloading) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
this.$emit('close');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
handleUpdate() {
|
|||
|
|
// #ifdef APP-PLUS
|
|||
|
|
if (this.downloading) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!this.downloadUrl) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '下载地址无效',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.downloading = true;
|
|||
|
|
this.downloadProgress = 0;
|
|||
|
|
|
|||
|
|
// 创建下载任务
|
|||
|
|
const downloadTask = uni.downloadFile({
|
|||
|
|
url: this.downloadUrl.trim(),
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.statusCode === 200) {
|
|||
|
|
console.log('下载成功,文件路径:', res.tempFilePath);
|
|||
|
|
// 下载完成,安装应用
|
|||
|
|
this.installApp(res.tempFilePath);
|
|||
|
|
} else {
|
|||
|
|
console.error('下载失败,状态码:', res.statusCode);
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '下载失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
this.downloading = false;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('下载失败:', err);
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '下载失败,请稍后重试',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
this.downloading = false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 监听下载进度
|
|||
|
|
downloadTask.onProgressUpdate((res) => {
|
|||
|
|
this.downloadProgress = res.progress;
|
|||
|
|
console.log('下载进度:', res.progress + '%');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.downloadTask = downloadTask;
|
|||
|
|
// #endif
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
installApp(filePath) {
|
|||
|
|
// #ifdef APP-PLUS
|
|||
|
|
console.log('开始安装应用:', filePath);
|
|||
|
|
plus.runtime.install(
|
|||
|
|
filePath,
|
|||
|
|
{
|
|||
|
|
force: false
|
|||
|
|
},
|
|||
|
|
() => {
|
|||
|
|
console.log('安装成功');
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '安装成功,请重启应用',
|
|||
|
|
icon: 'success',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 安装成功后关闭弹窗
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.downloading = false;
|
|||
|
|
this.downloadProgress = 0;
|
|||
|
|
this.$emit('close');
|
|||
|
|
|
|||
|
|
// 如果是强制更新,重启应用
|
|||
|
|
if (this.forceUpdate) {
|
|||
|
|
plus.runtime.restart();
|
|||
|
|
}
|
|||
|
|
}, 2000);
|
|||
|
|
},
|
|||
|
|
(error) => {
|
|||
|
|
console.error('安装失败:', error);
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '安装失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
this.downloading = false;
|
|||
|
|
}
|
|||
|
|
);
|
|||
|
|
// #endif
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
beforeDestroy() {
|
|||
|
|
// 组件销毁时,取消下载任务
|
|||
|
|
if (this.downloadTask) {
|
|||
|
|
this.downloadTask.abort();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.update-dialog-mask {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
background: rgba(0, 0, 0, 0.6);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
z-index: 99999;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.update-dialog-container {
|
|||
|
|
width: 580rpx;
|
|||
|
|
background: linear-gradient(180deg, #4A9FF5 0%, #2E7FD9 100%);
|
|||
|
|
border-radius: 32rpx;
|
|||
|
|
position: relative;
|
|||
|
|
overflow: visible;
|
|||
|
|
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.rocket-container {
|
|||
|
|
position: absolute;
|
|||
|
|
top: -120rpx;
|
|||
|
|
left: 50%;
|
|||
|
|
transform: translateX(-50%);
|
|||
|
|
width: 200rpx;
|
|||
|
|
height: 200rpx;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.rocket-wrapper {
|
|||
|
|
position: relative;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
animation: rocketFloat 2s ease-in-out infinite;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 火箭 SVG 图片 */
|
|||
|
|
.rocket-svg {
|
|||
|
|
position: absolute;
|
|||
|
|
top: 10rpx;
|
|||
|
|
left: 50%;
|
|||
|
|
transform: translateX(-50%);
|
|||
|
|
width: 160rpx;
|
|||
|
|
height: 160rpx;
|
|||
|
|
z-index: 10;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 火焰容器 */
|
|||
|
|
.flame-container {
|
|||
|
|
position: absolute;
|
|||
|
|
bottom: 10rpx;
|
|||
|
|
left: 50%;
|
|||
|
|
transform: translateX(-50%);
|
|||
|
|
width: 60rpx;
|
|||
|
|
height: 80rpx;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
z-index: 5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 火焰效果 */
|
|||
|
|
.flame {
|
|||
|
|
position: absolute;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
animation: flameFlicker 0.3s ease-in-out infinite alternate;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flame-1 {
|
|||
|
|
width: 40rpx;
|
|||
|
|
height: 30rpx;
|
|||
|
|
background: radial-gradient(ellipse at center, #FCD34D 0%, #FBBF24 50%, transparent 80%);
|
|||
|
|
top: 0;
|
|||
|
|
animation-delay: 0s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flame-2 {
|
|||
|
|
width: 30rpx;
|
|||
|
|
height: 40rpx;
|
|||
|
|
background: radial-gradient(ellipse at center, #FBBF24 0%, #F59E0B 50%, transparent 80%);
|
|||
|
|
top: 15rpx;
|
|||
|
|
animation-delay: 0.1s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flame-3 {
|
|||
|
|
width: 20rpx;
|
|||
|
|
height: 35rpx;
|
|||
|
|
background: radial-gradient(ellipse at center, #F59E0B 0%, #EF4444 50%, transparent 80%);
|
|||
|
|
top: 30rpx;
|
|||
|
|
animation-delay: 0.2s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 星星装饰 */
|
|||
|
|
.star {
|
|||
|
|
position: absolute;
|
|||
|
|
width: 8rpx;
|
|||
|
|
height: 8rpx;
|
|||
|
|
background: #FCD34D;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
box-shadow: 0 0 10rpx #FCD34D;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.star-1 {
|
|||
|
|
top: 30rpx;
|
|||
|
|
left: 20rpx;
|
|||
|
|
animation: starTwinkle 2s ease-in-out infinite;
|
|||
|
|
animation-delay: 0s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.star-2 {
|
|||
|
|
top: 50rpx;
|
|||
|
|
right: 15rpx;
|
|||
|
|
animation: starTwinkle 2s ease-in-out infinite;
|
|||
|
|
animation-delay: 0.5s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.star-3 {
|
|||
|
|
top: 80rpx;
|
|||
|
|
left: 10rpx;
|
|||
|
|
animation: starTwinkle 1.5s ease-in-out infinite;
|
|||
|
|
animation-delay: 1s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.star-4 {
|
|||
|
|
top: 100rpx;
|
|||
|
|
right: 20rpx;
|
|||
|
|
animation: starTwinkle 1.5s ease-in-out infinite;
|
|||
|
|
animation-delay: 1.5s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 动画定义 */
|
|||
|
|
@keyframes rocketFloat {
|
|||
|
|
0%, 100% {
|
|||
|
|
transform: translateY(0);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
transform: translateY(-15rpx);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes flameFlicker {
|
|||
|
|
0% {
|
|||
|
|
opacity: 0.8;
|
|||
|
|
transform: scaleY(1);
|
|||
|
|
}
|
|||
|
|
100% {
|
|||
|
|
opacity: 1;
|
|||
|
|
transform: scaleY(1.2);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes starTwinkle {
|
|||
|
|
0%, 100% {
|
|||
|
|
opacity: 0.3;
|
|||
|
|
transform: scale(1);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
opacity: 1;
|
|||
|
|
transform: scale(1.5);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dialog-content {
|
|||
|
|
padding: 50rpx 40rpx 40rpx;
|
|||
|
|
background: #FFFFFF;
|
|||
|
|
border-radius: 32rpx;
|
|||
|
|
margin-top: 80rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dialog-title {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: #333333;
|
|||
|
|
text-align: center;
|
|||
|
|
margin-bottom: 40rpx;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.force-tag {
|
|||
|
|
display: inline-block;
|
|||
|
|
margin-top: 10rpx;
|
|||
|
|
padding: 4rpx 16rpx;
|
|||
|
|
background: linear-gradient(135deg, #FF6B6B 0%, #FF4757 100%);
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
font-weight: normal;
|
|||
|
|
animation: tagPulse 1.5s ease-in-out infinite;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes tagPulse {
|
|||
|
|
0%, 100% {
|
|||
|
|
transform: scale(1);
|
|||
|
|
box-shadow: 0 0 0 0 rgba(255, 71, 87, 0.7);
|
|||
|
|
}
|
|||
|
|
50% {
|
|||
|
|
transform: scale(1.05);
|
|||
|
|
box-shadow: 0 0 0 8rpx rgba(255, 71, 87, 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.force-notice {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
padding: 20rpx;
|
|||
|
|
margin-bottom: 24rpx;
|
|||
|
|
background: linear-gradient(135deg, #FFF5F5 0%, #FFE5E5 100%);
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
border: 2rpx solid #FFB8B8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.force-notice-icon {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
margin-right: 12rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.force-notice-text {
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
color: #FF4757;
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.update-content {
|
|||
|
|
background: #F8F9FA;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
padding: 30rpx;
|
|||
|
|
margin-bottom: 40rpx;
|
|||
|
|
max-height: 300rpx;
|
|||
|
|
overflow-y: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.update-item {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #666666;
|
|||
|
|
line-height: 44rpx;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
|
|||
|
|
&:last-child {
|
|||
|
|
margin-bottom: 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-container {
|
|||
|
|
margin-bottom: 40rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-bar {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 12rpx;
|
|||
|
|
background: #E5E7EB;
|
|||
|
|
border-radius: 6rpx;
|
|||
|
|
overflow: hidden;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-fill {
|
|||
|
|
height: 100%;
|
|||
|
|
background: linear-gradient(90deg, #4A9FF5 0%, #2E7FD9 100%);
|
|||
|
|
border-radius: 6rpx;
|
|||
|
|
transition: width 0.3s ease;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-text {
|
|||
|
|
display: block;
|
|||
|
|
text-align: center;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #4A9FF5;
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.button-container {
|
|||
|
|
width: 100%;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.update-button {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 88rpx;
|
|||
|
|
background: linear-gradient(135deg, #4A9FF5 0%, #2E7FD9 100%);
|
|||
|
|
border-radius: 44rpx;
|
|||
|
|
border: none;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
box-shadow: 0 8rpx 24rpx rgba(46, 127, 217, 0.4);
|
|||
|
|
|
|||
|
|
&.downloading {
|
|||
|
|
background: #CCCCCC;
|
|||
|
|
box-shadow: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
&::after {
|
|||
|
|
border: none;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.close-button {
|
|||
|
|
position: absolute;
|
|||
|
|
bottom: -120rpx;
|
|||
|
|
left: 50%;
|
|||
|
|
transform: translateX(-50%);
|
|||
|
|
width: 80rpx;
|
|||
|
|
height: 80rpx;
|
|||
|
|
background: rgba(255, 255, 255, 0.3);
|
|||
|
|
border-radius: 50%;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
border: 2rpx solid rgba(255, 255, 255, 0.6);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.close-icon {
|
|||
|
|
font-size: 60rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
line-height: 1;
|
|||
|
|
font-weight: 300;
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
|