package service import ( "bytes" "context" "encoding/json" "fmt" oaApi "github.com/fonchain_enterprise/fonchain-main/api/oa" "github.com/fonchain_enterprise/fonchain-main/pkg/config" "github.com/google/uuid" "math/rand" "net/http" "strings" "time" ) // SendAppMessage 推送app消息 func SendAppMessageOld(title string, content string, userId uint64, approvalId uint64, sendType string) (err error) { type SendReq struct { RequestId string `json:"request_id"` PushClientid []string `json:"push_clientid"` Title string `json:"title"` Content string `json:"content"` ForceNotification bool `json:"force_notification"` Channel struct { VV int `json:"VV"` HW string `json:"HW"` } `json:"channel"` Options struct { HW struct { Importance string `json:"/message/android/notification/importance"` Category string `json:"/message/android/category"` DefaultSound bool `json:"/message/android/notification/default_sound"` ChannelId string `json:"/message/android/notification/channel_id"` Sound string `json:"/message/android/notification/sound"` } `json:"HW"` HO struct { Importance int `json:"/android/notification/importance"` } `json:"HO"` VV struct { //Classification int `json:"/classification"` NotifyType int `json:"/notifyType"` Category string `json:"/category"` } `json:"VV"` XM struct { ChannelId string `json:"/extra.channel_id"` //SoundUri string `json:"/extra.sound_uri"` } `json:"XM"` OP struct { ChannelId string `json:"/channel_id"` Category string `json:"/category"` //Style int `json:"/style"` NotifyLevel uint64 `json:"/notify_level"` } `json:"OP"` } `json:"options"` Payload struct { ApprovalId uint64 `json:"approval_id"` UserId uint64 `json:"user_id"` SendType string `json:"send_type"` } `json:"payload"` } // 生成10-32长度的随机数字字符串 rand.Seed(time.Now().UnixNano()) minLength := 10 maxLength := 32 length := minLength + rand.Intn(maxLength-minLength+1) randomString := generateRandomNumberString(length) //查询clientId punchReminderList, err := GrpcOAImpl.PunchReminderList(context.Background(), &oaApi.PunchReminderReq{UIDs: []uint64{userId}, IsOnline: 1}) if err != nil { return err } fmt.Println("==================ClientID===========================") fmt.Println(punchReminderList.Data) if len(punchReminderList.Data) < 1 { return nil } sendReq := &SendReq{} sendReq.RequestId = randomString sendReq.PushClientid = append(sendReq.PushClientid, punchReminderList.Data[0].ClientID) sendReq.Title = title sendReq.Content = content sendReq.ForceNotification = true //sendReq.Channel.VV = 1 //sendReq.Channel.HW = "NORMAL" sendReq.Options.HW.Importance = "NORMAL" sendReq.Options.HW.Category = "WORK" sendReq.Options.HW.ChannelId = "moceApproval" sendReq.Options.XM.ChannelId = config.XMChannelId sendReq.Options.VV.Category = "TODO" sendReq.Options.VV.NotifyType = 4 //sendReq.Options.OP.ChannelId = "oaApproval" sendReq.Options.OP.Category = "TODO" sendReq.Options.OP.NotifyLevel = 2 if sendType == "approval" { sendReq.Options.OP.ChannelId = "oaWaitApproval" } else { sendReq.Options.OP.ChannelId = "oaCopy" } sendReq.Payload.ApprovalId = approvalId sendReq.Payload.UserId = userId sendReq.Payload.SendType = sendType sendMarshal, err1 := json.Marshal(sendReq) if err1 != nil { return err1 } payload, err1 := json.Marshal(sendReq.Payload) if err1 != nil { return err1 } pushUser := make([]*oaApi.PushLogUser, 0) user := &oaApi.PushLogUser{ UserId: userId, PushClientId: punchReminderList.Data[0].ClientID, } pushUser = append(pushUser, user) logReq := &oaApi.CreatePushLogReq{ Users: pushUser, Title: title, Content: content, PayLoad: string(payload), PushType: 11, } //sendUrl := "https://fc-mp-e2cc2e59-5c7c-4d4c-b82c-db039e17f0c1.next.bspapp.com/oaapppush" sendUrl := fmt.Sprintf("https://fc-mp-e2cc2e59-5c7c-4d4c-b82c-db039e17f0c1.next.bspapp.com%v", config.Route) // 目标URL //如果失败再重复请求两次 for i := 0; i < config.SendTime; i++ { logReq.PushTime = time.Now().Format("2024-11-02 01:02:06") response, err2 := http.Post(sendUrl, "application/json", bytes.NewBuffer(sendMarshal)) logReq.Status = int32(response.StatusCode) if err2 != nil { //日志 logReq.ErrMsg = err2.Error() _, err3 := GrpcOAImpl.CreatePushLog(context.Background(), logReq) if err3 != nil { fmt.Println(err3) fmt.Println("==================记录日志失败=====================") } fmt.Println("=======================================发送失败==================================") } else { //日志 _, err3 := GrpcOAImpl.CreatePushLog(context.Background(), logReq) if err3 != nil { fmt.Println(err3) fmt.Println("==================记录日志失败=====================") } fmt.Println("====================================发送成功=======================================") break } } return nil } func SendAppMessage(title string, content string, userId uint64, approvalId uint64, sendType string) (err error) { //查询clientId punchReminderList, err := GrpcOAImpl.PunchReminderList(context.Background(), &oaApi.PunchReminderReq{UIDs: []uint64{userId}, IsOnline: 1, ForPush: 1}) if err != nil { return err } fmt.Println("==================ClientID===========================") fmt.Println(punchReminderList.Data) if len(punchReminderList.Data) < 1 { return nil } // 将数据编码为JSON type Payload struct { ApprovalId uint64 `json:"approval_id"` UserId uint64 `json:"user_id"` SendType string `json:"send_type"` } type HWNotification struct { Importance string `json:"/message/android/notification/importance"` Category string `json:"/message/android/category"` //DefaultSound bool `json:"/message/android/notification/default_sound"` ChannelId string `json:"/message/android/notification/channel_id"` //Sound string `json:"/message/android/notification/sound"` } type VVNotification struct { //Classification uint64 `json:"/classification"` NotifyType uint64 `json:"/notifyType"` Category string `json:"/category"` } type XMNotification struct { ChannelId string `json:"/extra.channel_id"` //SoundUri string `json:"/extra.sound_uri"` } type HONotification struct { Importance string `json:"/android/notification/importance"` } type OPNotification struct { ChannelId string `json:"/channel_id"` Category string `json:"/category"` NotifyLevel uint64 `json:"/notify_level"` //Style uint64 `json:"style"` } type Options struct { HW HWNotification `json:"HW"` VV VVNotification `json:"VV"` XM XMNotification `json:"XM"` OP OPNotification `json:"OP"` } type RequestData struct { PushClientId []string `json:"push_clientid"` Title string `json:"title"` Content string `json:"content"` RequestId string `json:"request_id"` ForceNotification bool `json:"force_notification"` Payload Payload `json:"payload"` Options Options `json:"options"` } UUID := uuid.New().String() data := &RequestData{ Title: title, Content: content, RequestId: UUID, ForceNotification: true, Payload: Payload{ ApprovalId: approvalId, UserId: userId, SendType: sendType, }, Options: Options{ HW: HWNotification{ Importance: "NORMAL", Category: "WORK", ChannelId: "moceApproval", }, VV: VVNotification{ Category: "TODO", NotifyType: 4, }, XM: XMNotification{ ChannelId: config.XMChannelId, //SoundUri: "android,resource://aobo,onbotics,accessibleCommunication/raw/callaudio", }, OP: OPNotification{ //ChannelId: "oaAttendance", Category: "TODO", NotifyLevel: 2, }, }, } data.PushClientId = make([]string, 0) data.PushClientId = append(data.PushClientId, punchReminderList.Data[0].ClientID) payload, err1 := json.Marshal(data.Payload) if err1 != nil { return err1 } if sendType == "approval" { data.Options.OP.ChannelId = "oaWaitApproval" } else { data.Options.OP.ChannelId = "oaCopy" } jsonData, err := json.Marshal(data) if err != nil { fmt.Printf("Error encoding JSON: %s\n", err) return } // 创建POST请求 //sendUrl := "https://fc-mp-e2cc2e59-5c7c-4d4c-b82c-db039e17f0c1.next.bspapp.com/oaapppush" sendUrl := fmt.Sprintf("https://fc-mp-e2cc2e59-5c7c-4d4c-b82c-db039e17f0c1.next.bspapp.com%v", config.Route) // 目标URL req, err := http.NewRequest("POST", sendUrl, bytes.NewBuffer(jsonData)) if err != nil { fmt.Printf("Error creating request: %s\n", err) return } // 设置请求头 req.Header.Set("Content-Type", "application/json") // 发送请求 client := &http.Client{} pushUser := make([]*oaApi.PushLogUser, 0) user := &oaApi.PushLogUser{ UserId: userId, PushClientId: punchReminderList.Data[0].ClientID, RequestInfo: string(jsonData), } pushUser = append(pushUser, user) logReq := &oaApi.CreatePushLogReq{ Uuid: UUID, Users: pushUser, Title: title, Content: content, PushTime: time.Now().Format("2006-01-02 15:04:05"), PayLoad: string(payload), PushType: 11, } //如果失败再重复请求两次 for i := 0; i < config.SendTime; i++ { resp, doErr := client.Do(req) if doErr != nil { //日志 logReq.ErrMsg = doErr.Error() logReq.Status = http.StatusInternalServerError fmt.Println("=======================================发送失败==================================") } else { logReq.Status = int32(resp.StatusCode) _ = resp.Body.Close() // Ensure response body is closed } _, err3 := GrpcOAImpl.CreatePushLog(context.Background(), logReq) if err3 != nil { fmt.Println(err3) fmt.Println("==================记录日志失败=====================") } if doErr != nil { continue } if resp.StatusCode == http.StatusOK { fmt.Println("====================================发送成功=======================================") return } } return nil } // 生成随机数字字符串 func generateRandomNumberString(n int) string { const digits = "0123456789" var sb strings.Builder sb.Grow(n) for i := 0; i < n; i++ { // 生成随机索引 index := rand.Intn(len(digits)) // 追加随机数字到字符串构建器 sb.WriteByte(digits[index]) } return sb.String() }