package model import ( "fmt" "mh-server/common" "mh-server/config" "mh-server/lib/requests" "strconv" "sync" "time" "github.com/codinl/go-logger" "github.com/pkg/errors" ) const ( WxPublicAppId = "wxfdb1c5654f681c7e" WxPublicAppSecret = "6e1908a71f31a80849ef0e59d90b7147" ) var mutexLock = new(sync.Mutex) func AccessToken() (string, error) { response := struct { AccessToken string `json:"access_token"` ExpiresIn uint32 `json:"expires_in"` Errcode uint32 `json:"errcode"` Errmsg string `json:"errmsg"` }{} //config.AppConfig.WxAppId = "wxfdb1c5654f681c7e" //config.AppConfig.WxAppSecret = "6e1908a71f31a80849ef0e59d90b7147" //config.AppConfig.WxAppId = "wx806c079463b5b56c" //config.AppConfig.WxAppSecret = "cb125688bf4e482f66e8c46062d568fc" //fmt.Println("WxAppId:", config.AppConfig.WxAppId) //fmt.Println("WxAppSecret:", config.AppConfig.WxAppSecret) fmt.Println("WxAppId:", WxPublicAppId) fmt.Println("WxAppSecret:", WxPublicAppSecret) if err := requests.GetAndParseJson("https://api.weixin.qq.com/cgi-bin/token", map[string]string{ "grant_type": "client_credential", "appId": WxPublicAppId, "secret": WxPublicAppSecret, }, &response); err != nil { logger.Error(err) return "", err } if response.Errcode != 0 { logger.Error(response.Errcode, "===", response.Errmsg) return "", errors.New(response.Errmsg) } logger.Infof("response=%+v", response) return response.AccessToken, nil } func AppAccessToken() (string, error) { response := struct { AccessToken string `json:"access_token"` ExpiresIn uint32 `json:"expires_in"` Errcode uint32 `json:"errcode"` Errmsg string `json:"errmsg"` }{} //config.AppConfig.WxAppId = "wxfdb1c5654f681c7e" //config.AppConfig.WxAppSecret = "6e1908a71f31a80849ef0e59d90b7147" config.AppConfig.WxAppId = "wx806c079463b5b56c" config.AppConfig.WxAppSecret = "cb125688bf4e482f66e8c46062d568fc" //fmt.Println("WxAppId:", config.AppConfig.WxAppId) //fmt.Println("WxAppSecret:", config.AppConfig.WxAppSecret) fmt.Println("WxAppId:", config.AppConfig.WxAppId) fmt.Println("WxAppSecret:", config.AppConfig.WxAppSecret) if err := requests.GetAndParseJson("https://api.weixin.qq.com/cgi-bin/token", map[string]string{ "grant_type": "client_credential", "appId": config.AppConfig.WxAppId, "secret": config.AppConfig.WxAppSecret, }, &response); err != nil { logger.Error(err) return "", err } if response.Errcode != 0 { logger.Error(response.Errcode, "===", response.Errmsg) return "", errors.New(response.Errmsg) } logger.Infof("response=%+v", response) return response.AccessToken, nil } // 获取 AccessToken 统一使用该方法,避免各自获取导致AccessToken 失效 func GetAccessToken() (string, error) { fmt.Println("获取AccessToken1:") accessToken := "" var ( err error tokenConfig Config ) //mutexLock.Lock() //defer mutexLock.Unlock() if err := NewConfigQuerySet(DB).NameEq(common.CONFIG_Access_Token).One(&tokenConfig); err != nil && err != RecordNotFound { logger.Error(err) return "", nil } logger.Error("查询accessToken:", tokenConfig.Value) accessToken = tokenConfig.Value if tokenConfig.UpdatedAt.Before(time.Unix(time.Now().Unix()-int64(7200), 0)) || tokenConfig.Value == "" { i := 0 tryTimes := 5 for ; i < tryTimes; i++ { accessToken, err = AccessToken() if err != nil { logger.Error("GetAccessToken Fail...err=", err) time.Sleep(time.Second * 2 * time.Duration(i)) continue } fmt.Println("accessToken:", accessToken) if accessToken != "" { logger.Info(accessToken) break } } if i >= tryTimes { logger.Error("GetAccessToken Fail...") return "", err } err = NewConfigQuerySet(DB).NameEq(common.CONFIG_Access_Token).GetUpdater().SetValue(accessToken).Update() if err != nil { logger.Error(err) return "", err } } fmt.Println("获取AccessToken3:") return accessToken, nil } // 获取 AccessToken 统一使用该方法,避免各自获取导致AccessToken 失效 func AppGetAccessToken() (string, error) { fmt.Println("获取AccessToken1:") accessToken := "" var ( err error tokenConfig Config ) //mutexLock.Lock() //defer mutexLock.Unlock() if err := NewConfigQuerySet(DB).NameEq(common.AppConfigAccessToken).One(&tokenConfig); err != nil && err != RecordNotFound { logger.Error(err) return "", nil } logger.Error("查询accessToken:", tokenConfig.Value) accessToken = tokenConfig.Value if tokenConfig.UpdatedAt.Before(time.Unix(time.Now().Unix()-int64(7200), 0)) || tokenConfig.Value == "" { i := 0 tryTimes := 5 for ; i < tryTimes; i++ { accessToken, err = AppAccessToken() if err != nil { logger.Error("GetAccessToken Fail...err=", err) time.Sleep(time.Second * 2 * time.Duration(i)) continue } fmt.Println("accessToken:", accessToken) if accessToken != "" { logger.Info(accessToken) break } } if i >= tryTimes { logger.Error("GetAccessToken Fail...") return "", err } err = NewConfigQuerySet(DB).NameEq(common.AppConfigAccessToken).GetUpdater().SetValue(accessToken).Update() if err != nil { logger.Error(err) return "", err } } fmt.Println("获取AccessToken3:") return accessToken, nil } // 获取 AccessToken 方法 func GenAccessToken() (string, error) { accessToken := "" var err error i := 0 tryTimes := 5 for ; i < tryTimes; i++ { accessToken, err = AccessToken() if err != nil { logger.Error("GetAccessToken Fail...err=", err) time.Sleep(time.Second * 2 * time.Duration(i)) continue } if accessToken != "" { logger.Info(accessToken) break } } if i >= tryTimes { logger.Error("GetAccessToken Fail...") return "", err } return accessToken, nil } type templeteMsgResponse struct { Errcode int `json:"errcode"` Errmsg string `json:"errmsg"` TemplateID string `json:"template_id"` } // 传的字符串直接在手机上显示 // 中奖结果通知 // treasureName 奖品名称 // exchangeUsername 兑换者姓名 // exchangeTime 兑换时间 // treasureIssueCode 中奖编码 // result 开奖结果 //func PushPrizeResult(accessToken string, treasureName, exchangeUsername, exchangeTime, treasureIssueCode, // result string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": treasureName, // }, // "keyword2": map[string]interface{}{ // "value": exchangeUsername, // }, // "keyword3": map[string]interface{}{ // "value": exchangeTime, // }, // "keyword5": map[string]interface{}{ // "value": treasureIssueCode, // }, // "keyword6": map[string]interface{}{ // "value": result, // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // openID := user.WxOpenID // if err := PushTemplate(openID, accessToken, common.TemplateID_Prize_Result_Notify, userForm.FormId, // "", "keyword1.DATA", data); err != nil { // logger.Error(err) // } // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //// 物流状态提醒 //// trackingNo 运单号 //// adName 联系人 //// prizeName 奖品名称 //// user_prize 发货时间 //func PushLogistics(accessToken, trackingNo, adName, prizeName, userPrizeTime string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // data := map[string]interface{}{ // "keyword3": map[string]interface{}{ // "value": trackingNo, // }, // "keyword5": map[string]interface{}{ // "value": adName, // }, // "keyword7": map[string]interface{}{ // "value": prizeName, // }, // "keyword9": map[string]interface{}{ // "value": userPrizeTime, // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // openID := user.WxOpenID // go func() { // if err := PushTemplate(openID, accessToken, common.TemplateID_Logistics_Notify, userForm.FormId, // "", "", data); err != nil { // logger.Error(err) // } // }() // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //// 客服回复通知 //// customName 客服姓名 //// respTime 回复时间 //// respContent 回复内容 //// info 温馨提示 //func PushCustomResponse(accessToken, customName, respTime, respContent, info string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": customName, // }, // "keyword2": map[string]interface{}{ // "value": respTime, // }, // "keyword3": map[string]interface{}{ // "value": respContent, // }, // "keyword4": map[string]interface{}{ // "value": info, // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // openID := user.WxOpenID // go func() { // if err := PushTemplate(openID, accessToken, common.TemplateID_Custom_Response_Notify, userForm.FormId, // "", "", data); err != nil { // logger.Error(err) // } // }() // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //// 签到提醒 //// signName 签到名称 //// signInfo 提醒内容 //// signCount 签到次数 //// signAward 今日签到 //// 签到名称 每日签到 //// 签到排名 第2名,共234人参与 //// 提醒内容 叮!该签到啦~锲而不舍,金石可镂。 //// 签到次数 第2次啦,加油嘞! //// 今日签到 200积分 //func PushCheckin(accessToken string, checkinName, checkinInfo, checkinCount, checkinAward string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": checkinName, // }, // "keyword3": map[string]interface{}{ // "value": checkinInfo, // }, // "keyword4": map[string]interface{}{ // "value": checkinCount, // }, // "keyword6": map[string]interface{}{ // "value": checkinAward, // }, // } // // for _, user := range users { // userFormId := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userFormId) == nil { // // openID := user.WxOpenID // if err := PushTemplate(openID, accessToken, common.TemplateID_Checkin_Notify, userFormId.FormId, // "", "", data); err != nil { // logger.Error(err) // continue // } // // userFormId.Used = true // _ = userFormId.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //// 日程提醒 //// scheduleTopic 日程主题 //// scheduleTime 日程时间 //// desc 任务描述 //func PushSchedule(accessToken string, scheduleTopic, scheduleTime, desc string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": scheduleTopic, // }, // "keyword2": map[string]interface{}{ // "value": scheduleTime, // }, // "keyword3": map[string]interface{}{ // "value": desc, // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // openID := user.WxOpenID // go func() { // if err := PushTemplate(openID, accessToken, common.TemplateID_Schedule_Notify, userForm.FormId, // "", "", data); err != nil { // logger.Error(err) // } // }() // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //// 订单发货提醒 //// billCreatedAt 购买时间 //// prizeName 物品名称 //// user_prize 发货时间 //func PushUserGoodSend(accessToken string, billCreatedAt, prizeName, userPrize string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": billCreatedAt, // }, // "keyword2": map[string]interface{}{ // "value": prizeName, // }, // "keyword3": map[string]interface{}{ // "value": userPrize, // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // openID := user.WxOpenID // go func() { // if err := PushTemplate(openID, accessToken, common.TemplateID_UserPrize_Send_Notify, userForm.FormId, // "", "", data); err != nil { // logger.Error(err) // } // }() // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //func PushLotteryResult(accessToken string, did, lotteryPrizeName, SponsorName string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": lotteryPrizeName, // }, // "keyword2": map[string]interface{}{ // "value": SponsorName, // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // openID := user.WxOpenID // go func() { // if err := PushTemplate(openID, accessToken, common.TemplateID_Lottery_Result_Notify, userForm.FormId, // fmt.Sprintf("pages/lottery/awardDetail/awardDetail?id=%s", did), "", data); err != nil { // logger.Error(err) // } // }() // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //func PushStockRefresh(accessToken string, prizeName string, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": prizeName, // }, // "keyword2": map[string]interface{}{ // "value": "收到你的喇叭喊话, 库存更新了", // }, // "keyword3": map[string]interface{}{ // "value": "散步拿奖, 免费兑换奖品", // }, // "keyword4": map[string]interface{}{ // "value": "快去看看, 慢了可能就抢光了~", // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // openID := user.WxOpenID // go func() { // if err := PushTemplate(openID, accessToken, common.TemplateID_Stock_Refresh_Notify, userForm.FormId, // "", "", data); err != nil { // logger.Error(err) // } // }() // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} // //func PushInviteLotteryResult(accessToken string, id uint32, uid ...uint32) error { // if len(uid) == 0 { // return errors.New("userList is Empty !") // } // // var users []User // if err := NewUserQuerySet(DB).UidIn(uid...).All(&users); err != nil { // logger.Error(err) // return err // } // // data := map[string]interface{}{ // "keyword1": map[string]interface{}{ // "value": "1~50元话费", // }, // "keyword2": map[string]interface{}{ // "value": "官方发起的抽奖正在开奖, 点击查看中奖结果", // }, // } // // for _, user := range users { // userForm := new(UserFormId) // if NewUserFormIdQuerySet(DB).UidEq(user.Uid).OrderAscByID().UsedEq(false). // CreatedAtGt(time.Now().AddDate(0, 0, -6)).One(userForm) == nil { // go func() { // if err := PushTemplate(user.WxOpenID, accessToken, common.TemplateID_Lottery_Result_Notify, userForm.FormId, // fmt.Sprintf("pages/lottery/awardDetail/awardDetail?id=%d&t=1", id), "", data); err != nil { // logger.Error(err) // } // }() // userForm.Used = true // go userForm.Update(DB, UserFormIdDBSchema.Used) // } // } // // return nil //} func PushTemplate(openID, accessToken, templateID, formID, page, emphasisKeyword string, data map[string]interface{}) error { params := map[string]interface{}{ "touser": openID, // openID "template_id": templateID, // 模板消息ID "form_id": formID, "data": data, } if page != "" { params["page"] = page // 点击模板卡片后的跳转页面, 示例index?foo=bar } if emphasisKeyword != "" { params["emphasis_keyword"] = emphasisKeyword // 要放大的词, 示例: keyword1.DATA } var response templeteMsgResponse if err := requests.PostAndParseJson(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/wxopen/"+ "template/send?access_token=%s", accessToken), params, requests.JSON, &response); err != nil { logger.Error(err) return err } if response.Errcode != 0 { return errors.New(strconv.Itoa(response.Errcode) + "===" + response.Errmsg) } return nil }