♻️ 重构通知模块

This commit is contained in:
chaos-zhu 2024-08-16 23:57:25 +08:00
parent ee63a53d6e
commit 1bdb620617
14 changed files with 280 additions and 480 deletions

View File

@ -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: {

View File

@ -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
}

View File

@ -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()
}

View File

@ -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',

View File

@ -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) {

View File

@ -1,3 +1,4 @@
// :TODO: 重写
const nodemailer = require('nodemailer')
const { readSupportEmailList, readUserEmailList } = require('./storage')
const commonTemp = require('../template/commonTemp')

View File

@ -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
}

View File

@ -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
}

View File

@ -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' })

View File

@ -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>

View File

@ -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="开关">

View 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>

View File

@ -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">

View File

@ -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>