167 lines
5.0 KiB
Go
167 lines
5.0 KiB
Go
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)
|
||
}
|
||
}()
|
||
}
|
||
}
|
||
}
|
||
}
|