package service
import (
"crypto/sha1"
"encoding/xml"
"fmt"
"io/ioutil"
"sort"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"kpt.notice/apiserver/model"
"kpt.notice/apiserver/model/http"
"kpt.notice/pkg/log"
"kpt.notice/pkg/util"
)
func (svc *Service) UpdateMessage(msg *model.Message) (err error) {
mtype := &http.MessageTypeReq{
SysName: msg.SysName,
PastureID: msg.PastureID,
ServiceID: msg.ServiceID,
}
if mtypes, e := svc.QueryMsgType(mtype); e != nil {
err = e
return
} else if len(mtypes) == 0 {
err = errors.New("没有匹配的消息类型")
return
} else {
m := make(map[string]interface{}, 3)
if mtypes[0].RemindType == 1 {
m["status"] = 1
} else if mtypes[0].RemindType == 2 {
if mtypes[0].CycleType == 1 || mtypes[0].CycleType == 3 {
m["status"] = 1
} else {
m["updated_at"] = time.Now()
m["push_count"] = msg.PushCount + 1
if msg.PushCount+1 >= mtypes[0].PushLimit {
m["status"] = 1
}
}
} else if mtypes[0].RemindType == 3 {
m["push_count"] = msg.PushCount + 1
m["updated_at"] = time.Now()
}
if res := svc.DB.Table("message").Where("id=?", msg.ID).Updates(m); res.Error != nil {
err = errors.Wrap(res.Error, "UpdateMessage.update=")
log.Errorf("%v", err)
}
}
return
}
func (svc *Service) UpdateMessageStatus(id int) (err error) {
err = svc.DB.Exec(` update message set status = -1 where id = ? `, id).Error
if err != nil {
log.Error(err)
return
}
return
}
func (svc *Service) QueryMsg() (msgs []model.Message, err error) {
var sql2 string
sql := `select sqltext from apisql where sqlname='getMessage' limit 1 `
svc.DB.Raw(sql).Scan(&sql2)
if err = svc.DB.Raw(sql2).Scan(&msgs).Error; err != nil {
err = errors.Wrap(err, "queryMsg{query msg exec sql err}==%v")
log.Errorf("%v", err)
return
}
return
}
func (svc *Service) InsertMessage(msg *http.MessageReq, body []byte) (resp *http.MessageResp, err error) {
tmp := make(map[string]interface{})
tmp["miniprogram"] = msg.Miniprogram
msgType := &http.MessageTypeReq{
SysName: msg.SysName,
PastureID: msg.PastureID,
ServiceID: msg.ServiceID,
}
sysuserList, e := svc.GetSysUser(msg.Target, msg.SysName, msg.PastureID)
if err != nil {
err = e
return
}
var targetList []string
for _, user := range sysuserList {
targetList = append(targetList, user.Openid)
}
if mt, e := svc.QueryMsgType(msgType); e != nil {
err = e
return
} else if len(mt) == 0 {
err = errors.New("没有匹配的消息类型")
return
} else {
tmp["template_id"] = mt[0].TemplateID
}
data := make(map[string]http.Tag)
for i, v := range msg.Keys {
data[v] = msg.Content[i]
}
tmp["data"] = data
status := -1
for _, target := range targetList {
if target != "" {
status = 0
break
}
}
msgDb := model.Message{
SysName: msg.SysName,
PastureID: msg.PastureID,
ServiceID: msg.ServiceID,
Target: util.MarshalToString(targetList),
MsgTypeID: msg.MsgTypeID,
MsgContent: util.MarshalToString(tmp),
UpdatedAt: time.Now(),
BodyData: string(body),
Status: status,
}
if err = svc.DB.Create(&msgDb).Error; err != nil {
err = errors.Wrap(err, "InsertMessage{insert msg}==%v")
log.Errorf("%v", err)
return
}
resp = &http.MessageResp{
ID: msgDb.ID,
}
return
}
// query the id or remind_type of the message by name
func (svc *Service) QueryRemindTypeID(name string) (int, error) {
m := new(http.MessageTypeReq)
tx := svc.DB.Table("message_type").Where("type_name = ?").First(m)
if tx.RowsAffected == 0 {
return 0, errors.New("没有匹配的类型")
}
return m.ID, nil
}
func (svc *Service) InsertMsgType(req *http.MessageTypeReq) (resp *http.MessageTypeResp, err error) {
//固定模板
req.TemplateID = "1_zBqvbzD-edg0b-O5OD1kAEMefygikcmBZACSiwX0w"
if query, e := svc.QueryMsgType(req); e != nil {
err = e
return
} else {
resp = new(http.MessageTypeResp)
switch {
case len(query) == 0:
resp.Method = "insert"
if res := svc.DB.Table("message_type").Create(req); res.Error != nil {
err = errors.Wrap(res.Error, "InsertMsgType{create msg type===%v}")
log.Errorf("%v", err)
} else {
resp.RowsAffected = int(res.RowsAffected)
}
break
case len(query) > 0:
resp.Method = "update"
index := map[string]interface{}{
"service_id": req.ServiceID,
"pasture_id": req.PastureID,
"sys_name": req.SysName,
}
log.Infof("msg type update index%v", index)
req.PastureID = 0
req.SysName = ""
req.ServiceID = 0
log.Infof("msg type update value%v", req)
if res := svc.DB.Table("message_type").Where(index).Updates(req); res.Error != nil {
err = errors.Wrap(err, "InsertMsgType{update msg type ===%v}")
log.Errorf("%v", err)
} else {
resp.RowsAffected = int(res.RowsAffected)
}
break
}
}
return
}
func (svc *Service) QueryMsgType(req *http.MessageTypeReq) (m []http.MessageTypeReq, err error) {
index := map[string]interface{}{}
if req.ServiceID != 0 {
index["service_id"] = req.ServiceID
}
if req.PastureID != 0 {
index["pasture_id"] = req.PastureID
}
if req.SysName != "" {
index["sys_name"] = req.SysName
}
log.Infof("query msg type===%v", index)
if err = svc.DB.Table("message_type").Where(index).Find(&m).Error; err != nil {
err = errors.Wrap(err, "QueryMsgType.find=")
log.Errorf("%v", err)
}
return
}
type WechatMessage struct {
ToUserName string `xml:"ToUserName"`
FromUserName string `xml:"FromUserName"`
CreateTime int64 `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Content string `xml:"Content"`
}
// type WechatTransferResponse struct {
// XMLName xml.Name `xml:"xml"`
// ToUserName string `xml:"ToUserName"`
// FromUserName string `xml:"FromUserName"`
// CreateTime int64 `xml:"CreateTime"`
// MsgType string `xml:"MsgType"`
// // TransInfo TransInfo `xml:"TransInfo"`
// }
type WechatResponse struct {
XMLName xml.Name `xml:"xml"`
ToUserName string `xml:"ToUserName"`
FromUserName string `xml:"FromUserName"`
CreateTime int64 `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Content string `xml:"Content"`
}
// func main() {
// r := gin.Default()
// r.GET("/wechat", handleVerification)
// r.POST("/wechat", handleMessage)
// fmt.Println("Server started on :80")
// r.Run(":80")
// }
func (svc *Service) HandleVerification(c *gin.Context) (bool, string) {
signature := c.Query("signature")
timestamp := c.Query("timestamp")
nonce := c.Query("nonce")
echostr := c.Query("echostr")
fmt.Println(signature)
fmt.Println(timestamp)
fmt.Println(nonce)
fmt.Println(echostr)
return checkSignature(signature, timestamp, nonce), echostr
}
func (svc *Service) HandleMessage(c *gin.Context) []byte {
body, _ := ioutil.ReadAll(c.Request.Body)
fmt.Println(string(body))
defer c.Request.Body.Close()
var msg WechatMessage
xml.Unmarshal(body, &msg)
var count int64
svc.DB.Table("public").Where("`create` between DATE_SUB(NOW(), INTERVAL 10 MINUTE) and NOW() ").Where(" wxid = ? ", msg.ToUserName).Count(&count)
p := new(http.Public)
p.Wxid = msg.ToUserName
p.Context = msg.Content
p.Create = time.Now().Format("2006-01-02 15:04:05")
svc.DB.Table("public").Create(p)
var content string
if count == 0 {
content = `您好!感谢您关注科湃腾!您哪个系统需要服务?
👉精准饲喂
👉智能脖环
👉智能喷淋
👉系统开发服务
👉其他
专线: 021- 6630 1586`
} else if p.Context == "精准饲喂" || p.Context == "智能脖环" || p.Context == "智能喷淋" || p.Context == "系统开发服务" || p.Context == "其他" {
content = `您所属那个大区?
👉东北大区
👉西北大区
👉华北大区
👉南方大区`
} else if p.Context == "东北大区" || p.Context == "西北大区" || p.Context == "华北大区" || p.Context == "南方大区" {
content = `东北大区服务老师联系方式
谭佳悦:18888309870
喻旭超:13594927924
您可通过电话进行咨询,若您现在不方便电话联系,可以留下您的联系方式,简单描述一下问题或者拍照,我们安排服务人员在4小时内联系您,请您留意电话接听,祝您生活愉快!`
// new(notice.MessageRequest)
// notice.SendMessage(nil)
} else {
}
response := WechatResponse{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: "text",
Content: content,
}
responseXML, _ := xml.Marshal(response)
return responseXML
}
func checkSignature(signature, timestamp, nonce string) bool {
token := "e10adc3949ba59abbe56e057f20f883e"
tmpList := []string{token, timestamp, nonce}
sort.Strings(tmpList)
tmpStr := strings.Join(tmpList, "")
h := sha1.New()
h.Write([]byte(tmpStr))
digest := fmt.Sprintf("%x", h.Sum(nil))
return digest == signature
}
type Message struct {
ToUser string `json:"touser"`
MsgType string `json:"msgtype"`
Text struct {
Content string `json:"content"`
} `json:"text"`
}
// func sendCustomMessage(accessToken, openID, content string) error {
// url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s", accessToken)
// message := Message{
// ToUser: openID,
// MsgType: "text",
// Text: struct {
// Content string `json:"content"`
// }{
// Content: content,
// },
// }
// payload, err := json.Marshal(message)
// if err != nil {
// return err
// }
// resp, err := http1.Post(url, "application/json", bytes.NewBuffer(payload))
// if err != nil {
// return err
// }
// defer resp.Body.Close()
// var result map[string]interface{}
// if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
// return err
// }
// fmt.Println("Response:", result)
// return nil
// }