Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
YYY
/
saas-v2-report-tool
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 6e6af76f
authored
Jun 05, 2026
by
niuxing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
调整监听配置
1 parent
ed210527
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
73 additions
and
10 deletions
server/index.js
server/routes/sql-manage.js
src/components/SendMailModal.jsx
src/components/SqlManagerModal.jsx
server/index.js
View file @
6e6af76
...
...
@@ -11,7 +11,7 @@ import schedulerRouter from './routes/scheduler.js'
const
__dirname
=
path
.
dirname
(
fileURLToPath
(
import
.
meta
.
url
))
const
app
=
express
()
const
PORT
=
4000
const
HOSTNAME
=
"
localhost
"
const
HOSTNAME
=
"
0.0.0.0
"
// 中间件
app
.
use
(
cors
())
...
...
server/routes/sql-manage.js
View file @
6e6af76
...
...
@@ -198,10 +198,10 @@ router.post('/:id/run', async (req, res) => {
}
})
// 手动发送邮件(可指定收件人)
// 手动发送邮件(可指定收件人
,支持群发/逐个发送
)
router
.
post
(
'/:id/send-mail'
,
async
(
req
,
res
)
=>
{
try
{
const
{
recipientEmails
,
emailSubject
}
=
req
.
body
const
{
recipientEmails
,
emailSubject
,
sendMode
}
=
req
.
body
const
scripts
=
loadScripts
()
const
script
=
scripts
.
find
(
s
=>
s
.
id
===
req
.
params
.
id
)
if
(
!
script
)
return
res
.
json
({
success
:
false
,
message
:
'脚本不存在'
})
...
...
@@ -311,6 +311,49 @@ router.post('/:id/send-mail', async (req, res) => {
</div>
`
// 逐个发送 vs 群发
const
recipientList
=
finalRecipients
.
split
(
','
).
map
(
e
=>
e
.
trim
()).
filter
(
e
=>
e
)
const
isIndividual
=
(
sendMode
||
'batch'
)
===
'individual'
if
(
isIndividual
&&
recipientList
.
length
>
1
)
{
// 逐个发送:每人一封单独邮件
let
successCount
=
0
let
failList
=
[]
for
(
const
rcpt
of
recipientList
)
{
try
{
await
sendReportMail
({
to
:
rcpt
,
subject
:
finalSubject
,
html
,
excelBuffer
,
fileName
,
})
successCount
++
}
catch
(
mailErr
)
{
failList
.
push
(
rcpt
)
console
.
error
(
`发送邮件到
${
rcpt
}
失败:`
,
mailErr
.
message
)
}
}
// 更新脚本状态
const
allScripts
=
loadScripts
()
const
idx
=
allScripts
.
findIndex
(
s
=>
s
.
id
===
script
.
id
)
if
(
idx
>=
0
)
{
allScripts
[
idx
].
lastRunAt
=
new
Date
().
toISOString
()
allScripts
[
idx
].
lastRunStatus
=
failList
.
length
===
0
?
'success'
:
(
successCount
>
0
?
'partial'
:
'failed'
)
allScripts
[
idx
].
lastRunMessage
=
failList
.
length
===
0
?
`逐个发送邮件成功,共
${
rows
.
length
}
条数据,
${
successCount
}
人已收到`
:
`逐个发送完成,成功
${
successCount
}
人,失败
${
failList
.
length
}
人:
${
failList
.
join
(
', '
)}
`
saveScripts
(
allScripts
)
}
if
(
failList
.
length
===
0
)
{
res
.
json
({
success
:
true
,
message
:
`逐个发送邮件成功,共
${
rows
.
length
}
条数据,
${
successCount
}
人已收到`
})
}
else
{
res
.
json
({
success
:
true
,
message
:
`逐个发送完成,成功
${
successCount
}
人,失败
${
failList
.
length
}
人:
${
failList
.
join
(
', '
)}
`
})
}
}
else
{
// 群发:一封邮件发送给所有人
await
sendReportMail
({
to
:
finalRecipients
,
subject
:
finalSubject
,
...
...
@@ -325,11 +368,12 @@ router.post('/:id/send-mail', async (req, res) => {
if
(
idx
>=
0
)
{
allScripts
[
idx
].
lastRunAt
=
new
Date
().
toISOString
()
allScripts
[
idx
].
lastRunStatus
=
'success'
allScripts
[
idx
].
lastRunMessage
=
`手动发送
邮件成功,共
${
rows
.
length
}
条数据,收件人:
${
finalRecipients
}
`
allScripts
[
idx
].
lastRunMessage
=
`群发
邮件成功,共
${
rows
.
length
}
条数据,收件人:
${
finalRecipients
}
`
saveScripts
(
allScripts
)
}
res
.
json
({
success
:
true
,
message
:
`邮件发送成功,共
${
rows
.
length
}
条数据,收件人:
${
finalRecipients
}
`
})
res
.
json
({
success
:
true
,
message
:
`群发邮件成功,共
${
rows
.
length
}
条数据,收件人:
${
finalRecipients
}
`
})
}
}
catch
(
e
)
{
// 更新脚本状态为失败
const
allScripts
=
loadScripts
()
...
...
src/components/SendMailModal.jsx
View file @
6e6af76
This diff is collapsed.
Click to expand it.
src/components/SqlManagerModal.jsx
View file @
6e6af76
...
...
@@ -440,7 +440,7 @@ export default function SqlManagerModal({ open, onClose, onLoadSql, currentSql,
{
title
:
'操作'
,
key
:
'action'
,
width
:
2
0
0
,
width
:
2
6
0
,
render
:
(
_
,
record
)
=>
(
<
Space
size=
{
4
}
>
<
Tooltip
title=
"加载到编辑器"
>
...
...
@@ -451,8 +451,10 @@ export default function SqlManagerModal({ open, onClose, onLoadSql, currentSql,
<
Tooltip
title=
"编辑脚本配置"
>
<
Button
type=
"link"
size=
"small"
icon=
{
<
EditOutlined
/>
}
onClick=
{
()
=>
handleEdit
(
record
)
}
/>
</
Tooltip
>
<
Tooltip
title=
"手动发送邮件"
>
<
Button
type=
"link"
size=
"small"
icon=
{
<
MailOutlined
/>
}
onClick=
{
()
=>
handleOpenSendMail
(
record
)
}
/>
<
Tooltip
title=
"手动发送邮件(可单独发送/群发)"
>
<
Button
type=
"link"
size=
"small"
style=
{
{
color
:
'#1890ff'
}
}
icon=
{
<
MailOutlined
/>
}
onClick=
{
()
=>
handleOpenSendMail
(
record
)
}
>
发邮件
</
Button
>
</
Tooltip
>
{
record
.
cronExpression
&&
(
<
Tooltip
title=
"手动触发执行"
>
...
...
@@ -530,12 +532,29 @@ export default function SqlManagerModal({ open, onClose, onLoadSql, currentSql,
}
}
>
{
record
.
sql
}
</
pre
>
<
div
style=
{
{
marginTop
:
8
,
display
:
'flex'
,
justifyContent
:
'space-between'
,
alignItems
:
'center'
}
}
>
<
div
>
{
record
.
recipientEmails
&&
(
<
div
style=
{
{
marginTop
:
8
,
fontSize
:
12
,
color
:
'#666'
}
}
>
<
span
style=
{
{
fontSize
:
12
,
color
:
'#666'
,
marginRight
:
16
}
}
>
<
MailOutlined
style=
{
{
marginRight
:
4
}
}
/>
收件人:
{
record
.
recipientEmails
}
</
div
>
</
span
>
)
}
{
record
.
purpose
&&
(
<
span
style=
{
{
fontSize
:
12
,
color
:
'#999'
}
}
>
用途:
{
record
.
purpose
}
</
span
>
)
}
</
div
>
<
Button
type=
"primary"
size=
"small"
icon=
{
<
MailOutlined
/>
}
onClick=
{
()
=>
handleOpenSendMail
(
record
)
}
>
发送邮件
</
Button
>
</
div
>
</
div
>
),
}
}
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment