有源标靶上位机
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

189 lines
5.8 KiB

import { useEffect, useState } from 'react'
import { Modal, Progress, Button, Space, Typography, notification } from 'antd'
import { DownloadOutlined, ReloadOutlined, CloseOutlined } from '@ant-design/icons'
import { IPC_EVENT } from '../../common/ipcEvents'
import styles from './AutoUpdater.module.css'
const { Title, Text } = Typography
function AutoUpdater() {
const [updateInfo, setUpdateInfo] = useState(null)
const [isModalVisible, setIsModalVisible] = useState(false)
const [updateStatus, setUpdateStatus] = useState('')
const [downloadProgress, setDownloadProgress] = useState(0)
const [isDownloading, setIsDownloading] = useState(false)
const [isDownloaded, setIsDownloaded] = useState(false)
useEffect(() => {
// 监听发现新版本
const handleUpdateAvailable = (event, info) => {
console.log('收到update-available事件:', info)
setUpdateInfo(info)
setUpdateStatus('发现新版本')
setIsModalVisible(true)
setIsDownloading(false)
setIsDownloaded(false)
setDownloadProgress(0)
}
// 监听下载进度
const handleDownloadProgress = (event, progressObj) => {
console.log('下载进度:', progressObj)
setDownloadProgress(Math.round(progressObj.percent))
setUpdateStatus(`正在下载新版本... ${Math.round(progressObj.percent)}%`)
}
// 监听下载完成
const handleUpdateDownloaded = () => {
console.log('下载完成')
setIsDownloading(false)
setIsDownloaded(true)
setUpdateStatus('新版本下载完成,准备安装')
notification.success({
message: '更新下载完成',
description: '新版本已下载完成,点击"立即安装"重启应用以完成更新',
duration: 5
})
}
// 监听更新错误
const handleUpdateError = (event, error) => {
console.error('更新错误:', error)
setIsDownloading(false)
setUpdateStatus(`更新失败: ${error}`)
notification.error({
message: '更新失败',
description: error,
duration: 5
})
}
// 注册监听器
window.electron.ipcRenderer.on(IPC_EVENT.UPDATE_AVAILABLE, handleUpdateAvailable)
window.electron.ipcRenderer.on(IPC_EVENT.DOWNLOAD_PROGRESS, handleDownloadProgress)
window.electron.ipcRenderer.on(IPC_EVENT.UPDATE_DOWNLOADED, handleUpdateDownloaded)
window.electron.ipcRenderer.on(IPC_EVENT.UPDATE_ERROR, handleUpdateError)
// 清理监听器
return () => {
window.electron.ipcRenderer.removeListener(IPC_EVENT.UPDATE_AVAILABLE, handleUpdateAvailable)
window.electron.ipcRenderer.removeListener(
IPC_EVENT.DOWNLOAD_PROGRESS,
handleDownloadProgress
)
window.electron.ipcRenderer.removeListener(
IPC_EVENT.UPDATE_DOWNLOADED,
handleUpdateDownloaded
)
window.electron.ipcRenderer.removeListener(IPC_EVENT.UPDATE_ERROR, handleUpdateError)
}
}, [])
// 开始下载
const handleDownload = async () => {
setIsDownloading(true)
setUpdateStatus('准备下载新版本...')
setDownloadProgress(0)
try {
await window.electron.ipcRenderer.invoke(IPC_EVENT.UPDATE_DOWNLOAD)
} catch (error) {
console.error('请求下载失败:', error)
setIsDownloading(false)
}
}
// 安装更新
const handleInstall = async () => {
try {
await window.electron.ipcRenderer.invoke(IPC_EVENT.UPDATE_INSTALL)
} catch (error) {
console.error('安装更新失败:', error)
}
}
// 取消更新
const handleCancel = () => {
setIsModalVisible(false)
setUpdateInfo(null)
setIsDownloading(false)
setIsDownloaded(false)
setDownloadProgress(0)
}
return (
<Modal
title={
<Space>
<DownloadOutlined />
<span>软件更新</span>
</Space>
}
open={isModalVisible}
onCancel={handleCancel}
footer={null}
width={480}
maskClosable={false}
>
<div className={styles.modalContent}>
{updateInfo && (
<div className={styles.versionInfo}>
<Title level={5} className={styles.versionTitle}>
发现新版本v{updateInfo.version}
</Title>
{updateInfo.releaseNotes && (
<div className={styles.releaseNotesSection}>
<Text type="secondary">更新说明</Text>
<div className={styles.releaseNotesContainer}>
<Text className={styles.releaseNotesText}>{updateInfo.releaseNotes}</Text>
</div>
</div>
)}
</div>
)}
<div className={styles.statusSection}>
<Text>{updateStatus}</Text>
</div>
{isDownloading && (
<div className={styles.progressSection}>
<Progress
percent={downloadProgress}
status="active"
strokeColor={{
'0%': '#108ee9',
'100%': '#87d068'
}}
format={(percent) => `${percent}%`}
/>
</div>
)}
<div className={styles.actionButtons}>
<Space>
<Button icon={<CloseOutlined />} onClick={handleCancel}>
{isDownloaded ? '稍后安装' : '取消'}
</Button>
{!isDownloaded && !isDownloading && (
<Button type="primary" icon={<DownloadOutlined />} onClick={handleDownload}>
立即下载
</Button>
)}
{isDownloaded && (
<Button
type="primary"
icon={<ReloadOutlined />}
onClick={handleInstall}
className={styles.installButton}
>
立即安装
</Button>
)}
</Space>
</div>
</div>
</Modal>
)
}
export default AutoUpdater