You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
6.4 KiB
Go

3 years ago
/**
* @Author: jager
* @Email: lhj168os@gmail.com
* @File: wxgzh
* @Date: 2021/12/20 6:53
* @package: wxgzh
* @Version: v1.0.0
*
* @Description:
*
*/
package wxgzh
import (
"fmt"
3 years ago
"github.com/gin-gonic/gin"
3 years ago
"github.com/jageros/hawox/errcode"
"github.com/jageros/hawox/httpc"
3 years ago
"github.com/jageros/hawox/logx"
"net/http"
3 years ago
"stock/fund"
"stock/stock"
3 years ago
"stock/user"
"strings"
3 years ago
"time"
)
var (
appid = "wxba88e64e7342b027"
secret = "ab8130a7bf55b78992e3d17f59909e0a"
accessTokenUrl = fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, secret)
sendUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s"
accessToken = ""
expiresIn int64
)
3 years ago
func InitCfg(appid_, secret_ string) {
appid = appid_
secret = secret_
}
3 years ago
type Resp struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
Msgid int `json:"msgid"`
}
type AccessToken struct {
AccessToken string `json:"access_token"`
ExpiresIn int64 `json:"expires_in"`
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
3 years ago
type IArg interface {
Arg(openid string) map[string]interface{}
3 years ago
}
3 years ago
type IMsg interface {
Msg() string
Name() string
}
3 years ago
func getAccessToken(update bool) (string, error) {
if !update && time.Now().Unix() < expiresIn {
return accessToken, nil
}
resp := &AccessToken{}
err := httpc.RequestWithInterface(httpc.GET, accessTokenUrl, httpc.FORM, nil, nil, resp)
if err != nil {
return "", err
}
if resp.Errcode != 0 {
return "", errcode.New(int32(resp.Errcode), resp.Errmsg)
}
accessToken = resp.AccessToken
expiresIn = time.Now().Unix() + resp.ExpiresIn
return resp.AccessToken, nil
}
3 years ago
func send(openID string, arg IArg, recall bool) error {
3 years ago
token, err := getAccessToken(false)
if err != nil {
return err
}
url := fmt.Sprintf(sendUrl, token)
3 years ago
msg := arg.Arg(openID)
3 years ago
if msg == nil {
3 years ago
return nil
3 years ago
}
3 years ago
resp := &Resp{}
3 years ago
err = httpc.RequestWithInterface(httpc.POST, url, httpc.JSON, msg, nil, resp)
3 years ago
if err != nil {
return err
}
if resp.Errcode != 0 {
if resp.Errcode == 40014 {
_, err = getAccessToken(true)
if err != nil {
return err
}
if recall {
3 years ago
return send(openID, arg, false)
3 years ago
}
}
return errcode.New(int32(resp.Errcode), resp.Errmsg)
}
return nil
}
3 years ago
func Send(openId string, stk IArg) error {
3 years ago
return send(openId, stk, true)
}
3 years ago
3 years ago
//func SendAll(stk IArg) error {
// user.ForEachUser(func(u *user.User) bool {
// if u.HasSubscribed(false, "") {
// err := Send(u.OpenID(), stk)
// if err != nil {
// logx.Error(err)
// return false
// }
// }
// return true
// })
// return nil
//}
3 years ago
type rData struct {
ToUserName string `xml:"ToUserName"`
FromUserName string `xml:"FromUserName"`
CreateTime int64 `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Content string `xml:"Content"`
MsgID int64 `xml:"MsgId"`
3 years ago
Event string `xml:"Event"`
3 years ago
}
type xml struct {
ToUserName string `xml:"ToUserName"`
FromUserName string `xml:"FromUserName"`
CreateTime int64 `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Content string `xml:"Content"`
}
func Handle(c *gin.Context) {
rMsg := &rData{}
err := c.BindXML(rMsg)
if err != nil {
c.String(http.StatusOK, err.Error())
c.Abort()
return
}
wMsg := &xml{
ToUserName: rMsg.FromUserName,
FromUserName: rMsg.ToUserName,
MsgType: "text",
CreateTime: time.Now().Unix(),
3 years ago
Content: "查询股票:=st股票代码例如=st600905\n查询基金=fd基金代码例如=fd161725\n\n" +
"订阅股票:+st股票代码例如+st600905\n订阅基金+fd基金代码例如+fd161725\n\n" +
3 years ago
"取消订阅股票:-st股票代码例如-st600905\n取消订阅基金-fd基金代码例如-fd161725\n\n" +
"查询已订阅股票lst\n" +
"查询已订阅基金lfd\n" +
"停止通知stop\n" +
"启动通知start\n",
}
u, err := user.GetUser(rMsg.FromUserName)
if err != nil {
wMsg.Content = err.Error()
rMsg.MsgType = ""
3 years ago
}
if rMsg.MsgType == "text" {
switch {
3 years ago
case strings.ToLower(rMsg.Content) == "stop":
u.Stop()
wMsg.Content = "已停止通知!"
case strings.ToLower(rMsg.Content) == "start":
u.Start()
wMsg.Content = "已启动通知!"
case strings.ToLower(rMsg.Content) == "lst":
codes := u.Codes(false)
stks, err := stock.GetStocks(codes...)
if err != nil {
wMsg.Content = "查询错误:\n" + err.Error()
} else {
3 years ago
msg := stks.Msg(true)
3 years ago
if msg == "" {
wMsg.Content = "您未订阅任何股票!"
} else {
wMsg.Content = "所有订阅股票信息:\n" + msg
}
}
case strings.ToLower(rMsg.Content) == "lfd":
codes := u.Codes(true)
msg := fund.FundsMsg(codes...)
if msg == "" {
wMsg.Content = "您未订阅任何基金!"
} else {
wMsg.Content = "所有订阅基金信息:\n" + msg
}
3 years ago
case len(rMsg.Content) < 9:
break
case strings.HasPrefix(rMsg.Content, "="):
code := rMsg.Content[3:]
isFund := rMsg.Content[1:3] == "fd"
var im IMsg
if isFund {
im, err = fund.NewFund(code)
} else {
im, err = stock.GetStock(code)
}
if err != nil {
wMsg.Content = "查询出错:\n" + err.Error()
} else {
wMsg.Content = "查询成功:\n" + im.Msg()
}
3 years ago
case strings.HasPrefix(rMsg.Content, "+"):
3 years ago
code := rMsg.Content[3:]
isFund := rMsg.Content[1:3] == "fd"
var im IMsg
if isFund {
im, err = fund.NewFund(code)
} else {
im, err = stock.GetStock(code)
}
if err != nil {
wMsg.Content = "订阅出错:\n" + err.Error()
} else {
u.Subscribe(isFund, code)
wMsg.Content = "订阅成功:\n" + im.Msg()
}
3 years ago
case strings.HasPrefix(rMsg.Content, "-"):
3 years ago
code := rMsg.Content[3:]
isFund := rMsg.Content[1:3] == "fd"
var im IMsg
if isFund {
im, err = fund.NewFund(code)
} else {
im, err = stock.GetStock(code)
}
if err != nil {
wMsg.Content = "取消订阅:\n" + err.Error()
} else {
wMsg.Content = "成功取消订阅:" + im.Name()
}
u.UnSubscribe(isFund, code)
3 years ago
}
}
3 years ago
if rMsg.MsgType == "event" {
switch rMsg.Event {
case "subscribe":
logx.Infof("user=%s subscribe!", u.OpenID())
u.Start()
case "unsubscribe":
logx.Infof("user=%s unsubscribe!", u.OpenID())
u.Stop()
c.String(http.StatusOK, "success")
c.Abort()
return
}
}
3 years ago
c.XML(http.StatusOK, wMsg)
}