支持版本更新检测

This commit is contained in:
chaos-zhu 2024-08-04 23:10:00 +08:00
parent 16f86e8024
commit f5f46aeda3
14 changed files with 121 additions and 47 deletions

View File

@ -1,6 +1,5 @@
{
"name": "easynode",
"version": "2.0.0",
"description": "web ssh",
"private": true,
"workspaces": [

View File

@ -1,4 +1,5 @@
const jwt = require('jsonwebtoken')
const axios = require('axios')
const { getNetIPInfo, readKey, writeKey, RSADecryptSync, AESEncryptSync, SHA1Encrypt, sendEmailToConfList, getNotifySwByType } = require('../utils')
const getpublicKey = async ({ res }) => {
@ -112,9 +113,22 @@ const getLoginRecord = async ({ res }) => {
res.success({ data: global.loginRecord, msg: 'success' })
}
const getEasynodeVersion = async ({ res }) => {
try {
// const { data } = await axios.get('https://api.github.com/repos/chaos-zhu/easynode/releases/latest')
const { data } = await axios.get('https://get-easynode-latest-version.chaoszhu.workers.dev/version')
console.log(data)
res.success({ data, msg: 'success' })
} catch (error) {
consola.error('Failed to fetch Easynode latest version:', error)
res.fail({ msg: 'Failed to fetch Easynode latest version' })
}
}
module.exports = {
login,
getpublicKey,
updatePwd,
getLoginRecord
getLoginRecord,
getEasynodeVersion
}

View File

@ -51,12 +51,13 @@ function initNotifyDB() {
'type': 'updatePwd',
'desc': '修改密码提醒',
'sw': true
},
{
'type': 'host_offline',
'desc': '客户端离线提醒(每小时最多发送一次提醒)',
'sw': true
}]
}
// {
// 'type': 'host_offline',
// 'desc': '客户端离线提醒(每小时最多发送一次提醒)',
// 'sw': true
// }
]
await writeNotifyList(defaultData)
}

View File

@ -1,6 +1,6 @@
const { getSSHList, addSSH, updateSSH, removeSSH, getCommand } = require('../controller/ssh')
const { getHostList, addHost, updateHost, removeHost, importHost } = require('../controller/host')
const { login, getpublicKey, updatePwd, getLoginRecord } = require('../controller/user')
const { login, getpublicKey, updatePwd, getLoginRecord, getEasynodeVersion } = require('../controller/user')
const { getSupportEmailList, getUserEmailList, updateUserEmailList, removeUserEmail, pushEmail, getNotifyList, updateNotifyList } = require('../controller/notify')
const { getGroupList, addGroupList, updateGroupList, removeGroup } = require('../controller/group')
const { getScriptList, getLocalScriptList, addScript, updateScriptList, removeScript } = require('../controller/scripts')
@ -80,6 +80,11 @@ const user = [
method: 'get',
path: '/get-login-record',
controller: getLoginRecord
},
{
method: 'get',
path: '/version',
controller: getEasynodeVersion
}
]
const notify = [

View File

@ -1,6 +1,5 @@
{
"name": "server",
"version": "2.0.0",
"description": "easynode-server",
"bin": "./bin/www",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "web",
"version": "0.0.1",
"version": "2.1.1",
"description": "easynode-web",
"private": true,
"scripts": {

View File

@ -108,5 +108,8 @@ export default {
},
deleteOnekeyRecord(ids) {
return axios({ url: '/onekey', method: 'post', data: { ids } })
},
getEasynodeVersion() {
return axios({ url: '/version', method: 'get' })
}
}

View File

@ -46,3 +46,8 @@ html, body {
// height: 100vh;
// overflow: hidden;
}
.link {
color: var(--el-color-primary);
cursor: pointer;
}

View File

@ -3,32 +3,76 @@
<div class="bar_wrap">
<h2>{{ title }}</h2>
<!-- <el-icon><UserFilled /></el-icon> -->
<el-popover placement="bottom" trigger="hover">
<template #reference>
<div class="right_wrap">
<el-icon><User /></el-icon>
<span>{{ user }}</span>
</div>
<el-button
type="info"
class="about_btn top_text"
link
@click="visible = true"
>
关于 <span class="link">{{ isNew ? `(新版本可用)` : '' }}</span>
</el-button>
<el-dropdown trigger="click">
<span class="username top_text"><el-icon><User /></el-icon> {{ user }}</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleLogout">
退出登录
</el-dropdown-item>
</el-dropdown-menu>
</template>
<el-button
type="primary"
class="logout_btn"
link
@click="handleLogout"
>
安全退出
</el-button>
</el-popover>
</el-dropdown>
</div>
<el-dialog
v-model="visible"
title="关于"
width="30%"
:append-to-body="false"
>
<div class="about_content">
<h1>EasyNode</h1>
<p>Version: {{ currentVersion }}</p>
<p v-if="isNew" style="text-decoration: underline;">
有新版本可用: {{ latestVersion }} - <a class="link" href="https://github.com/chaos-zhu/easynode/releases" target="_blank">https://github.com/chaos-zhu/easynode/releases</a>
</p>
<p>Author: <a class="link" href="https://github.com/chaos-zhu" target="_blank">ChaosZhu</a></p>
<p>Source: <a class="link" href="https://github.com/chaos-zhu/easynode" target="_blank">https://github.com/chaos-zhu/easynode</a></p>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { getCurrentInstance, computed } from 'vue'
import { ref, getCurrentInstance, computed } from 'vue'
import { User } from '@element-plus/icons-vue'
import packageJson from '../../package.json'
const { proxy: { $router, $store, $message } } = getCurrentInstance()
const { proxy: { $router, $store, $message, $http } } = getCurrentInstance()
let visible = ref(false)
let currentVersion = ref(`v${ packageJson.version }`)
let latestVersion = ref(null)
let isNew = computed(() => {
return latestVersion.value && latestVersion.value !== currentVersion.value
})
async function checkLatestVersion() {
try {
const response = await fetch('https://production.get-easynode-latest-version.chaoszhu.workers.dev/version')
// const response = await fetch('https://api.github.com/repos/chaos-zhu/easynode/releases/latest')
if (!response.ok) {
throw new Error('版本信息请求失败: ' + response.statusText)
}
const data = await response.json()
latestVersion.value = data.tag_name
} catch (error) {
console.error('版本信息请求失败:', error.message)
}
}
checkLatestVersion()
let user = computed(() => {
return $store.user
@ -61,19 +105,25 @@ const handleLogout = () => {
padding: 0 20px;
h2 {
font-size: 18px;
margin-right: auto;
}
.right_wrap {
display: flex;
align-items: center;
// color: red;
.username {
margin-left: 10px;
cursor: pointer;
}
.top_text {
color: var(--el-menu-text-color);
span {
margin-left: 3px;
}
.logout_btn {
margin: 0 10px 0 15px;
}
// color: var(--el-button-text-color);
font-size: 14px;
}
}
.about_content {
h1 {
font-size: 18px;
font-weight: 600;
margin: 15px 0;
}
p {
line-height: 35px;
}
}
}

View File

@ -5,6 +5,7 @@ import router from './router'
import tools from './plugins/tools'
import elementPlugins from './plugins/element'
import globalComponents from './plugins/components'
import axios from '@/utils/axios'
import api from './api'
import App from './app.vue'
import './assets/scss/reset.scss'
@ -20,6 +21,7 @@ app.use(router)
app.config.globalProperties.$api = api
app.config.globalProperties.$tools = tools
app.config.globalProperties.$http = axios
app.config.globalProperties.$store = useStore()
const serviceURI = import.meta.env.DEV ? process.env.serviceURI : location.origin

View File

@ -189,9 +189,5 @@ const handleRemoveHost = async ({ host }) => {
text-align: center;
color: var(--el-color-warning);;
}
.link {
color: var(--el-color-primary);
cursor: pointer;
}
}
</style>

View File

@ -53,7 +53,7 @@
<!-- 提示 -->
<el-alert type="success" :closable="false">
<template #title>
<span style="letter-spacing: 2px;"> Tips: 系统所有通知邮件将会下发到所有已经配置成功的邮箱中 </span>
<span style="letter-spacing: 2px;"> 系统所有通知邮件将会下发到所有已经配置成功的邮箱中 </span>
</template>
</el-alert>
<!-- 表格 -->

View File

@ -1,7 +1,7 @@
<template>
<el-alert type="success" :closable="false">
<template #title>
<span style="letter-spacing: 2px;"> Tips: 请添加邮箱并确保测试邮件通过 </span>
<span style="letter-spacing: 2px;"> 请添加邮箱并确保测试邮件通过 </span>
</template>
</el-alert>
<el-table v-loading="notifyListLoading" :data="notifyList">

View File

@ -1,7 +1,7 @@
<template>
<el-alert type="success" :closable="false">
<template #title>
<span style="letter-spacing: 2px;"> Tips: 系统只保存最近10条登录记录, 目前版本只保存在内存中 </span>
<span style="letter-spacing: 2px;"> 系统只保存最近10条登录记录, 目前版本只保存在内存中 </span>
</template>
</el-alert>
<el-table v-loading="loading" :data="loginRecordList">