package web import ( "encoding/json" "fmt" "net/http" "strings" "sync" "time" "github.com/johlanse/wechat/mp" "github.com/johlanse/wechat/mp/request" log "github.com/sirupsen/logrus" "github.com/johlanse/study_xxqg/conf" "github.com/johlanse/study_xxqg/lib" "github.com/johlanse/study_xxqg/model" ) func init() { initWechat() } var ( wx *mp.WeiXin lastNonce = "" datas sync.Map ) const ( login = "login" StartStudy = "start_study" getUser = "stop_study" SCORE = "score" ) func initWechat() { config := conf.GetConfig() if !config.Wechat.Enable { return } log.Infoln(config.Wechat) wx = mp.New(config.Wechat.Token, config.Wechat.AppID, config.Wechat.Secret, "123", "123") err := wx.CreateMenu(&mp.Menu{Buttons: []mp.MenuButton{ { Name: "登录", Type: "click", Key: login, Url: "", MediaId: "", SubButtons: nil, }, { Name: "学习管理", Type: "click", Key: "study", Url: "", MediaId: "", SubButtons: []mp.MenuButton{ { Name: "开始学习", Type: "click", Key: StartStudy, Url: "", MediaId: "", SubButtons: nil, }, { Name: "获取用户", Type: "click", Key: getUser, Url: "", MediaId: "", SubButtons: nil, }, { Name: "积分查询", Type: "click", Key: SCORE, Url: "", MediaId: "", SubButtons: nil, }, }, }, }}) if err != nil { log.Errorln("设置自定义菜单出现异常" + err.Error()) return } if conf.GetConfig().Wechat.PushLoginWarn { model.SetPush(sendMsg) } wx.HandleFunc("eventCLICK", func(wx *mp.WeiXin, w http.ResponseWriter, r *request.WeiXinRequest, timestamp, nonce string) { if lastNonce == nonce { return } lastNonce = nonce switch r.EventKey { case login: go handleLogin(r.FromUserName) case StartStudy: go handleStartStudy(r.FromUserName) case getUser: go handleGetUser(r.FromUserName) case SCORE: go handleScore(r.FromUserName) } }) } func sendMsg(id, message string) { m := map[string]interface{}{ "data": map[string]string{ "value": message, }, } data, _ := json.Marshal(m) _, err := wx.SendTemplateMessage(&mp.TemplateMessage{ ToUser: id, TemplateId: conf.GetConfig().Wechat.NormalTempID, URL: "", TopColor: "", RawJSONData: data, }) if err != nil { return } } // HandleWechat /* @Description: * @param rep * @param req */ func HandleWechat(rep http.ResponseWriter, req *http.Request) { wx.ServeHTTP(rep, req) } func handleLogin(id string) { defer func() { err := recover() if err != nil { log.Errorln("处理微信事件错误") log.Errorln(err) } }() core := &lib.Core{Push: func(kind, message string) { if kind == "flush" && strings.HasPrefix(message, "登录链接") { l := strings.ReplaceAll(message, "登录链接:\r\n", "") _, err := wx.SendTemplateMessage(&mp.TemplateMessage{ ToUser: id, TemplateId: conf.GetConfig().Wechat.LoginTempID, URL: l, TopColor: "", RawJSONData: nil, }) if err != nil { log.Errorln(err.Error()) return } } }} _, err := core.L(0, id) if err != nil { return } sendMsg(id, "登录成功") } func handleStartStudy(id string) { defer func() { err := recover() if err != nil { log.Errorln("处理微信事件错误") log.Errorln(err) } }() users, err := model.QueryByPushID(id) if err != nil { return } if users == nil { log.Warningln("还未存在绑定的用户登录") sendMsg(id, "你还没有已登陆的用户,请点击下方登录按钮登录!") return } core := &lib.Core{ShowBrowser: conf.GetConfig().ShowBrowser, Push: func(kind, msg string) { }} core.Init() defer core.Quit() for i, user := range users { _, ok := datas.Load(user.UID) if ok { log.Warningln("用户" + user.Nick + "已经在学习中了,跳过该用户") continue } else { datas.Store(user.UID, "") } sendMsg(id, fmt.Sprintf("开始学习第%d个用户,用户名:%v", i+1, user.Nick)) core.LearnArticle(user) core.LearnVideo(user) core.RespondDaily(user, "daily") core.RespondDaily(user, "weekly") core.RespondDaily(user, "special") datas.Delete(user.UID) score, _ := lib.GetUserScore(user.ToCookies()) sendMsg(id, fmt.Sprintf("第%d个用户%v学习完成,学习积分\n%v", i+1, user.Nick, lib.FormatScore(score))) } } func handleGetUser(id string) { defer func() { err := recover() if err != nil { log.Errorln("处理微信事件错误") log.Errorln(err) } }() users, err := model.Query() if err != nil { return } if users == nil { log.Warningln("还未存在绑定的用户登录") sendMsg(id, "你还没有已登陆的用户,请点击下方登录按钮登录!") return } message := "" for _, user := range users { message += fmt.Sprintf("%v ==> %v", user.Nick, time.Unix(user.LoginTime, 0).Format("2006-01-02 15:04:05")) if user.PushId == id { message += "(已绑定)\n" } } sendMsg(id, message) } func handleScore(id string) { defer func() { err := recover() if err != nil { log.Errorln("处理微信事件错误") log.Errorln(err) } }() defer func() { err := recover() if err != nil { log.Errorln("处理微信事件错误") log.Errorln(err) } }() users, err := model.Query() if err != nil { return } if users == nil { log.Warningln("还未存在绑定的用户登录") sendMsg(id, "你还没有已登陆的用户,请点击下方登录按钮登录!") return } for _, user := range users { score, _ := lib.GetUserScore(user.ToCookies()) sendMsg(id, "用户:"+user.Nick+"\n"+lib.FormatScore(score)) } }