♻️ 重构通知模块
This commit is contained in:
parent
ee63a53d6e
commit
1bdb620617
@ -11,10 +11,10 @@ module.exports = {
|
||||
credentialsDBPath: path.join(process.cwd(),'app/db/credentials.db'),
|
||||
keyDBPath: path.join(process.cwd(),'app/db/key.db'),
|
||||
hostListDBPath: path.join(process.cwd(),'app/db/host.db'),
|
||||
notifyConfDBPath: path.join(process.cwd(),'app/db/notify.db'),
|
||||
groupConfDBPath: path.join(process.cwd(),'app/db/group.db'),
|
||||
emailNotifyDBPath: path.join(process.cwd(),'app/db/email.db'),
|
||||
scriptsDBPath: path.join(process.cwd(),'app/db/scripts.db'),
|
||||
notifyDBPath: path.join(process.cwd(),'app/db/notify.db'),
|
||||
notifyConfigDBPath: path.join(process.cwd(),'app/db/notify-config.db'),
|
||||
onekeyDBPath: path.join(process.cwd(),'app/db/onekey.db'),
|
||||
apiPrefix: '/api/v1',
|
||||
logConfig: {
|
||||
|
@ -1,64 +1,16 @@
|
||||
const {
|
||||
readSupportEmailList,
|
||||
readUserEmailList,
|
||||
writeUserEmailList,
|
||||
emailTransporter,
|
||||
readNotifyList,
|
||||
writeNotifyList } = require('../utils')
|
||||
const commonTemp = require('../template/commonTemp')
|
||||
const { readNotifyConfig, writeNotifyConfig, readNotifyList, writeNotifyList } = require('../utils')
|
||||
// const commonTemp = require('../template/commonTemp')
|
||||
|
||||
async function getSupportEmailList({ res }) {
|
||||
const data = await readSupportEmailList()
|
||||
res.success({ data })
|
||||
async function getNotifyConfig({ res }) {
|
||||
const data = await readNotifyConfig()
|
||||
return res.success({ data })
|
||||
}
|
||||
|
||||
async function getUserEmailList({ res }) {
|
||||
const userEmailList = (await readUserEmailList()).map(({ target, auth: { user } }) => ({ target, user }))
|
||||
const supportEmailList = await readSupportEmailList()
|
||||
const data = userEmailList.map(({ target: userTarget, user: email }) => {
|
||||
let name = supportEmailList.find(({ target: supportTarget }) => supportTarget === userTarget).name
|
||||
return { name, email }
|
||||
})
|
||||
res.success({ data })
|
||||
}
|
||||
|
||||
async function pushEmail({ res, request }) {
|
||||
let { body: { toEmail, isTest } } = request
|
||||
if (!isTest) return res.fail({ msg: '此接口暂时只做测试邮件使用, 需传递参数isTest: true' })
|
||||
consola.info('发送测试邮件:', toEmail)
|
||||
let { code, msg } = await emailTransporter({ toEmail, title: '测试邮件', html: commonTemp('邮件通知测试邮件') })
|
||||
msg = msg && msg.message || msg
|
||||
if (code === 0) return res.success({ msg })
|
||||
return res.fail({ msg })
|
||||
}
|
||||
|
||||
async function updateUserEmailList({ res, request }) {
|
||||
let { body: { target, auth } } = request
|
||||
const supportList = await readSupportEmailList()
|
||||
let flag = supportList.some((item) => item.target === target)
|
||||
if (!flag) return res.fail({ msg: `不支持的邮箱类型:${ target }` })
|
||||
if (!auth.user || !auth.pass) return res.fail({ msg: 'missing params: auth.' })
|
||||
|
||||
let newUserEmail = { target, auth }
|
||||
let userEmailList = await readUserEmailList()
|
||||
let idx = userEmailList.findIndex(({ auth: { user } }) => auth.user === user)
|
||||
if (idx !== -1) userEmailList.splice(idx, 1, newUserEmail)
|
||||
else userEmailList.unshift(newUserEmail)
|
||||
|
||||
const { code, msg } = await writeUserEmailList(userEmailList)
|
||||
if (code === 0) return res.success()
|
||||
return res.fail({ msg })
|
||||
}
|
||||
|
||||
async function removeUserEmail({ res, request }) {
|
||||
let { params: { email } } = request
|
||||
const userEmailList = await readUserEmailList()
|
||||
let idx = userEmailList.findIndex(({ auth: { user } }) => user === email)
|
||||
if (idx === -1) return res.fail({ msg: `删除失败, 不存在该邮箱:${ email }` })
|
||||
userEmailList.splice(idx, 1)
|
||||
const { code, msg } = await writeUserEmailList(userEmailList)
|
||||
if (code === 0) return res.success()
|
||||
return res.fail({ msg })
|
||||
// 根据type待编写测试方法,测试通过才保存到库
|
||||
async function updateNotifyConfig({ res, request }) {
|
||||
let { body: { noticeConfig } } = request
|
||||
await writeNotifyConfig(noticeConfig)
|
||||
return res.success()
|
||||
}
|
||||
|
||||
async function getNotifyList({ res }) {
|
||||
@ -73,17 +25,13 @@ async function updateNotifyList({ res, request }) {
|
||||
let target = notifyList.find((item) => item.type === type)
|
||||
if (!target) return res.fail({ msg: `更新失败, 不存在该通知类型:${ type }` })
|
||||
target.sw = sw
|
||||
// console.log(notifyList)
|
||||
await writeNotifyList(notifyList)
|
||||
res.success()
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
pushEmail,
|
||||
getSupportEmailList,
|
||||
getUserEmailList,
|
||||
updateUserEmailList,
|
||||
removeUserEmail,
|
||||
getNotifyConfig,
|
||||
updateNotifyConfig,
|
||||
getNotifyList,
|
||||
updateNotifyList
|
||||
}
|
||||
|
144
server/app/db.js
144
server/app/db.js
@ -1,6 +1,5 @@
|
||||
const { writeKey, writeNotifyList, writeGroupList } = require('./utils/storage')
|
||||
const { KeyDB, NotifyDB, GroupDB, EmailNotifyDB } = require('./utils/db-class')
|
||||
const { readScriptList, writeScriptList } = require('./utils')
|
||||
const { writeKey, writeGroupList, writeNotifyList, writeNotifyConfig } = require('./utils/storage')
|
||||
const { KeyDB, GroupDB, NotifyDB, NotifyConfigDB } = require('./utils/db-class')
|
||||
|
||||
function initKeyDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -27,6 +26,25 @@ function initKeyDB() {
|
||||
})
|
||||
}
|
||||
|
||||
function initGroupDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const groupDB = new GroupDB().getInstance()
|
||||
groupDB.count({}, async (err, count) => {
|
||||
if (err) {
|
||||
consola.log('初始化groupDB错误:', err)
|
||||
reject(err)
|
||||
} else {
|
||||
if (count === 0) {
|
||||
consola.log('初始化groupDB✔')
|
||||
const defaultData = [{ '_id': 'default', 'name': '默认分组', 'index': 0 }]
|
||||
await writeGroupList(defaultData)
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function initNotifyDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const notifyDB = new NotifyDB().getInstance()
|
||||
@ -67,18 +85,28 @@ function initNotifyDB() {
|
||||
})
|
||||
}
|
||||
|
||||
function initGroupDB() {
|
||||
function initNotifyConfigDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const groupDB = new GroupDB().getInstance()
|
||||
groupDB.count({}, async (err, count) => {
|
||||
const notifyConfigDB = new NotifyConfigDB().getInstance()
|
||||
notifyConfigDB.count({}, async (err, count) => {
|
||||
if (err) {
|
||||
consola.log('初始化groupDB错误:', err)
|
||||
consola.log('初始化NotifyConfigDB错误:', err)
|
||||
reject(err)
|
||||
} else {
|
||||
if (count === 0) {
|
||||
consola.log('初始化groupDB✔')
|
||||
const defaultData = [{ '_id': 'default', 'name': '默认分组', 'index': 0 }]
|
||||
await writeGroupList(defaultData)
|
||||
consola.log('初始化NotifyConfigDB✔')
|
||||
const defaultData = {
|
||||
type: 'sct',
|
||||
sct: {
|
||||
sendKey: ''
|
||||
},
|
||||
email: {
|
||||
service: 'QQ',
|
||||
user: '',
|
||||
pass: ''
|
||||
}
|
||||
}
|
||||
await writeNotifyConfig(defaultData)
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
@ -86,103 +114,9 @@ function initGroupDB() {
|
||||
})
|
||||
}
|
||||
|
||||
function initEmailNotifyDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const emailNotifyDB = new EmailNotifyDB().getInstance()
|
||||
emailNotifyDB.count({}, async (err, count) => {
|
||||
if (err) {
|
||||
consola.log('初始化emailNotifyDB错误:', err)
|
||||
reject(err)
|
||||
} else {
|
||||
if (count === 0) {
|
||||
consola.log('初始化emailNotifyDB✔')
|
||||
const defaultData = {
|
||||
'support': [
|
||||
{
|
||||
'name': 'QQ邮箱',
|
||||
'target': 'qq',
|
||||
'host': 'smtp.qq.com',
|
||||
'port': 465,
|
||||
'secure': true,
|
||||
'tls': {
|
||||
'rejectUnauthorized': false
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': '网易126',
|
||||
'target': 'wangyi126',
|
||||
'host': 'smtp.126.com',
|
||||
'port': 465,
|
||||
'secure': true,
|
||||
'tls': {
|
||||
'rejectUnauthorized': false
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': '网易163',
|
||||
'target': 'wangyi163',
|
||||
'host': 'smtp.163.com',
|
||||
'port': 465,
|
||||
'secure': true,
|
||||
'tls': {
|
||||
'rejectUnauthorized': false
|
||||
}
|
||||
}
|
||||
],
|
||||
'user': [
|
||||
]
|
||||
}
|
||||
emailNotifyDB.update({}, { $set: defaultData }, { upsert: true }, (err, numReplaced) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
emailNotifyDB.compactDatafile()
|
||||
resolve(numReplaced)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function initScriptsDB() {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve) => {
|
||||
let scriptList = await readScriptList()
|
||||
let clientInstallScript = 'curl -o- https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/main/client/easynode-client-install.sh | bash'
|
||||
let clientUninstallScript = 'curl -o- https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/main/client/easynode-client-uninstall.sh | bash'
|
||||
let installId = 'clientInstall'
|
||||
let uninstallId = 'clientUninstall'
|
||||
|
||||
let isClientInstall = scriptList?.find(script => script._id = installId)
|
||||
let isClientUninstall = scriptList?.find(script => script._id = uninstallId)
|
||||
let writeFlag = false
|
||||
if (!isClientInstall) {
|
||||
console.info('初始化客户端安装脚本')
|
||||
scriptList.push({ _id: installId, name: 'easynode-客户端-安装脚本', description: '系统内置|重启生成', command: clientInstallScript, index: 1 })
|
||||
writeFlag = true
|
||||
} else {
|
||||
console.info('客户端安装脚本已存在')
|
||||
}
|
||||
if (!isClientUninstall) {
|
||||
console.info('初始化客户端卸载脚本')
|
||||
scriptList.push({ _id: uninstallId, name: 'easynode-客户端-卸载脚本', description: '系统内置|重启生成', command: clientUninstallScript, index: 0 })
|
||||
writeFlag = true
|
||||
} else {
|
||||
console.info('客户端卸载脚本已存在')
|
||||
}
|
||||
if (writeFlag) await writeScriptList(scriptList)
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = async () => {
|
||||
await initKeyDB()
|
||||
await initNotifyDB()
|
||||
await initGroupDB()
|
||||
await initEmailNotifyDB()
|
||||
// await initScriptsDB()
|
||||
await initNotifyConfigDB()
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
const { getSSHList, addSSH, updateSSH, removeSSH, getCommand } = require('../controller/ssh')
|
||||
const { getHostList, addHost, updateHost, removeHost, importHost } = require('../controller/host')
|
||||
const { login, getpublicKey, updatePwd, getLoginRecord, getEasynodeVersion } = require('../controller/user')
|
||||
const { getSupportEmailList, getUserEmailList, updateUserEmailList, removeUserEmail, pushEmail, getNotifyList, updateNotifyList } = require('../controller/notify')
|
||||
const { getNotifyConfig, updateNotifyConfig, getNotifyList, updateNotifyList } = require('../controller/notify')
|
||||
const { getGroupList, addGroupList, updateGroupList, removeGroup } = require('../controller/group')
|
||||
const { getScriptList, getLocalScriptList, addScript, updateScriptList, removeScript } = require('../controller/scripts')
|
||||
const { getOnekeyRecord, removeOnekeyRecord } = require('../controller/onekey')
|
||||
@ -90,28 +90,13 @@ const user = [
|
||||
const notify = [
|
||||
{
|
||||
method: 'get',
|
||||
path: '/support-email',
|
||||
controller: getSupportEmailList
|
||||
path: '/notify-config',
|
||||
controller: getNotifyConfig
|
||||
},
|
||||
{
|
||||
method: 'get',
|
||||
path: '/user-email',
|
||||
controller: getUserEmailList
|
||||
},
|
||||
{
|
||||
method: 'post',
|
||||
path: '/user-email',
|
||||
controller: updateUserEmailList
|
||||
},
|
||||
{
|
||||
method: 'post',
|
||||
path: '/push-email',
|
||||
controller: pushEmail
|
||||
},
|
||||
{
|
||||
method: 'delete',
|
||||
path: '/user-email/:email',
|
||||
controller: removeUserEmail
|
||||
method: 'put',
|
||||
path: '/notify-config',
|
||||
controller: updateNotifyConfig
|
||||
},
|
||||
{
|
||||
method: 'get',
|
||||
|
@ -1,5 +1,14 @@
|
||||
const Datastore = require('@seald-io/nedb')
|
||||
const { credentialsDBPath, hostListDBPath, keyDBPath, emailNotifyDBPath, notifyConfDBPath, groupConfDBPath, scriptsDBPath, onekeyDBPath } = require('../config')
|
||||
const {
|
||||
credentialsDBPath,
|
||||
hostListDBPath,
|
||||
keyDBPath,
|
||||
notifyDBPath,
|
||||
notifyConfigDBPath,
|
||||
groupConfDBPath,
|
||||
scriptsDBPath,
|
||||
onekeyDBPath
|
||||
} = require('../config')
|
||||
|
||||
module.exports.KeyDB = class KeyDB {
|
||||
constructor() {
|
||||
@ -37,7 +46,7 @@ module.exports.SshRecordDB = class SshRecordDB {
|
||||
module.exports.NotifyDB = class NotifyDB {
|
||||
constructor() {
|
||||
if (!NotifyDB.instance) {
|
||||
NotifyDB.instance = new Datastore({ filename: notifyConfDBPath, autoload: true })
|
||||
NotifyDB.instance = new Datastore({ filename: notifyDBPath, autoload: true })
|
||||
}
|
||||
}
|
||||
getInstance() {
|
||||
@ -45,6 +54,17 @@ module.exports.NotifyDB = class NotifyDB {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.NotifyConfigDB = class NotifyConfigDB {
|
||||
constructor() {
|
||||
if (!NotifyConfigDB.instance) {
|
||||
NotifyConfigDB.instance = new Datastore({ filename: notifyConfigDBPath, autoload: true })
|
||||
}
|
||||
}
|
||||
getInstance() {
|
||||
return NotifyConfigDB.instance
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.GroupDB = class GroupDB {
|
||||
constructor() {
|
||||
if (!GroupDB.instance) {
|
||||
@ -56,17 +76,6 @@ module.exports.GroupDB = class GroupDB {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.EmailNotifyDB = class EmailNotifyDB {
|
||||
constructor() {
|
||||
if (!EmailNotifyDB.instance) {
|
||||
EmailNotifyDB.instance = new Datastore({ filename: emailNotifyDBPath, autoload: true })
|
||||
}
|
||||
}
|
||||
getInstance() {
|
||||
return EmailNotifyDB.instance
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.ScriptsDB = class ScriptsDB {
|
||||
constructor() {
|
||||
if (!ScriptsDB.instance) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
// :TODO: 重写
|
||||
const nodemailer = require('nodemailer')
|
||||
const { readSupportEmailList, readUserEmailList } = require('./storage')
|
||||
const commonTemp = require('../template/commonTemp')
|
||||
|
@ -5,19 +5,18 @@ const {
|
||||
writeHostList,
|
||||
readKey,
|
||||
writeKey,
|
||||
readSupportEmailList,
|
||||
readUserEmailList,
|
||||
writeUserEmailList,
|
||||
readNotifyList,
|
||||
getNotifySwByType,
|
||||
writeNotifyList,
|
||||
readGroupList,
|
||||
writeGroupList,
|
||||
readScriptList,
|
||||
writeScriptList,
|
||||
readOneKeyRecord,
|
||||
writeOneKeyRecord,
|
||||
deleteOneKeyRecord
|
||||
deleteOneKeyRecord,
|
||||
readNotifyConfig,
|
||||
writeNotifyConfig,
|
||||
getNotifySwByType,
|
||||
readNotifyList,
|
||||
writeNotifyList
|
||||
} = require('./storage')
|
||||
const { RSADecryptSync, AESEncryptSync, AESDecryptSync, SHA1Encrypt } = require('./encrypt')
|
||||
const { verifyAuthSync, isProd } = require('./verify-auth')
|
||||
@ -44,19 +43,18 @@ module.exports = {
|
||||
writeHostList,
|
||||
readKey,
|
||||
writeKey,
|
||||
readSupportEmailList,
|
||||
readUserEmailList,
|
||||
writeUserEmailList,
|
||||
emailTransporter,
|
||||
sendEmailToConfList,
|
||||
readNotifyList,
|
||||
getNotifySwByType,
|
||||
writeNotifyList,
|
||||
readGroupList,
|
||||
writeGroupList,
|
||||
readScriptList,
|
||||
writeScriptList,
|
||||
readOneKeyRecord,
|
||||
writeOneKeyRecord,
|
||||
deleteOneKeyRecord
|
||||
deleteOneKeyRecord,
|
||||
readNotifyConfig,
|
||||
writeNotifyConfig,
|
||||
getNotifySwByType,
|
||||
readNotifyList,
|
||||
writeNotifyList
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { KeyDB, HostListDB, SshRecordDB, NotifyDB, GroupDB, EmailNotifyDB, ScriptsDB, OnekeyDB } = require('./db-class')
|
||||
const { KeyDB, HostListDB, SshRecordDB, NotifyDB, NotifyConfigDB, ScriptsDB, GroupDB, OnekeyDB } = require('./db-class')
|
||||
|
||||
const readKey = async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -102,56 +102,33 @@ const writeHostList = async (record = []) => {
|
||||
})
|
||||
}
|
||||
|
||||
const readEmailNotifyConf = () => {
|
||||
const readNotifyConfig = async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const emailNotifyDB = new EmailNotifyDB().getInstance()
|
||||
emailNotifyDB.findOne({}, (err, docs) => {
|
||||
const notifyConfigDB = new NotifyConfigDB().getInstance()
|
||||
notifyConfigDB.findOne({}, (err, doc) => {
|
||||
if (err) {
|
||||
consola.error('读取email-notify-conf-db错误:', err)
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(docs)
|
||||
resolve(doc)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
const writeUserEmailList = (user) => {
|
||||
const emailNotifyDB = new EmailNotifyDB().getInstance()
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let support = await readSupportEmailList()
|
||||
const emailConf = { support, user }
|
||||
emailNotifyDB.update({}, { $set: emailConf }, { upsert: true }, (err) => {
|
||||
|
||||
const writeNotifyConfig = async (keyObj = {}) => {
|
||||
const notifyConfigDB = new NotifyConfigDB().getInstance()
|
||||
return new Promise((resolve, reject) => {
|
||||
notifyConfigDB.update({}, { $set: keyObj }, { upsert: true }, (err, numReplaced) => {
|
||||
if (err) {
|
||||
reject({ code: -1, msg: err.message || err })
|
||||
reject(err)
|
||||
} else {
|
||||
emailNotifyDB.compactDatafile()
|
||||
resolve({ code: 0 })
|
||||
notifyConfigDB.compactDatafile()
|
||||
resolve(numReplaced)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const readSupportEmailList = async () => {
|
||||
let support = []
|
||||
try {
|
||||
support = (await readEmailNotifyConf()).support
|
||||
} catch (error) {
|
||||
consola.error('读取email support错误: ', error)
|
||||
}
|
||||
return support
|
||||
}
|
||||
|
||||
const readUserEmailList = async () => {
|
||||
let user = []
|
||||
try {
|
||||
user = (await readEmailNotifyConf()).user
|
||||
} catch (error) {
|
||||
consola.error('读取email config错误: ', error)
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
const getNotifySwByType = async (type) => {
|
||||
if (!type) throw Error('missing params: type')
|
||||
try {
|
||||
@ -283,6 +260,7 @@ const readOneKeyRecord = async () => {
|
||||
consola.error('读取onekey record错误: ', err)
|
||||
reject(err)
|
||||
} else {
|
||||
onekeyDB.compactDatafile()
|
||||
resolve(docs)
|
||||
}
|
||||
})
|
||||
@ -319,23 +297,12 @@ const deleteOneKeyRecord = async (ids =[]) => {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
readSSHRecord,
|
||||
writeSSHRecord,
|
||||
readHostList,
|
||||
writeHostList,
|
||||
readKey,
|
||||
writeKey,
|
||||
readNotifyList,
|
||||
getNotifySwByType,
|
||||
writeNotifyList,
|
||||
readGroupList,
|
||||
writeGroupList,
|
||||
readSupportEmailList,
|
||||
readUserEmailList,
|
||||
writeUserEmailList,
|
||||
readScriptList,
|
||||
writeScriptList,
|
||||
readOneKeyRecord,
|
||||
writeOneKeyRecord,
|
||||
deleteOneKeyRecord
|
||||
readSSHRecord, writeSSHRecord,
|
||||
readHostList, writeHostList,
|
||||
readKey, writeKey,
|
||||
readNotifyList, writeNotifyList,
|
||||
readNotifyConfig, writeNotifyConfig, getNotifySwByType,
|
||||
readGroupList, writeGroupList,
|
||||
readScriptList, writeScriptList,
|
||||
readOneKeyRecord, writeOneKeyRecord, deleteOneKeyRecord
|
||||
}
|
@ -55,20 +55,26 @@ export default {
|
||||
// updateHostSort(data) {
|
||||
// return axios({ url: '/host-sort', method: 'put', data })
|
||||
// },
|
||||
getUserEmailList() {
|
||||
return axios({ url: '/user-email', method: 'get' })
|
||||
// getUserEmailList() {
|
||||
// return axios({ url: '/user-email', method: 'get' })
|
||||
// },
|
||||
// getSupportEmailList() {
|
||||
// return axios({ url: '/support-email', method: 'get' })
|
||||
// },
|
||||
// updateUserEmailList(data) {
|
||||
// return axios({ url: '/user-email', method: 'post', data })
|
||||
// },
|
||||
// deleteUserEmail(email) {
|
||||
// return axios({ url: `/user-email/${ email }`, method: 'delete' })
|
||||
// },
|
||||
// pushTestEmail(data) {
|
||||
// return axios({ url: '/push-email', method: 'post', data })
|
||||
// },
|
||||
getNotifyConfig() {
|
||||
return axios({ url: '/notify-config', method: 'get' })
|
||||
},
|
||||
getSupportEmailList() {
|
||||
return axios({ url: '/support-email', method: 'get' })
|
||||
},
|
||||
updateUserEmailList(data) {
|
||||
return axios({ url: '/user-email', method: 'post', data })
|
||||
},
|
||||
deleteUserEmail(email) {
|
||||
return axios({ url: `/user-email/${ email }`, method: 'delete' })
|
||||
},
|
||||
pushTestEmail(data) {
|
||||
return axios({ url: '/push-email', method: 'post', data })
|
||||
updateNotifyConfig(data) {
|
||||
return axios({ url: '/notify-config', method: 'put', data })
|
||||
},
|
||||
getNotifyList() {
|
||||
return axios({ url: '/notify', method: 'get' })
|
||||
|
@ -1,185 +0,0 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-form
|
||||
ref="emailFormRef"
|
||||
:model="emailForm"
|
||||
:rules="rules"
|
||||
:inline="true"
|
||||
:hide-required-asterisk="true"
|
||||
label-suffix=":"
|
||||
>
|
||||
<el-form-item label="" prop="target" style="width: 200px;">
|
||||
<el-select
|
||||
v-model="emailForm.target"
|
||||
placeholder="邮件服务商"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in supportEmailList"
|
||||
:key="item.target"
|
||||
:label="item.name"
|
||||
:value="item.target"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="auth.user" style="width: 200px;">
|
||||
<el-input
|
||||
v-model.trim="emailForm.auth.user"
|
||||
clearable
|
||||
placeholder="邮箱"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="auth.pass" style="width: 200px;">
|
||||
<el-input
|
||||
v-model.trim="emailForm.auth.pass"
|
||||
clearable
|
||||
placeholder="SMTP授权码"
|
||||
autocomplete="off"
|
||||
@keyup.enter="addEmail"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="重复添加的邮箱将会被覆盖"
|
||||
placement="right"
|
||||
>
|
||||
<el-button type="primary" @click="addEmail">
|
||||
添加
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 提示 -->
|
||||
<el-alert type="success" :closable="false">
|
||||
<template #title>
|
||||
<span style="letter-spacing: 2px;"> 系统所有通知邮件将会下发到所有已经配置成功的邮箱中 </span>
|
||||
</template>
|
||||
</el-alert>
|
||||
<!-- 表格 -->
|
||||
<el-table :data="userEmailList" class="table">
|
||||
<el-table-column prop="email" label="Email" />
|
||||
<el-table-column prop="name" label="服务商" />
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="row.loading"
|
||||
@click="pushTestEmail(row)"
|
||||
>
|
||||
测试
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
@click="deleteUserEmail(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
const { proxy: { $api, $message, $messageBox, $notification } } = getCurrentInstance()
|
||||
|
||||
const loading = ref(false)
|
||||
const userEmailList = ref([])
|
||||
const supportEmailList = ref([])
|
||||
const emailFormRef = ref(null)
|
||||
|
||||
const emailForm = reactive({
|
||||
target: 'qq',
|
||||
auth: {
|
||||
user: '',
|
||||
pass: ''
|
||||
}
|
||||
})
|
||||
|
||||
const rules = reactive({
|
||||
'auth.user': { required: true, type: 'email', message: '需输入邮箱', trigger: 'change' },
|
||||
'auth.pass': { required: true, message: '需输入SMTP授权码', trigger: 'change' }
|
||||
})
|
||||
|
||||
const getUserEmailList = () => {
|
||||
loading.value = true
|
||||
$api.getUserEmailList()
|
||||
.then(({ data }) => {
|
||||
userEmailList.value = data.map(item => {
|
||||
item.loading = false
|
||||
return item
|
||||
})
|
||||
})
|
||||
.finally(() => loading.value = false)
|
||||
}
|
||||
|
||||
const getSupportEmailList = () => {
|
||||
$api.getSupportEmailList()
|
||||
.then(({ data }) => {
|
||||
supportEmailList.value = data
|
||||
})
|
||||
}
|
||||
|
||||
const addEmail = () => {
|
||||
emailFormRef.value.validate()
|
||||
.then(() => {
|
||||
$api.updateUserEmailList({ ...emailForm })
|
||||
.then(() => {
|
||||
$message.success('添加成功, 点击[测试]按钮发送测试邮件')
|
||||
let { target } = emailForm
|
||||
emailForm.target = target
|
||||
emailForm.auth.user = ''
|
||||
emailForm.auth.pass = ''
|
||||
getUserEmailList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const pushTestEmail = (row) => {
|
||||
row.loading = true
|
||||
const { email: toEmail } = row
|
||||
$api.pushTestEmail({ isTest: true, toEmail })
|
||||
.then(() => {
|
||||
$message.success(`发送成功, 请检查邮箱: ${ toEmail }`)
|
||||
})
|
||||
.catch((error) => {
|
||||
$notification({
|
||||
title: '发送测试邮件失败, 请检查邮箱SMTP配置',
|
||||
message: error.response?.data.msg,
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
row.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const deleteUserEmail = ({ email }) => {
|
||||
$messageBox.confirm(
|
||||
`确认删除邮箱:${ email }`,
|
||||
'Warning',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
await $api.deleteUserEmail(email)
|
||||
$message.success('success')
|
||||
getUserEmailList()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getUserEmailList()
|
||||
getSupportEmailList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
@ -1,9 +1,14 @@
|
||||
<template>
|
||||
<el-alert type="success" :closable="false">
|
||||
<!-- <el-alert type="success" :closable="false">
|
||||
<template #title>
|
||||
<span style="letter-spacing: 2px;"> 请添加邮箱并确保测试邮件通过 </span>
|
||||
</template>
|
||||
</el-alert>
|
||||
</el-alert> -->
|
||||
<!--
|
||||
{"type":"login","desc":"登录面板提醒","sw":true,"_id":"jxbeElEds9virx4m"}
|
||||
{"type":"updatePwd","desc":"修改密码提醒","sw":true,"_id":"uPa6imN4pKnAIgMW"}
|
||||
{"type":"err_login","desc":"登录错误提醒(连续5次)","sw":true,"_id":"wARAnQXturdZHdWK"}
|
||||
-->
|
||||
<el-table v-loading="notifyListLoading" :data="notifyList">
|
||||
<el-table-column prop="desc" label="通知类型" />
|
||||
<el-table-column prop="sw" label="开关">
|
130
web/src/views/setting/components/notify-config.vue
Normal file
130
web/src/views/setting/components/notify-config.vue
Normal file
@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<!-- <el-alert type="success" :closable="false">
|
||||
<template #title>
|
||||
<span style="letter-spacing: 2px;"> 保存并测试通过后才会收到通知 </span>
|
||||
</template>
|
||||
</el-alert> -->
|
||||
<!-- <br> -->
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="noticeConfig"
|
||||
:rules="rules"
|
||||
:inline="false"
|
||||
:hide-required-asterisk="true"
|
||||
:show-message="false"
|
||||
label-width="100px"
|
||||
label-suffix=":"
|
||||
>
|
||||
<el-form-item label="通知方式" prop="type" class="form_item">
|
||||
<el-select v-model="noticeConfig.type" placeholder="">
|
||||
<el-option
|
||||
v-for="item in noticeTypeList"
|
||||
:key="item.type"
|
||||
:label="item.desc"
|
||||
:value="item.type"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<template v-if="noticeConfig.type === 'sct'">
|
||||
<el-form-item label="SendKey" prop="sct.sendKey" class="form_item">
|
||||
<el-input
|
||||
v-model.trim="noticeConfig.sct.sendKey"
|
||||
clearable
|
||||
placeholder="SCT******"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="noticeConfig.type === 'email'">
|
||||
<el-form-item label="服务商" prop="email.service" class="form_item">
|
||||
<el-input
|
||||
v-model.trim="noticeConfig.email.service"
|
||||
clearable
|
||||
placeholder="邮箱服务商简写, 例如: Gmial、qq、126、163"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱地址" prop="email.user" class="form_item">
|
||||
<el-input
|
||||
v-model.trim="noticeConfig.email.user"
|
||||
clearable
|
||||
placeholder="邮箱地址"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="SMTP" prop="auth.pass" class="form_item">
|
||||
<el-input
|
||||
v-model.trim="noticeConfig.email.pass"
|
||||
clearable
|
||||
placeholder="SMTP授权码/密码"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item label="" class="form_item">
|
||||
<el-button type="primary" :loading="loading" @click="handleSave">
|
||||
保存并测试
|
||||
</el-button>
|
||||
<!-- <el-tooltip effect="dark" content="重复添加的邮箱将会被覆盖" placement="right">
|
||||
</el-tooltip> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
const { proxy: { $api, $message, $messageBox, $notification } } = getCurrentInstance()
|
||||
|
||||
const loading = ref(false)
|
||||
const noticeConfig = ref({})
|
||||
const noticeTypeList = ref([
|
||||
{
|
||||
type: 'email',
|
||||
desc: '邮箱'
|
||||
},
|
||||
{
|
||||
type: 'sct',
|
||||
desc: 'Server酱'
|
||||
},
|
||||
])
|
||||
const formRef = ref(null)
|
||||
|
||||
const rules = reactive({
|
||||
'sct.sendKey': { required: true, message: '需输入sendKey', trigger: 'change' },
|
||||
'email.service': { required: true, message: '需输入邮箱提供商', trigger: 'change' },
|
||||
'email.user': { required: true, type: 'email', message: '需输入邮箱', trigger: 'change' },
|
||||
'email.pass': { required: true, message: '需输入邮箱SMTP授权码', trigger: 'change' }
|
||||
})
|
||||
|
||||
const handleSave = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (!valid) return
|
||||
await $api.updateNotifyConfig({ noticeConfig: { ...noticeConfig.value } })
|
||||
$message.success('保存成功')
|
||||
})
|
||||
}
|
||||
|
||||
const getNotifyConfig = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
let { data } = await $api.getNotifyConfig()
|
||||
noticeConfig.value = data || {}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getNotifyConfig()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form_item {
|
||||
width: 350px;
|
||||
}
|
||||
</style>
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-alert type="success" :closable="false">
|
||||
<template #title>
|
||||
<span style="letter-spacing: 2px;"> 系统只保存最近10条登录记录, 目前版本只保存在内存中 </span>
|
||||
<span style="letter-spacing: 2px;"> 系统只保存最近10条登录记录, 目前版本只保存在内存中, 重启面板服务后会丢失 </span>
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-table v-loading="loading" :data="loginRecordList">
|
||||
|
@ -14,20 +14,22 @@
|
||||
<Sort @update-list="emitUpdateList" />
|
||||
</el-tab-pane> -->
|
||||
<el-tab-pane label="全局通知" lazy>
|
||||
<NotifyList />
|
||||
<GlobalNotify />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="邮箱配置" lazy>
|
||||
<EmailList />
|
||||
<el-tab-pane label="通知配置" lazy>
|
||||
<!-- <EmailList /> -->
|
||||
<NotifyConfig />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import NotifyList from './components/notify-list.vue'
|
||||
import EmailList from './components/email-list.vue'
|
||||
import GlobalNotify from './components/global-notify.vue'
|
||||
// import EmailList from './components/email-list.vue'
|
||||
import Record from './components/record.vue'
|
||||
import User from './components/user.vue'
|
||||
import NotifyConfig from './components/notify-config.vue'
|
||||
|
||||
</script>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user