feat: add cronmessage sendNow
This commit is contained in:
@@ -161,3 +161,40 @@ func EditCronMsgTask(c *gin.Context) {
|
||||
cron_msg_service.UpdateCronMsgToCronServer(msg)
|
||||
appG.CResponse(http.StatusOK, "编辑定时消息成功!", nil)
|
||||
}
|
||||
|
||||
type SendNowCronMsgReq struct {
|
||||
TaskID string `json:"task_id" validate:"required,max=100,min=1" label:"关联的任务id"`
|
||||
Title string `json:"title" validate:"required,max=100,min=1" label:"消息标题"`
|
||||
Content string `json:"content" validate:"required,max=10000,min=1" label:"消息内容"`
|
||||
Url string `json:"url" validate:"" label:"消息详情地址"`
|
||||
}
|
||||
|
||||
// SendNowCronMsg 立即发送定时消息
|
||||
func SendNowCronMsg(c *gin.Context) {
|
||||
var (
|
||||
appG = app.Gin{C: c}
|
||||
req SendNowCronMsgReq
|
||||
)
|
||||
|
||||
errCode, errMsg := app.BindJsonAndPlayValid(c, &req)
|
||||
if errCode != e.SUCCESS {
|
||||
appG.CResponse(errCode, errMsg, nil)
|
||||
return
|
||||
}
|
||||
|
||||
CronMsgService := cron_msg_service.CronMsgService{
|
||||
TaskID: req.TaskID,
|
||||
Title: req.Title,
|
||||
Content: req.Content,
|
||||
Url: req.Url,
|
||||
}
|
||||
|
||||
// 调用立即发送服务
|
||||
err := CronMsgService.SendNowByParams(c.ClientIP())
|
||||
if err != nil {
|
||||
appG.CResponse(http.StatusBadRequest, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
appG.CResponse(http.StatusOK, "发送成功!", nil)
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ func InitRouter(f embed.FS) *gin.Engine {
|
||||
apiV1.GET("/cronmessages/list", v1.GetCronMsgList)
|
||||
apiV1.POST("/cronmessages/delete", v1.DeleteCronMsgTask)
|
||||
apiV1.POST("/cronmessages/edit", v1.EditCronMsgTask)
|
||||
apiV1.POST("/cronmessages/sendnow", v1.SendNowCronMsg)
|
||||
|
||||
// hostedMessage
|
||||
apiV1.GET("/hostedmessages/list", v1.GetHostMessageList)
|
||||
|
||||
@@ -85,3 +85,29 @@ func GetCronNextTime(cronExpr string) string {
|
||||
nextTime := schedule.Next(time.Now()).Format("2006-01-02 15:04:05")
|
||||
return nextTime
|
||||
}
|
||||
|
||||
// SendNow 立即发送定时消息(根据定时消息ID)
|
||||
func (st *CronMsgService) SendNow(callerIP string) error {
|
||||
// 获取定时消息详情
|
||||
msg, err := st.GetByID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 调用发送服务
|
||||
return SendCronMessage(msg, callerIP)
|
||||
}
|
||||
|
||||
// SendNowByParams 立即发送定时消息(根据传入的参数)
|
||||
func (st *CronMsgService) SendNowByParams(callerIP string) error {
|
||||
// 直接使用传入的参数构造消息对象
|
||||
msg := models.CronMessages{
|
||||
TaskID: st.TaskID,
|
||||
Title: st.Title,
|
||||
Content: st.Content,
|
||||
Url: st.Url,
|
||||
}
|
||||
|
||||
// 调用发送服务
|
||||
return SendCronMessage(msg, callerIP)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package cron_msg_service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"github.com/sirupsen/logrus"
|
||||
"message-nest/models"
|
||||
"message-nest/pkg/constant"
|
||||
@@ -106,3 +107,44 @@ func RemoveCronMsgToCronServer(msg models.CronMessages) {
|
||||
func StartUpMsgCronTask() {
|
||||
MsgCronTask{}.Register()
|
||||
}
|
||||
|
||||
// SendCronMessage 发送定时消息(用于立即发送)
|
||||
func SendCronMessage(msg models.CronMessages, callerIP string) error {
|
||||
// 查询关联的发信任务
|
||||
task, err := models.GetTaskByID(msg.TaskID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("发信任务不存在: %s", msg.TaskID)
|
||||
}
|
||||
|
||||
// 创建发送服务
|
||||
sender := send_message_service.SendMessageService{
|
||||
TaskID: task.ID,
|
||||
Title: msg.Title,
|
||||
Text: msg.Content,
|
||||
URL: msg.Url,
|
||||
CallerIp: callerIP,
|
||||
DefaultLogger: logrus.WithFields(logrus.Fields{
|
||||
"prefix": "[Manual Send Cron Message]",
|
||||
}),
|
||||
}
|
||||
|
||||
// 预检查
|
||||
taskData, err := sender.SendPreCheck()
|
||||
if err != nil {
|
||||
errMsg := err.Error()
|
||||
// 如果是没有关联实例的错误,返回更友好的提示
|
||||
if strings.Contains(errMsg, "没有关联任何实例") {
|
||||
return fmt.Errorf("该发信任务尚未配置发送实例,请先在【发信任务】页面为任务 [%s] 添加至少一个发送实例", task.Name)
|
||||
}
|
||||
return fmt.Errorf("发送预检查失败: %s", errMsg)
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
_, err = sender.Send(taskData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("发送失败: %s", err.Error())
|
||||
}
|
||||
|
||||
logrus.Infof("立即发送定时消息成功,消息id: %s,消息名: %s", msg.ID, msg.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -69,6 +69,44 @@ const handleCancel = () => {
|
||||
emit('cancel')
|
||||
emit('update:open', false)
|
||||
}
|
||||
|
||||
// 立即发送(新增模式也支持,可以在创建前测试发送效果)
|
||||
const handleSendNow = async () => {
|
||||
// 验证必填字段
|
||||
if (!formData.task_id) {
|
||||
toast.error('请先选择关联的发信任务')
|
||||
return
|
||||
}
|
||||
if (!formData.title) {
|
||||
toast.error('请先填写消息标题')
|
||||
return
|
||||
}
|
||||
if (!formData.content) {
|
||||
toast.error('请先填写消息内容')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const postData = {
|
||||
task_id: formData.task_id,
|
||||
title: formData.title,
|
||||
content: formData.content,
|
||||
url: formData.url
|
||||
}
|
||||
|
||||
const rsp = await request.post('/cronmessages/sendnow', postData)
|
||||
if (rsp.data.code === 200) {
|
||||
toast.success(rsp.data.msg)
|
||||
} else {
|
||||
toast.error(rsp.data.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error('发送失败,请稍后重试')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -82,6 +120,7 @@ const handleCancel = () => {
|
||||
:loading="loading"
|
||||
@submit="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
@send-now="handleSendNow"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Textarea } from '@/components/ui/textarea'
|
||||
import { request } from '@/api/api'
|
||||
|
||||
interface CronMessageFormData {
|
||||
id?: number
|
||||
id?: string
|
||||
name: string
|
||||
cron_expression: string
|
||||
title: string
|
||||
@@ -27,6 +27,7 @@ interface Emits {
|
||||
(e: 'update:modelValue', value: CronMessageFormData): void
|
||||
(e: 'submit'): void
|
||||
(e: 'cancel'): void
|
||||
(e: 'sendNow'): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -92,6 +93,11 @@ const handleCancel = () => {
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
// 立即发送
|
||||
const handleSendNow = () => {
|
||||
emit('sendNow')
|
||||
}
|
||||
|
||||
// 组件挂载时加载数据
|
||||
loadAvailableTasks()
|
||||
</script>
|
||||
@@ -117,6 +123,9 @@ loadAvailableTasks()
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p class="text-xs text-gray-500">
|
||||
⚠️ 请确保所选任务已配置至少一个发送实例,否则无法发送
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
@@ -152,6 +161,9 @@ loadAvailableTasks()
|
||||
<Button variant="outline" @click="handleCancel" size="sm" :disabled="loading">
|
||||
取消
|
||||
</Button>
|
||||
<Button variant="secondary" @click="handleSendNow" size="sm" :disabled="loading">
|
||||
立即发送
|
||||
</Button>
|
||||
<Button @click="handleSubmit" size="sm" :disabled="loading">
|
||||
{{ mode === 'add' ? '创建定时消息' : '更新定时消息' }}
|
||||
</Button>
|
||||
|
||||
@@ -89,6 +89,44 @@ const handleCancel = () => {
|
||||
emit('update:open', false)
|
||||
}
|
||||
|
||||
// 立即发送
|
||||
const handleSendNow = async () => {
|
||||
// 验证必填字段
|
||||
if (!formData.task_id) {
|
||||
toast.error('请先选择关联的发信任务')
|
||||
return
|
||||
}
|
||||
if (!formData.title) {
|
||||
toast.error('请先填写消息标题')
|
||||
return
|
||||
}
|
||||
if (!formData.content) {
|
||||
toast.error('请先填写消息内容')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const postData = {
|
||||
task_id: formData.task_id,
|
||||
title: formData.title,
|
||||
content: formData.content,
|
||||
url: formData.url
|
||||
}
|
||||
|
||||
const rsp = await request.post('/cronmessages/sendnow', postData)
|
||||
if (rsp.data.code === 200) {
|
||||
toast.success(rsp.data.msg)
|
||||
} else {
|
||||
toast.error(rsp.data.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error('发送失败,请稍后重试')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 监听 cronMessage 变化,更新表单数据
|
||||
watch(
|
||||
() => props.cronMessage,
|
||||
@@ -114,6 +152,7 @@ watch(
|
||||
:loading="loading"
|
||||
@submit="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
@send-now="handleSendNow"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user