✨ 支持版本更新检测
This commit is contained in:
parent
16f86e8024
commit
f5f46aeda3
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "easynode",
|
"name": "easynode",
|
||||||
"version": "2.0.0",
|
|
||||||
"description": "web ssh",
|
"description": "web ssh",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const jwt = require('jsonwebtoken')
|
const jwt = require('jsonwebtoken')
|
||||||
|
const axios = require('axios')
|
||||||
const { getNetIPInfo, readKey, writeKey, RSADecryptSync, AESEncryptSync, SHA1Encrypt, sendEmailToConfList, getNotifySwByType } = require('../utils')
|
const { getNetIPInfo, readKey, writeKey, RSADecryptSync, AESEncryptSync, SHA1Encrypt, sendEmailToConfList, getNotifySwByType } = require('../utils')
|
||||||
|
|
||||||
const getpublicKey = async ({ res }) => {
|
const getpublicKey = async ({ res }) => {
|
||||||
@ -112,9 +113,22 @@ const getLoginRecord = async ({ res }) => {
|
|||||||
res.success({ data: global.loginRecord, msg: 'success' })
|
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 = {
|
module.exports = {
|
||||||
login,
|
login,
|
||||||
getpublicKey,
|
getpublicKey,
|
||||||
updatePwd,
|
updatePwd,
|
||||||
getLoginRecord
|
getLoginRecord,
|
||||||
|
getEasynodeVersion
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,13 @@ function initNotifyDB() {
|
|||||||
'type': 'updatePwd',
|
'type': 'updatePwd',
|
||||||
'desc': '修改密码提醒',
|
'desc': '修改密码提醒',
|
||||||
'sw': true
|
'sw': true
|
||||||
},
|
}
|
||||||
{
|
// {
|
||||||
'type': 'host_offline',
|
// 'type': 'host_offline',
|
||||||
'desc': '客户端离线提醒(每小时最多发送一次提醒)',
|
// 'desc': '客户端离线提醒(每小时最多发送一次提醒)',
|
||||||
'sw': true
|
// 'sw': true
|
||||||
}]
|
// }
|
||||||
|
]
|
||||||
await writeNotifyList(defaultData)
|
await writeNotifyList(defaultData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const { getSSHList, addSSH, updateSSH, removeSSH, getCommand } = require('../controller/ssh')
|
const { getSSHList, addSSH, updateSSH, removeSSH, getCommand } = require('../controller/ssh')
|
||||||
const { getHostList, addHost, updateHost, removeHost, importHost } = require('../controller/host')
|
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 { getSupportEmailList, getUserEmailList, updateUserEmailList, removeUserEmail, pushEmail, getNotifyList, updateNotifyList } = require('../controller/notify')
|
||||||
const { getGroupList, addGroupList, updateGroupList, removeGroup } = require('../controller/group')
|
const { getGroupList, addGroupList, updateGroupList, removeGroup } = require('../controller/group')
|
||||||
const { getScriptList, getLocalScriptList, addScript, updateScriptList, removeScript } = require('../controller/scripts')
|
const { getScriptList, getLocalScriptList, addScript, updateScriptList, removeScript } = require('../controller/scripts')
|
||||||
@ -80,6 +80,11 @@ const user = [
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
path: '/get-login-record',
|
path: '/get-login-record',
|
||||||
controller: getLoginRecord
|
controller: getLoginRecord
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
path: '/version',
|
||||||
|
controller: getEasynodeVersion
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const notify = [
|
const notify = [
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "server",
|
"name": "server",
|
||||||
"version": "2.0.0",
|
|
||||||
"description": "easynode-server",
|
"description": "easynode-server",
|
||||||
"bin": "./bin/www",
|
"bin": "./bin/www",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "0.0.1",
|
"version": "2.1.1",
|
||||||
"description": "easynode-web",
|
"description": "easynode-web",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -108,5 +108,8 @@ export default {
|
|||||||
},
|
},
|
||||||
deleteOnekeyRecord(ids) {
|
deleteOnekeyRecord(ids) {
|
||||||
return axios({ url: '/onekey', method: 'post', data: { ids } })
|
return axios({ url: '/onekey', method: 'post', data: { ids } })
|
||||||
|
},
|
||||||
|
getEasynodeVersion() {
|
||||||
|
return axios({ url: '/version', method: 'get' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,3 +46,8 @@ html, body {
|
|||||||
// height: 100vh;
|
// height: 100vh;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@ -3,32 +3,76 @@
|
|||||||
<div class="bar_wrap">
|
<div class="bar_wrap">
|
||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
<!-- <el-icon><UserFilled /></el-icon> -->
|
<!-- <el-icon><UserFilled /></el-icon> -->
|
||||||
|
<el-button
|
||||||
<el-popover placement="bottom" trigger="hover">
|
type="info"
|
||||||
<template #reference>
|
class="about_btn top_text"
|
||||||
<div class="right_wrap">
|
link
|
||||||
<el-icon><User /></el-icon>
|
@click="visible = true"
|
||||||
<span>{{ user }}</span>
|
>
|
||||||
</div>
|
关于 <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>
|
</template>
|
||||||
<el-button
|
</el-dropdown>
|
||||||
type="primary"
|
|
||||||
class="logout_btn"
|
|
||||||
link
|
|
||||||
@click="handleLogout"
|
|
||||||
>
|
|
||||||
安全退出
|
|
||||||
</el-button>
|
|
||||||
</el-popover>
|
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance, computed } from 'vue'
|
import { ref, getCurrentInstance, computed } from 'vue'
|
||||||
import { User } from '@element-plus/icons-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(() => {
|
let user = computed(() => {
|
||||||
return $store.user
|
return $store.user
|
||||||
@ -61,19 +105,25 @@ const handleLogout = () => {
|
|||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
.right_wrap {
|
.username {
|
||||||
display: flex;
|
margin-left: 10px;
|
||||||
align-items: center;
|
cursor: pointer;
|
||||||
// color: red;
|
}
|
||||||
|
.top_text {
|
||||||
color: var(--el-menu-text-color);
|
color: var(--el-menu-text-color);
|
||||||
span {
|
font-size: 14px;
|
||||||
margin-left: 3px;
|
}
|
||||||
}
|
}
|
||||||
.logout_btn {
|
.about_content {
|
||||||
margin: 0 10px 0 15px;
|
h1 {
|
||||||
}
|
font-size: 18px;
|
||||||
// color: var(--el-button-text-color);
|
font-weight: 600;
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 35px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import router from './router'
|
|||||||
import tools from './plugins/tools'
|
import tools from './plugins/tools'
|
||||||
import elementPlugins from './plugins/element'
|
import elementPlugins from './plugins/element'
|
||||||
import globalComponents from './plugins/components'
|
import globalComponents from './plugins/components'
|
||||||
|
import axios from '@/utils/axios'
|
||||||
import api from './api'
|
import api from './api'
|
||||||
import App from './app.vue'
|
import App from './app.vue'
|
||||||
import './assets/scss/reset.scss'
|
import './assets/scss/reset.scss'
|
||||||
@ -20,6 +21,7 @@ app.use(router)
|
|||||||
|
|
||||||
app.config.globalProperties.$api = api
|
app.config.globalProperties.$api = api
|
||||||
app.config.globalProperties.$tools = tools
|
app.config.globalProperties.$tools = tools
|
||||||
|
app.config.globalProperties.$http = axios
|
||||||
app.config.globalProperties.$store = useStore()
|
app.config.globalProperties.$store = useStore()
|
||||||
|
|
||||||
const serviceURI = import.meta.env.DEV ? process.env.serviceURI : location.origin
|
const serviceURI = import.meta.env.DEV ? process.env.serviceURI : location.origin
|
||||||
|
@ -189,9 +189,5 @@ const handleRemoveHost = async ({ host }) => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--el-color-warning);;
|
color: var(--el-color-warning);;
|
||||||
}
|
}
|
||||||
.link {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
<!-- 提示 -->
|
<!-- 提示 -->
|
||||||
<el-alert type="success" :closable="false">
|
<el-alert type="success" :closable="false">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span style="letter-spacing: 2px;"> Tips: 系统所有通知邮件将会下发到所有已经配置成功的邮箱中 </span>
|
<span style="letter-spacing: 2px;"> 系统所有通知邮件将会下发到所有已经配置成功的邮箱中 </span>
|
||||||
</template>
|
</template>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-alert type="success" :closable="false">
|
<el-alert type="success" :closable="false">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span style="letter-spacing: 2px;"> Tips: 请添加邮箱并确保测试邮件通过 </span>
|
<span style="letter-spacing: 2px;"> 请添加邮箱并确保测试邮件通过 </span>
|
||||||
</template>
|
</template>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
<el-table v-loading="notifyListLoading" :data="notifyList">
|
<el-table v-loading="notifyListLoading" :data="notifyList">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-alert type="success" :closable="false">
|
<el-alert type="success" :closable="false">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span style="letter-spacing: 2px;"> Tips: 系统只保存最近10条登录记录, 目前版本只保存在内存中 </span>
|
<span style="letter-spacing: 2px;"> 系统只保存最近10条登录记录, 目前版本只保存在内存中 </span>
|
||||||
</template>
|
</template>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
<el-table v-loading="loading" :data="loginRecordList">
|
<el-table v-loading="loading" :data="loginRecordList">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user