Commit ce822374 authored by 陈子龙's avatar 陈子龙

工单定时推送短信优化

parent da1f6fa2
...@@ -26,6 +26,7 @@ require ( ...@@ -26,6 +26,7 @@ require (
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.66.0 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.66.0
github.com/prometheus/alertmanager v0.25.0 github.com/prometheus/alertmanager v0.25.0
github.com/robfig/cron v1.2.0 github.com/robfig/cron v1.2.0
github.com/robfig/cron/v3 v3.0.1
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/spf13/cast v1.5.0 github.com/spf13/cast v1.5.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
......
...@@ -579,6 +579,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O ...@@ -579,6 +579,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
......
package entity package entity
import "time" import (
"time"
)
type WorkOrder struct { type WorkOrder struct {
Id int `json:"id" xorm:"pk autoincr" ` // id Id int `json:"id" xorm:"pk autoincr" ` // id
......
...@@ -53,7 +53,7 @@ func main() { ...@@ -53,7 +53,7 @@ func main() {
//启动定时任务 //启动定时任务
cron.StartCron() cron.StartCron()
service.PushWorkOrderMessage() service.CronPushWorkOrder()
// server start... // server start...
conf.Logger.Info("config info", zap.Any("options", conf.Options)) conf.Logger.Info("config info", zap.Any("options", conf.Options))
conf.Logger.Error("server start err", zap.Error(newServer().ListenAndServe())) conf.Logger.Error("server start err", zap.Error(newServer().ListenAndServe()))
...@@ -151,12 +151,6 @@ func initAnsibleHosts() { ...@@ -151,12 +151,6 @@ func initAnsibleHosts() {
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
//else {
// _, err := f.Write([]byte("[web]\n"))
// if err != nil {
// fmt.Println(err.Error())
// }
//}
} }
func initTempDirPrefix() { func initTempDirPrefix() {
...@@ -181,14 +175,4 @@ func initAnsibleSSH() { ...@@ -181,14 +175,4 @@ func initAnsibleSSH() {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
} }
//f2, err := os.CreateIndex("/root/.ssh/id_rsa.pub")
//defer f2.Close()
//if err != nil {
// fmt.Println(err.Error())
//} else {
// _, err := f.Write([]byte(conf.Options.PublicKeySSH))
// if err != nil {
// fmt.Println(err.Error())
// }
//}
} }
...@@ -175,3 +175,10 @@ func DisposedStatusText(code int) string { ...@@ -175,3 +175,10 @@ func DisposedStatusText(code int) string {
return "未知状态" return "未知状态"
} }
} }
// 工单定时类型
const (
TimingClick = 1 //手动下发
TimingWeekly = 2 //按周
TimingCustom = 3 //自定义时间
)
...@@ -46,5 +46,4 @@ func InitWorkOrderRouter(e *gin.Engine) { ...@@ -46,5 +46,4 @@ func InitWorkOrderRouter(e *gin.Engine) {
me.PUT("/feedback", controller.FeedbackWorkOrderMe) // 处置反馈 me.PUT("/feedback", controller.FeedbackWorkOrderMe) // 处置反馈
me.GET("/list", controller.ListWorkOrderMe) // 我的业务工单列表 me.GET("/list", controller.ListWorkOrderMe) // 我的业务工单列表
} }
//so.POST("/note_sg", controller.WorkOrderPushNoteMsg)
} }
...@@ -10,6 +10,4 @@ func StartCron() { ...@@ -10,6 +10,4 @@ func StartCron() {
defer c.Start() defer c.Start()
c.AddFunc("0 0 0 * * *", service.CronStatusDetection) // 每天凌晨0点状态检测 c.AddFunc("0 0 0 * * *", service.CronStatusDetection) // 每天凌晨0点状态检测
c.AddFunc("0 0 0 * * *", service.CronWorkOrderIssuance) // 每天凌晨0点扫描当天需下发工单
} }
...@@ -5,14 +5,17 @@ import ( ...@@ -5,14 +5,17 @@ import (
"fmt" "fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi" "github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
json "github.com/json-iterator/go" json "github.com/json-iterator/go"
"github.com/robfig/cron/v3"
"github.com/wanghuiyt/ding" "github.com/wanghuiyt/ding"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"go.uber.org/zap" "go.uber.org/zap"
"strings" "strings"
"time" "time"
...@@ -165,6 +168,11 @@ func (w *WorkOrderManageSvc) StateWorkOrderManage(req request.StateWorkOrderReq) ...@@ -165,6 +168,11 @@ func (w *WorkOrderManageSvc) StateWorkOrderManage(req request.StateWorkOrderReq)
err = resp.DbUpdateError.WithError(err) err = resp.DbUpdateError.WithError(err)
return return
} }
if req.TimingState == 1 {
//创建定时任务
CronPushWorkOrder()
}
return return
} }
...@@ -715,194 +723,140 @@ func WorkOrderPushNoteMsg(orderName string, phone []string, orderLevel int) (err ...@@ -715,194 +723,140 @@ func WorkOrderPushNoteMsg(orderName string, phone []string, orderLevel int) (err
return return
} }
// CronWorkOrderIssuance 定时任务-每天凌晨0点检测当天需下发工单 // PushObjMsg 解析用户并推送消息
func CronWorkOrderIssuance() { func PushObjMsg(obj, orderName string, orderLevel int) (err error) {
db, err := client.GetDbClient() var pushObj request.PushObj
if err != nil { err = json.Unmarshal([]byte(obj), &pushObj)
fmt.Println("CronStatusDetection err:", err.Error())
return
}
//查询推送工单
workOrderList := make([]entity.WorkOrder, 0)
finder := db.Table("work_order_manage").Where("timing_state = 1 AND (timing_type = 2 OR timing_type = 3)")
err = finder.Find(&workOrderList)
if err != nil { if err != nil {
fmt.Println("CronStatusDetection err:", err.Error())
return return
} }
week := map[time.Weekday]int{ var phones []string
time.Monday: 1, for _, v := range pushObj.UserObj {
time.Tuesday: 2, phones = append(phones, v.Phone)
time.Wednesday: 3,
time.Thursday: 4,
time.Friday: 5,
time.Saturday: 6,
time.Sunday: 7,
} }
switch pushObj.PushMethod {
for _, v := range workOrderList { case 1:
if v.TimingType == 2 { //发送钉钉消息
//按周 err = WorkOrderPushDingTalkMsg(orderName, orderLevel, phones)
var timingWeekly request.TimingWeekly
err = json.Unmarshal([]byte(v.TimingRule), &timingWeekly)
if err != nil { if err != nil {
fmt.Println("CronStatusDetection err:", err.Error()) return
continue
} }
days := week[time.Now().Weekday()] case 2:
for _, i := range timingWeekly.Week { //发送短信
if i == days { err = WorkOrderPushNoteMsg(orderName, phones, orderLevel)
//写redis
err = PushRedisWorkOrder(timingWeekly.PointTime, v.PushObj, v.OrderName, v.OrderLevel)
if err != nil { if err != nil {
fmt.Println("CronStatusDetection redis set err:", err.Error()) return
continue
}
break
}
} }
} else if v.TimingType == 3 { case 3:
//自定义时间 //发送钉钉消息
var timingCustom []request.TimingCustom err = WorkOrderPushDingTalkMsg(orderName, orderLevel, phones)
err = json.Unmarshal([]byte(v.TimingRule), &timingCustom)
if err != nil { if err != nil {
fmt.Println("CronStatusDetection json Unmarshal err:", err.Error()) return
continue
}
for _, v1 := range timingCustom {
t := time.Now()
dateFrom, err1 := time.Parse(jsontime.LocalDateFormat, v1.DateFrom)
if err1 != nil {
fmt.Println("CronStatusDetection dateFrom parse err:", err1.Error())
continue
}
dateTo, err1 := time.Parse(jsontime.LocalDateFormat, v1.DateTo)
if err1 != nil {
fmt.Println("CronStatusDetection dateTo parse err:", err1.Error())
continue
} }
if t.After(dateFrom) && t.Before(dateTo) { //发送短信
//写redis err = WorkOrderPushNoteMsg(orderName, phones, orderLevel)
err = PushRedisWorkOrder(v1.PointTime, v.PushObj, v.OrderName, v.OrderLevel)
if err != nil { if err != nil {
fmt.Println("CronStatusDetection redis set err:", err.Error()) return
continue
}
break
}
}
} }
} }
fmt.Println("CronPersonalCardDate success!") conf.Logger.Info("定时下发工单完成,工单名称:" + orderName)
return
} }
type CronRedisWorkOrder struct { var c = cron.New(cron.WithSeconds())
PointTime int64 `json:"point_Time"` // 时间点
PushObj string `json:"push_obj"` //推送对象
OrderName string `json:"order_name"` // 工单名称
OrderLevel int `json:"order_level"` // 工单等级(1紧急任务 2重要任务 3一般任务)
}
func PushRedisWorkOrder(pointTime, pushObj, orderName string, orderLevel int) (err error) { // CronPushWorkOrder 创建工单下发定时任务
redis, err := client.GetRedisClient() func CronPushWorkOrder() {
db, err := client.GetDbClient()
if err != nil { if err != nil {
conf.Logger.Error("获取数据库连接", zap.Error(err))
return return
} }
timeUnix, err := time.Parse(jsontime.LocalTimeFormat, pointTime) //查询推送工单
if err != nil { workOrderList := make([]entity.WorkOrder, 0)
return finder := db.Table("work_order_manage").Where("timing_state = ? AND (timing_type = ? "+
} "OR timing_type = ?)", constant.TimingClick, constant.TimingWeekly, constant.TimingCustom)
cronRedisWorkOrder := CronRedisWorkOrder{ err = finder.Find(&workOrderList)
PointTime: timeUnix.Unix(),
PushObj: pushObj,
OrderName: orderName,
OrderLevel: orderLevel,
}
workOrderObj, err := json.Marshal(cronRedisWorkOrder)
if err != nil { if err != nil {
conf.Logger.Error("查询推送工单", zap.Error(err))
return return
} }
//写redis
err = redis.LPush(conf.WorkOrderPush, fmt.Sprintf("%s", workOrderObj)) c.Stop()
defer c.Start()
for _, v := range workOrderList {
var pushObj request.PushObj
err = json.Unmarshal([]byte(v.PushObj), &pushObj)
if err != nil { if err != nil {
return return
} }
return svc := WorkOrderManageSvc{User: entity.SystemUserInfo{SystemAccount: v.CreateUser}}
}
// PushWorkOrderMessage 工单定时下发消息 if v.TimingType == constant.TimingWeekly {
func PushWorkOrderMessage() { var timingWeekly request.TimingWeekly
go func() { err = json.Unmarshal([]byte(v.TimingRule), &timingWeekly)
for {
redis, err := client.GetRedisClient()
if err != nil { if err != nil {
zap.L().Error(err.Error()) conf.Logger.Error("反序列化定时规则", zap.Error(err))
continue continue
} }
workOrderList, err := redis.LRange(conf.WorkOrderPush)
if err != nil { for k, v1 := range timingWeekly.Week {
zap.L().Error(err.Error()) if v1 == 7 {
continue timingWeekly.Week[k] = 0
} }
for _, v := range workOrderList {
var cronRedisWorkOrder CronRedisWorkOrder
err = json.Unmarshal([]byte(v), &cronRedisWorkOrder)
if err != nil {
zap.L().Error(err.Error())
continue
} }
times, err1 := time.Parse(jsontime.LocalTimeFormat, time.Now().Format(jsontime.LocalTimeFormat)) t, err := time.Parse(jsontime.LocalTimeFormat, timingWeekly.PointTime)
if err1 != nil {
zap.L().Error(err1.Error())
return
}
if cronRedisWorkOrder.PointTime == times.Unix() {
var pushObj request.PushObj
err = json.Unmarshal([]byte(cronRedisWorkOrder.PushObj), &pushObj)
if err != nil { if err != nil {
zap.L().Error(err.Error()) conf.Logger.Error("时间点类型转换错误", zap.Error(err))
continue continue
} }
var phones []string
for _, v1 := range pushObj.UserObj { expr := fmt.Sprintf("%d %d %d * * %s", t.Second(), t.Minute(), t.Hour(), strings.Join(util.IntsToStrings(timingWeekly.Week), ","))
phones = append(phones, v1.Phone) //创建定时任务
c.AddFunc(expr, func() {
err = svc.PushWorkOrderManage(request.PushWorkOrderReq{Id: v.Id, PushObj: pushObj})
//err = PushObjMsg(v.PushObj, v.OrderName, v.OrderLevel)
if err != nil {
conf.Logger.Error("发送定时消息失败", zap.Error(err))
} }
switch pushObj.PushMethod { })
case 1: } else {
//发送钉钉消息 var timingCustom request.TimingCustom
err = WorkOrderPushDingTalkMsg(cronRedisWorkOrder.OrderName, cronRedisWorkOrder.OrderLevel, phones) err = json.Unmarshal([]byte(v.TimingRule), &timingCustom)
if err != nil { if err != nil {
zap.L().Error(err.Error()) conf.Logger.Error("反序列化定时规则", zap.Error(err))
continue
} }
case 2:
//发送短信 dateFrom, err := time.Parse(jsontime.LocalDateFormat, timingCustom.DateFrom)
err = WorkOrderPushNoteMsg(cronRedisWorkOrder.OrderName, phones, cronRedisWorkOrder.OrderLevel)
if err != nil { if err != nil {
zap.L().Error(err.Error()) conf.Logger.Error("时间类型转换错误", zap.Error(err))
continue
} }
case 3: dateTo, err := time.Parse(jsontime.LocalDateFormat, timingCustom.DateTo)
//发送钉钉消息
err = WorkOrderPushDingTalkMsg(cronRedisWorkOrder.OrderName, cronRedisWorkOrder.OrderLevel, phones)
if err != nil { if err != nil {
zap.L().Error(err.Error()) conf.Logger.Error("时间类型转换错误", zap.Error(err))
continue
} }
//发送短信 t, err := time.Parse(jsontime.LocalDateFormat, timingCustom.PointTime)
err = WorkOrderPushNoteMsg(cronRedisWorkOrder.OrderName, phones, cronRedisWorkOrder.OrderLevel)
if err != nil { if err != nil {
zap.L().Error(err.Error()) conf.Logger.Error("时间点类型转换错误", zap.Error(err))
continue
} }
} for d := dateFrom; d.Before(dateTo); d = d.AddDate(0, 0, 1) {
//删除redis expr := fmt.Sprintf("%d %d %d %d %d %d", t.Second(), t.Minute(), t.Hour(), d.Day(), d.Month(), d.Year())
err = redis.LRem(conf.WorkOrderPush, v) //创建定时任务
c.AddFunc(expr, func() {
err = svc.PushWorkOrderManage(request.PushWorkOrderReq{Id: v.Id, PushObj: pushObj})
//err = PushObjMsg(v.PushObj, v.OrderName, v.OrderLevel)
if err != nil { if err != nil {
zap.L().Error(err.Error()) conf.Logger.Error("发送定时消息失败", zap.Error(err))
} }
})
} }
} }
} }
}()
} }
...@@ -16,3 +16,14 @@ func ConvertToString(v interface{}) string { ...@@ -16,3 +16,14 @@ func ConvertToString(v interface{}) string {
} }
return string(jsonData) return string(jsonData)
} }
// IntsToStrings 将int切片转换为字符串切片
func IntsToStrings(ints []int) []string {
strs := make([]string, len(ints))
for i, v := range ints {
strs[i] = fmt.Sprint(v)
}
return strs
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment