first commit

This commit is contained in:
2026-02-17 13:06:23 +08:00
commit 7cbd3d061d
349 changed files with 126558 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
package websrv
import "xiawan/wx/clientsdk/baseinfo"
const (
// TaskStateLoginSuccess 登录成功状态
TaskStateLoginSuccess = string("2")
// TaskStateLogout 退出登录
TaskStateLogout = string("6")
// TaskStateCheckLoginQrcodeSuccess 检测状态
TaskStateCheckLoginQrcodeSuccess = string("1")
// TaskStateCheckLoginQrcodeStartLogin 用户点击了登录
TaskStateCheckLoginQrcodeStartLogin = string("7")
// TaskStateMismatching 账号不匹配
TaskStateMismatching = string("9")
// TaskTypeUploadStatus 上传状态
TaskTypeUploadStatus uint32 = 1
// TaskTypeReportHeart 发送心跳包
TaskTypeReportHeart uint32 = 2
)
// TaskInfo 任务信息
type TaskInfo struct {
UUID string
TaskID string
Name string
AppNumber string
Account string
SignKey string
}
// UploadTaskStatusResp 上传状态响应
type UploadTaskStatusResp struct {
Code uint32 `json:"code"`
Msg string `json:"msg"`
Data string `json:"data"`
}
// WebTask web任务
type WebTask struct {
UserInfo *baseinfo.UserInfo
TaskInfo *TaskInfo
ConnectInfo map[string]interface{}
Status string
Type uint32
Count uint32
}
+51
View File
@@ -0,0 +1,51 @@
package websrv
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
)
// TaskPost 短连接发送数据
func TaskPost(uri string, data []byte) ([]byte, error) {
client := &http.Client{}
request, err := http.NewRequest("POST", uri, bytes.NewReader(data))
if err != nil {
return nil, err
}
request.Header.Add("UserAgent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)")
request.Header.Add("Accept", "*/*")
request.Header.Add("content-type", "application/x-www-form-urlencoded")
resp, err := client.Do(request)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return []byte(body), nil
}
// TaskPost 短连接发送数据
func TaskPostJson(uri string, data []byte) ([]byte, error) {
client := &http.Client{}
request, err := http.NewRequest("POST", uri, bytes.NewReader(data))
if err != nil {
return nil, err
}
request.Header.Add("content-type", "application/json")
resp, err := client.Do(request)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
fmt.Println("短连接发送数据", uri,string(data),string(body))
return []byte(body), nil
}
+112
View File
@@ -0,0 +1,112 @@
package websrv
import (
"errors"
"sync"
"xiawan/wx/clientsdk/baseinfo"
)
// WebTaskMgr web任务管理器
type WebTaskMgr struct {
// wxConn wxface.IWXConnect
taskChan chan *WebTask
endChan chan bool
isStart bool
}
// 全局只能定义一个
var WebTaskMgrInit *WebTaskMgr = &WebTaskMgr{
taskChan: make(chan *WebTask, 100),
endChan: make(chan bool, 1),
isStart: false,
}
var globalLock sync.Mutex = sync.Mutex{}
// NewWebTaskMgr 新建web任务管理器
func NewWebTaskMgr() *WebTaskMgr {
globalLock.Lock()
defer globalLock.Unlock()
return WebTaskMgrInit
}
// Start 开启
func (wtm *WebTaskMgr) Start() {
globalLock.Lock()
defer globalLock.Unlock()
if wtm.isStart {
return
}
wtm.isStart = true
go wtm.queryAndExecuteTask()
}
// Stop 关闭
func (wtm *WebTaskMgr) Stop() {
wtm.isStart = false
wtm.endChan <- true
}
// AddWebTask 新增Web任务
func (wtm *WebTaskMgr) retSetWebTask(webTask *WebTask) {
// 最多三次
if webTask.Count >= 2 {
return
}
webTask.Count++
wtm.taskChan <- webTask
}
// AddWebTask 新增Web任务
func (wtm *WebTaskMgr) AddWebTask(userInfo *baseinfo.UserInfo, taskInfo *TaskInfo, status string, tmpType uint32, connectInfo map[string]interface{}) {
if !wtm.isStart {
return
}
globalLock.Lock()
defer globalLock.Unlock()
newWebTask := &WebTask{}
newWebTask.ConnectInfo = connectInfo
newWebTask.TaskInfo = taskInfo
newWebTask.UserInfo = userInfo
newWebTask.Status = status
newWebTask.Type = tmpType
newWebTask.Count = 0
wtm.taskChan <- newWebTask
}
func (wtm *WebTaskMgr) queryAndExecuteTask() {
for {
select {
case webTask := <-wtm.taskChan:
if webTask.Type == TaskTypeUploadStatus {
err := errors.New("")
// err := UploadTaskStatus(webTask)
// if err != nil && webTask.Status != TaskStateCheckLoginQrcodeSuccess {
// wtm.retSetWebTask(webTask)
// continue
// }
// 登陆成功上报
if webTask.Status == TaskStateLoginSuccess {
err = ReportWechatStatus(webTask, "1")
if err != nil {
wtm.retSetWebTask(webTask)
continue
}
}
// 退出登陆上报
if webTask.Status == TaskStateLogout {
err = ReportWechatStatus(webTask, "0")
if err != nil {
wtm.retSetWebTask(webTask)
continue
}
}
} else if webTask.Type == TaskTypeReportHeart {
// 上报心跳包
}
continue
case <-wtm.endChan:
return
}
}
}
+126
View File
@@ -0,0 +1,126 @@
package websrv
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"reflect"
"strconv"
"time"
"xiawan/wx/clientsdk/baseutils"
"xiawan/wx/srv/srvconfig"
)
func createParamData(paramMap map[string]string) []byte {
retString := ""
for key, value := range paramMap {
retString = retString + key + "=" + value + "&"
}
retBytes := []byte(retString)
count := len(retBytes)
retBytes = retBytes[0 : count-1]
return retBytes
}
func getBaseParamMap(taskInfo *TaskInfo) map[string]string {
retMap := make(map[string]string)
curTime := strconv.Itoa(int(time.Now().UnixNano() / 1000000000))
head := curTime + taskInfo.SignKey
hsWebTime := curTime + baseutils.RandomBigHexString(20)
apiKey := baseutils.Md5Value(head)
retMap["name"] = taskInfo.Name
retMap["app_number"] = taskInfo.AppNumber
retMap["apikey"] = apiKey
retMap["hswebtime"] = hsWebTime
retMap["time"] = curTime
return retMap
}
// UploadTaskStatus 上传任务状态
func UploadTaskStatus(webTask *WebTask) error {
baseParamMap := getBaseParamMap(webTask.TaskInfo)
baseParamMap["name"] = webTask.UserInfo.NickName
baseParamMap["task_id"] = webTask.TaskInfo.TaskID
baseParamMap["account"] = webTask.UserInfo.WxId
baseParamMap["headimg"] = webTask.UserInfo.HeadURL
baseParamMap["status"] = webTask.Status
if webTask.Status == TaskStateLoginSuccess {
tmpToken := base64.StdEncoding.EncodeToString(webTask.UserInfo.AutoAuthKey)
baseParamMap["token"] = tmpToken
baseParamMap["data"] = ""
baseParamMap["autoauth"] = "data=" + "token=" + tmpToken
}
paramBytes := createParamData(baseParamMap)
respData, err := TaskPost("http://"+srvconfig.GlobalSetting.WebDomain+"/statistic/Wechat/upd.html", paramBytes)
if err != nil {
baseutils.PrintLog(err.Error())
return err
}
resp := &UploadTaskStatusResp{}
err = json.Unmarshal(respData, resp)
if err != nil {
return err
}
// 如果显示44
if resp.Code == 44 {
return nil
}
return nil
}
// ReportWechatStatus 上报状态
func ReportWechatStatus(webTask *WebTask, tmpType string) error {
baseParamMap := getBaseParamMap(webTask.TaskInfo)
baseParamMap["name"] = webTask.UserInfo.NickName
baseParamMap["uuid"] = webTask.UserInfo.UUID
baseParamMap["task_id"] = webTask.TaskInfo.TaskID
baseParamMap["account"] = webTask.UserInfo.WxId
baseParamMap["task_type"] = "2"
baseParamMap["service"] = srvconfig.GlobalSetting.WebDomainNum
baseParamMap["type"] = tmpType
connectInfo := map[string]interface{}{}
connectInfo["info"] = baseParamMap
// 复制所有能够被序列化的字段
for key, value := range webTask.ConnectInfo {
switch v := value.(type) {
case func(): // 这里检查并排除不支持的字段
fmt.Println("Skipping function:", key)
default:
// 判断是否是基本类型
if reflect.TypeOf(v).Kind() == reflect.String || reflect.TypeOf(v).Kind() == reflect.Int || reflect.TypeOf(v).Kind() == reflect.Bool {
connectInfo[key] = v
}
}
}
// 将参数转换为 JSON 格式
paramBytes, err := json.Marshal(connectInfo)
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return err
}
if srvconfig.GlobalSetting.WebDomain == "" {
return nil
}
respData, err := TaskPostJson("http://"+srvconfig.GlobalSetting.WebDomain+"/statistic/Wechat/reportStatus", paramBytes)
if err != nil {
baseutils.PrintLog(err.Error())
return err
}
resp := &UploadTaskStatusResp{}
err = json.Unmarshal(respData, resp)
if err != nil {
return err
}
// 上报错误
if resp.Code == 44 {
return errors.New("上报错误")
}
return nil
}