package coryCommon import ( "context" "encoding/json" "errors" "fmt" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" commonService "github.com/tiger1103/gfast/v3/internal/app/common/service" "github.com/tiger1103/gfast/v3/internal/app/system/dao" "github.com/tiger1103/gfast/v3/internal/app/system/model" wxModel "github.com/tiger1103/gfast/v3/internal/app/wxApplet/model" tool "github.com/tiger1103/gfast/v3/utility/coryUtils" "strconv" "strings" "time" ) // 微信小程序的消息订阅 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/subscribe-message/sendMessage.html type TokenEntity struct { AccessToken string `json:"accessToken"` ExpiresIn string `json:"expiresIn"` } func GetAccessToken() (token string, err error) { var te *TokenEntity appId, _ := g.Cfg().Get(gctx.New(), "wx.appId") appSecret, _ := g.Cfg().Get(gctx.New(), "wx.appSecret") key := "weChatAccessToken" //从缓存捞取key ctx := gctx.New() get := commonService.Cache().Get(ctx, key) if get != nil && get.String() != "" { token = get.String() return "", err } else { uri := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId.String() + "&secret=" + appSecret.String() response, err := g.Client().Get(gctx.New(), uri) if err != nil { return "", err } else { allString := response.ReadAllString() err := json.Unmarshal([]byte(allString), &te) if err != nil { return "", err } else { //将token存储到redis中,tiken默认时间为秒,实际计算为2小时,(这里少100秒,防止token过期还存在redis中) num, err := strconv.Atoi(te.ExpiresIn) if err != nil { err = errors.New("过期时间转换失败!") return "", err } commonService.Cache().Set(ctx, key, te.AccessToken, time.Duration(num-100)*time.Second) token = te.AccessToken return token, err } } } } type AppletSubscription struct { Touser string `json:"touser"` TemplateId string `json:"template_id"` MiniprogramState string `json:"MiniprogramState"` Data DataEntity `json:"data"` } type DataEntity struct { Date1 ValueEntity `json:"date1"` Thing2 ValueEntity `json:"thing2"` Thing3 ValueEntity `json:"thing3"` } type ValueEntity struct { Value string `json:"value"` } type MsgEntity struct { ErrCode int `json:"errcode"` ErrMsg int64 `json:"errmsg"` MsgId string `json:"msgid"` } // Subscription 微信服务通知(消息订阅) func Subscription(openid string) (msgEntity *MsgEntity, err error) { //1、获取token token, err := GetAccessToken() if err != nil { fmt.Println("获取微信凭证错误!") return } //2、组装数据 //now := time.Now() var entity = new(AppletSubscription) entity.Touser = openid entity.TemplateId = "EyBO6gWizF5HwUThYSSm_HuQWgfMrwEkVHPXeEq1Me8" entity.MiniprogramState = "trial" var dataEntity = DataEntity{} dataEntity.Date1 = ValueEntity{Value: time.Now().Format("2006-01-02 15:04:05")} dataEntity.Thing2 = ValueEntity{Value: "您今日还有打卡未完成!"} dataEntity.Thing3 = ValueEntity{Value: "请登录中煤小程序进行打卡操作!"} entity.Data = dataEntity marshal, _ := json.Marshal(entity) //3、发起请求 msgEntity = new(MsgEntity) uri := "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token post, err := g.Client().Post(gctx.New(), uri, marshal) postBytes, err := json.Marshal(post) if err != nil { fmt.Println("JSON marshaling error:", err) return } if err := json.Unmarshal(postBytes, &msgEntity); err != nil { fmt.Println("解析JSON错误:", err) return nil, err } return } func ServiceNoticeFunc(ctx context.Context) { //1、获取所有项目的打卡范围 var projectEntity []*model.SysProjectListRes err := dao.SysProject.Ctx(ctx). Where("status", 0). Where("show_hidden", 1). Fields("id,project_name,punch_range").Scan(&projectEntity) if err != nil { fmt.Println("获取项目失败!") } //2、遍历项目获取打卡范围 for _, pData := range projectEntity { // 3、每个项目都有两个临时触发器 punchRange := pData.PunchRange split := strings.Split(punchRange, ",") for _, cfq := range split { dn, err := tool.TimeStr(cfq) if err != nil { fmt.Println(err) } //创建临时定时器 if dn > 0 { tempTimer := time.NewTimer(dn) // 在新的 goroutine 中等待临时定时器触发 go func() { <-tempTimer.C //4、就获取当前项目下面的所有成员(条件为subscription为1的数据) 下发数据,并存储下发数据的状态 var openidList []*wxModel.BusConstructionUserListRes dao.BusConstructionUser.Ctx(ctx). Fields("openid"). Where("subscription", "1"). Where("status = 0"). Where("entry_date is not null and entry_date!='' and (leave_date is null or leave_date = '')"). Where("project_id", pData.Id). Scan(&openidList) for _, oi := range openidList { Subscription(oi.Openid) } }() } } } }