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.

227 lines
5.1 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* @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"
"github.com/gin-gonic/gin"
"github.com/jageros/hawox/errcode"
"github.com/jageros/hawox/httpc"
"github.com/jageros/hawox/logx"
"net/http"
"stock/fund"
"stock/module"
"stock/stock"
"stock/user"
"strings"
"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
)
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"`
}
type IArg interface {
Arg(openid string) map[string]interface{}
}
type IMsg interface {
Msg() string
Name() string
}
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
}
func send(openID string, arg IArg, recall bool) error {
token, err := getAccessToken(false)
if err != nil {
return err
}
url := fmt.Sprintf(sendUrl, token)
msg := arg.Arg(openID)
if msg == nil {
return errcode.New(1, "arg == nil")
}
resp := &Resp{}
err = httpc.RequestWithInterface(httpc.POST, url, httpc.JSON, msg, nil, resp)
if err != nil {
return err
}
if resp.Errcode != 0 {
if resp.Errcode == 40014 {
_, err = getAccessToken(true)
if err != nil {
return err
}
if recall {
return send(openID, arg, false)
}
}
return errcode.New(int32(resp.Errcode), resp.Errmsg)
}
return nil
}
func Send(openId string, stk IArg) error {
return send(openId, stk, true)
}
func SendAll(stk IArg) error {
user.ForEachUser(func(u module.IUser) bool {
if u.HasSubscribed(false, "") {
err := Send(u.OpenID(), stk)
if err != nil {
logx.Error(err)
return false
}
}
return true
})
return nil
}
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"`
}
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(),
Content: "查询股票:=st股票代码例如=st600905\n查询基金=fd基金代码例如=fd161725\n\n" +
"订阅股票:+st股票代码例如+st600905\n订阅基金+fd基金代码例如+fd161725\n\n" +
"取消订阅股票:-st股票代码例如-st600905\n取消订阅基金-fd基金代码例如-fd161725",
}
if rMsg.MsgType == "text" {
u, err := user.GetUser(rMsg.FromUserName)
if err != nil {
c.String(http.StatusOK, err.Error())
c.Abort()
return
}
switch {
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()
}
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 {
u.Subscribe(isFund, code)
wMsg.Content = "订阅成功:\n" + im.Msg()
}
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 = "成功取消订阅:" + im.Name()
}
u.UnSubscribe(isFund, code)
}
}
c.XML(http.StatusOK, wMsg)
}