package task import ( "bytes" "encoding/json" "fmt" "io" "sundynix-go/global" "sundynix-go/model/plant" "sundynix-go/model/system" "sundynix-go/pkg/httpclient" "sundynix-go/utils/timer" "sundynix-go/utils/wechat" "time" ) type TemplateDataItem struct { Value string `json:"value"` } // SendMessagePayload 是我们发送给微信服务器的消息体 type SendMessagePayload struct { TemplateID string `json:"template_id"` Page string `json:"page"` Touser string `json:"touser"` Data map[string]TemplateDataItem `json:"data"` MiniProgramState string `json:"miniprogram_state"` //跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 Lang string `json:"lang"` } // SendMessageResponse 是发送消息的响应体 type SendMessageResponse struct { Errcode int `json:"errcode"` Errmsg string `json:"errmsg"` } // SendCareMsg 发送提醒消息 func SendCareMsg() error { httpUrl := "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + wechat.GetMiniAccessToken() //1.查询出今日的养护任务 now := time.Now() today := timer.GetZeroTime() endOfToday := today.Add(24 * time.Hour) var tasks []*plant.CareTask err := global.DB.Where("status = 1 and due_date < ?", endOfToday).Order("due_date ASC").Find(&tasks).Error if len(tasks) > 0 { // 将tasks分组,key为用户id 保证无论用户有多少植物,只给用户发送一条消息 tasksMap := make(map[string][]*plant.CareTask) for _, task := range tasks { //用户id不为空再添加 if task.UserId != "" { tasksMap[task.UserId] = append(tasksMap[task.UserId], task) } } for userId, cares := range tasksMap { //1.查询用户 var user system.User err = global.DB.Where("id = ?", userId).First(&user).Error if err != nil { return err } if user.MiniOpenId != "" { //2.用户该养护的植物 plantId := cares[0].PlantId var myPlant plant.MyPlant err = global.DB.Where("id = ?", plantId).First(&myPlant).Error if err != nil { return err } //3.构造请求参数 发送订阅消息 payload := SendMessagePayload{ TemplateID: "iG5GYMPQAgKxIE9zZNOgKS6tCURhM9p9AC8iZ3Uj3uA", Page: "pages/tasks/index", Touser: user.MiniOpenId, Data: map[string]TemplateDataItem{ "thing1": { Value: myPlant.Name + "等", }, "time3": { // 今天的九点 Value: time.Date(now.Year(), now.Month(), now.Day(), 8, 30, 0, 0, time.Local).Format("2006-01-02"), }, }, MiniProgramState: "formal", //MiniProgramState: "trial", Lang: "zh_CN", } payloadBytes, err := json.Marshal(payload) if err != nil { return err } myHttpClient := httpclient.GetClient() resp, err := myHttpClient.Post(httpUrl, "application/json", bytes.NewBuffer(payloadBytes)) if err != nil { return err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("读取订阅消息响应失败: %v", err) } var smr SendMessageResponse err = json.Unmarshal(body, &smr) if err != nil { return fmt.Errorf("解析订阅消息响应失败: %v, body: %s", err, string(body)) } if smr.Errcode != 0 { global.Logger.Error("订阅消息发送失败!" + userId + "open-id" + user.MiniOpenId) return fmt.Errorf("微信服务器返回错误: errcode=%d, errmsg=%s", smr.Errcode, smr.Errmsg) } global.Logger.Info("订阅消息发送成功!" + userId + "open-id" + user.MiniOpenId) } } } return nil }