wangchuanjin 9 gadi atpakaļ
vecāks
revīzija
ed945208e3

+ 5 - 8
common/src/qfw/util/rpc/weixin.go

@@ -24,16 +24,13 @@ type BonusMsg struct {
 	Actname     string `json:"act_name"`     //活动名称
 	Remark      string `json:"remark"`       //说明
 }
-type Articles struct {
+type Article struct {
 	Title       string `json:"title"`
 	Description string `json:"description"`
+	PicUrl      string `json:"picurl"`
 	Url         string `json:"url"`
-	Picurl      string `json:"picurl"`
 }
-type ImgTextMsg struct {
-	ToUser  string `json:"touser"`
-	MsgType string `json:"msgtype"`
-	News    struct {
-		Articles []Articles `json:"articles"`
-	} `json:"news"`
+type News struct {
+	ToUser   string //用户id
+	Articles []Article
 }

+ 4 - 3
weixin/src/config.json

@@ -43,11 +43,12 @@
 	"dir":"/opt/mntdisk/qfw-v1.1",
 	"qmxcdn":"http://cdn.qmx.top:9000",
 	"rpcserver": "127.0.0.1:83",
-	"msgserver":"test.qmx.top:7070",
+	"msgserver":"192.168.3.14:7070",
 	"distinguishWork":{
+		"errorCount":3,
 		"title":"识别验证码",
-		"detail":"企明星",
-		"result":"您有一个待识别的验证码,点击下方“详情”查看",
+        "detail":"企明星",
+        "result":"您有一个待识别的验证码,点击下方“详情”查看",
 		"description":"请识别图中验证码并回复",
 		"in":"欢迎您进入了识别验证码工作,输入“结束识别验证码”退出本次工作。",
 		"out":"您已退出本次工作,辛苦了,再见。",

+ 2 - 0
weixin/src/main.go

@@ -30,6 +30,8 @@ func init() {
 	log.Printf("The web server listen on %s %s:%s \n AppContext:%s \n", "http://", wf.SysConfig.Domain, wf.SysConfig.Port, wf.SysConfig.Appcontext)
 	//微信sdk配置
 	weixin.InitWeixinSdk()
+	//连接消息总线
+	weixin.InitDgWork()
 }
 
 func main() {

+ 104 - 28
weixin/src/qfw/weixin/distinguishwork.go

@@ -11,6 +11,7 @@ import (
 	"net/rpc"
 	"os"
 	qfwutil "qfw/util"
+	"qfw/util/image"
 	qrpc "qfw/util/rpc"
 	wf "qfw/weixinconfig"
 	"sync"
@@ -33,7 +34,7 @@ var client *util.Client
 type DistinguishWork struct {
 }
 
-func initDgWork() {
+func InitDgWork() {
 	client, _ = util.StartClient(processevent, wf.SysConfig.Msgserver, []int{util.SERVICE_DISTINGUISH}, 20)
 	client.ResetMyName("识别验证码")
 }
@@ -41,24 +42,28 @@ func processevent(p *util.Packet) {
 	event := int(p.Event)
 	switch event {
 	case util.SERVICE_DISTINGUISH:
-		log.Println("------从消息总线接收到了一个消息-----")
+		log.Println("------接收到消息的数据-----")
 		//写数据
 		if ret := make(map[string]interface{}); json.Unmarshal(p.GetBusinessData(), &ret) == nil {
 			flag, _ := ret["flag"].(bool)
 			if flag {
+				img, _ := ret["img"]
+				if img == nil {
+					return
+				}
 				imgTmp, err := json.Marshal(ret["img"])
 				if err != nil {
 					return
 				}
-				var img []byte
-				err = json.Unmarshal(imgTmp, &img)
+				var imgbyte []byte
+				err = json.Unmarshal(imgTmp, &imgbyte)
 				if err != nil {
 					return
 				}
 				obj := map[string]interface{}{
 					"from":  p.From,
 					"msgId": p.Msgid,
-					"img":   img,
+					"img":   imgbyte,
 				}
 				if len(workers) == 0 {
 					waitWorks = append(waitWorks, obj)
@@ -75,7 +80,7 @@ func processevent(p *util.Packet) {
 //开始工作,记录工作人的相关数
 func (a *DistinguishWork) Start(openId string) {
 	if client == nil {
-		initDgWork()
+		InitDgWork()
 	}
 	for _, v := range workers {
 		if v["openId"] == openId {
@@ -88,6 +93,10 @@ func (a *DistinguishWork) Start(openId string) {
 
 //结束工作,删除工作人
 func (a *DistinguishWork) End(openId string) {
+	end(openId)
+}
+
+func end(openId string) {
 	deleteWorker(openId)
 	for k, v := range workers {
 		if v["openId"] == openId {
@@ -149,59 +158,106 @@ func deleteWorker(openId string) {
 
 //进行一个任务
 func toWork(o map[string]interface{}) {
-	openId, obj, err := worked(o)
-	if err == nil {
+	openId, obj, status := worked(o)
+	if openId == "" || status == 0 { //成功 || 该任务无效
 		return
 	}
-	//如果任务在执行过程中出现异常,把该任务放入等待队列中,修改这个人的状态为空闲
-	obj["status"] = "-1"
-	waitWorks = append(waitWorks, obj)
+	if obj == nil || status == -1 {
+		deleteWorker(openId)
+		updateWorker(openId, status_rest)
+		return
+	}
+	obj["status"] = status
+	errorCount := qfwutil.IntAll(obj["errorCount"])
+	if status == -2 {
+		errorCount++
+		if errorCount >= qfwutil.IntAll(wf.SysConfig.DistinguishWork["errorCount"]) { //没有超过失败次数
+			deleteWorker(openId)
+			updateWorker(openId, status_rest)
+			return
+		}
+		obj["errorCount"] = errorCount
+	}
+	if status == -4 { //发送模板消息失败
+		end(openId)
+		toWork(obj)
+		return
+	}
+	//把该任务放入等待队列中第一个,修改这个人的状态为空闲
+	var waitWorksCopy []map[string]interface{}
+	waitWorksCopy = append(waitWorksCopy, obj)
+	for _, v := range waitWorks {
+		waitWorksCopy = append(waitWorksCopy, v)
+	}
+	waitWorks = waitWorksCopy
 	deleteWorker(openId)
 	updateWorker(openId, status_rest)
 }
 
-func worked(o map[string]interface{}) (string, map[string]interface{}, error) {
+func worked(o map[string]interface{}) (string, map[string]interface{}, int) {
 	openId, obj := getWorker(o)
 	if openId == "" { //没有闲人
-		return openId, obj, nil
+		return openId, obj, 0
+	}
+	from, ok := obj["from"].(string)
+	msgId, ok := obj["msgId"].(string)
+	img, ok := obj["img"].([]byte)
+	if !ok {
+		log.Println("获取到的数据不完整:", obj)
+		return openId, obj, -1
+	}
+	var name string
+	var err error
+	if imgName := obj["imgName"]; imgName != nil {
+		name, _ = imgName.(string)
+	} else {
+		//生成验证码图片
+		name, err = createImg(msgId, img)
+		obj["imgName"] = name
 	}
-	from := obj["from"].(string)
-	msgId := obj["msgId"].(string)
-	img := obj["img"].([]byte)
-	//生成验证码图片
-	name, err := createImg(msgId, img)
 	if name == "" || err != nil {
 		log.Println("生成验证码图片出错:", err)
-		return openId, obj, err
+		return openId, obj, -2
 	}
 	workering[openId] = []string{msgId, from}
 	//发送验证码图片
-	var e error
+	var itm qrpc.News
+	itm.ToUser = openId
+
+	var als qrpc.Article
+	als.Title = wf.SysConfig.DistinguishWork["title"].(string)
+	als.Description = wf.SysConfig.DistinguishWork["description"].(string)
+	als.Url = wf.SysConfig.Qmxcdn + "/upload/spider/" + name
+	als.PicUrl = wf.SysConfig.Qmxcdn + "/upload/spider/" + name
+
+	itm.Articles = append(itm.Articles, als)
+
+	var status = 0
 	qfwutil.Try(func() {
 		client, err := rpc.DialHTTP("tcp", wf.SysConfig.Rpcserver)
 		defer client.Close()
 		if err != nil {
 			log.Println(err.Error())
-			e = err
+			status = -3
 			return
 		}
 		var repl qrpc.RpcResult
-		err = client.Call("WeiXinRpc.SendManagerNotifyMsg", &qrpc.NotifyMsg{
+		err = client.Call("WeiXinRpc.SendNews", itm, &repl)
+		/*err = client.Call("WeiXinRpc.SendManagerNotifyMsg", &qrpc.NotifyMsg{
 			Openid: openId,
 			Title:  wf.SysConfig.DistinguishWork["title"],
 			Detail: wf.SysConfig.DistinguishWork["detail"],
 			Result: wf.SysConfig.DistinguishWork["result"],
 			Url:    wf.SysConfig.Qmxcdn + "/upload/spider/" + name,
-		}, &repl)
+		}, &repl)*/
 		if err != nil {
 			log.Println(err.Error())
-			e = err
-			return
+			status = -4
 		} else {
 			updateWorker(openId, status_waitReply)
 		}
 	}, func(e interface{}) {})
-	return openId, obj, e
+	return openId, obj, status
 }
 
 //修改这个人的状态为等待回复
@@ -239,8 +295,12 @@ func getWorker(obj map[string]interface{}) (openId string, object map[string]int
 	tmp_index := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(tmp_length)
 	workers_index := tmp[tmp_index]
 	workers[workers_index]["status"] = status_working
-	openId = workers[workers_index]["openId"].(string)
+	openId, _ = workers[workers_index]["openId"].(string)
 	if len(waitWorks) > 0 {
+		//把该任务加入等待队列
+		if obj != nil {
+			waitWorks = append(waitWorks, obj)
+		}
 		object = waitWorks[0]
 		//删除第一个
 		waitWorks = waitWorks[1:]
@@ -265,14 +325,28 @@ func createImg(msgId string, img []byte) (string, error) {
 		log.Println("创建验证码图片出错:", err)
 		return "", err
 	}
+	defer file.Close()
 	_, err = file.Write(img)
 	if err != nil {
 		log.Println("写入验证码图片出错:", err)
 		return "", err
 	}
-	defer file.Close()
+	newName, e := image.MakeResize(path+"/"+name, 640, 320, 100, 0)
+	if e == nil {
+		//删除老文件
+		file.Close()
+		if e = os.Remove(path + "/" + name); e != nil {
+			return newName, nil
+		}
+		os.Rename(path+"/"+newName, path+"/"+name)
+	}
 	return name, nil
 }
+
+func Distinguishworkinit(w http.ResponseWriter, r *http.Request) {
+	var distinguishWork DistinguishWork
+	distinguishWork.Start("o8-2pwHj1s_tv3nnRxrH9cD2ngkk")
+}
 func Monitor(w http.ResponseWriter, r *http.Request) {
 	var h_p, h_w, h_wa string
 	for _, v := range workers {
@@ -282,8 +356,10 @@ func Monitor(w http.ResponseWriter, r *http.Request) {
 		h_w += fmt.Sprint(k) + ":" + fmt.Sprint(v) + "<br>"
 	}
 	for _, v := range waitWorks {
+		img := v["img"]
 		delete(v, "img")
 		h_wa += fmt.Sprint(v) + "<br>"
+		v["img"] = img
 	}
 	if h_p == "" {
 		h_p = "无"

+ 4 - 4
weixin/src/qfw/weixin/msgtxtchandler.go

@@ -107,15 +107,15 @@ func MsgTxtHandler(w ResponseWriter, r *Request) {
 			PicUrl:      wf.SysConfig.Qmxcdn + "/images/swordfish/jianyu_weixin.jpg",
 			Url:         "http://mp.weixin.qq.com/s?__biz=MzA5MTk0MTk5Ng==&mid=406103124&idx=1&sn=c12f1cc34899f0c3b36492885567315a#rd",
 		}})
-	} else if !distinguishWork.IsWorking(openid) && r.Content == "开始识别验证码" { //进入人工识别验证码工作
-		w.ReplyText(wf.SysConfig.DistinguishWork["in"])
+	} else if r.Content == "开始识别验证码" { //进入人工识别验证码工作
+		w.ReplyText(wf.SysConfig.DistinguishWork["in"].(string))
 		distinguishWork.Start(openid)
 	} else if distinguishWork.IsWorking(openid) { //人工识别验证码工作中。。。
 		if r.Content == "结束识别验证码" {
-			w.ReplyText(wf.SysConfig.DistinguishWork["out"])
+			w.ReplyText(wf.SysConfig.DistinguishWork["out"].(string))
 			distinguishWork.End(openid)
 		} else if distinguishWork.IsWaitReply(openid) {
-			w.ReplyText(wf.SysConfig.DistinguishWork["reply"])
+			w.PostText(wf.SysConfig.DistinguishWork["reply"].(string))
 			distinguishWork.Reply(openid, r.Content)
 		}
 	} else {

+ 12 - 4
weixin/src/qfw/weixin/rpc/rpc.go

@@ -203,13 +203,21 @@ func (wxrpc *WeiXinRpc) SendOffLineMsg(param *qrpc.NotifyMsg, ret *qrpc.RpcResul
 }
 
 //发送图文消息
-func (wxrpc *WeiXinRpc) SendImgTextMsg(param *qrpc.ImgTextMsg, ret *qrpc.RpcResult) (err error) {
-	param.MsgType = "news"
-	err = wxrpc.wx.PostTextCustom(itmapi_url, param)
+func (wxrpc *WeiXinRpc) SendNews(param *qrpc.News, ret *qrpc.RpcResult) (err error) {
+	var articles []weixin.Article
+	for _, v := range param.Articles {
+		articles = append(articles, weixin.Article{
+			Title:       v.Title,
+			Description: v.Description,
+			Url:         v.Url,
+			PicUrl:      v.PicUrl,
+		})
+	}
+	err = wxrpc.wx.PostNews(param.ToUser, articles)
 	if err != nil {
 		log.Println(err.Error())
 	} else {
-		log.Println("send imgTextMsg success!")
+		log.Println("send news success!")
 	}
 	return
 }

+ 37 - 37
weixin/src/qfw/weixinconfig/weixinconfig.go

@@ -2,43 +2,43 @@ package weixinconfig
 
 //微信配置文件
 type wxconfig struct {
-	Domain                string            `json:"domain"`
-	Port                  string            `json:"port"`
-	Imgpath               string            `json:"imgpath"`
-	Redisservers          string            `json:"redisServers"`   //redis缓存服务器列表
-	Mongodbservers        string            `json:"mongodbServers"` //mongodb节点
-	MongodbPoolSize       int               `json:"mongodbPoolSize"`
-	MongodbName           string            `json:"mongodbName"`
-	Elasticsearch         string            `json:"elasticsearch"`
-	Rpcport               string            `json:"rpcport"`
-	ServiceTip            string            `json:"serviceTip"`
-	Appcontext            string            `json:"appcontext"`
-	Appid                 string            `json:"appid"`
-	Token                 string            `json:"token"`
-	Appsecret             string            `json:"appsecret"`
-	Aboutmeurl            string            `json:"aboutmeurl"`
-	Conactusurl           string            `json:"conactusurl"`
-	ElasticPoolSize       int               `json:"elasticPoolSize"`
-	Wsqurl                string            `json:"wsqurl"`
-	EntAuthTip            string            `json:"entAuthTip"`
-	PerAuthTip            string            `json:"perAuthTip"`
-	OthAuthTip            string            `json:"othAuthTip"`
-	MessageTpl            map[string]string `json:"messagetpl"` //消息模板配置
-	WelcomeTip            string            `json:"welcomeTip"`
-	OWelcomeTip           string            `json:"oWelcomeTip"`
-	LoginTip              string            `json:"loginTip"`
-	FreezeTip             string            `json:"freezeTip"`
-	Activity              map[string]string `json:"activity"` //活动配置
-	WeixinAutoRpl         string            `json:"weixinautorpl"`
-	WeixinAutoRpl2        string            `json:"weixinautorpl2"`
-	SubscribeMonitorCyc   int               `json:"subscribemonitorcyc"`
-	SubscribeMonitorTimes int               `json:"subscribemonitortimes"`
-	Mids                  []string          `json:"mids"`
-	Dir                   string            `json:"dir"`
-	DistinguishWork       map[string]string `json:"distinguishWork"`
-	Rpcserver             string            `json:"rpcserver"`
-	Msgserver             string            `json:"msgserver"`
-	Qmxcdn                string            `json:"qmxcdn"`
+	Domain                string                 `json:"domain"`
+	Port                  string                 `json:"port"`
+	Imgpath               string                 `json:"imgpath"`
+	Redisservers          string                 `json:"redisServers"`   //redis缓存服务器列表
+	Mongodbservers        string                 `json:"mongodbServers"` //mongodb节点
+	MongodbPoolSize       int                    `json:"mongodbPoolSize"`
+	MongodbName           string                 `json:"mongodbName"`
+	Elasticsearch         string                 `json:"elasticsearch"`
+	Rpcport               string                 `json:"rpcport"`
+	ServiceTip            string                 `json:"serviceTip"`
+	Appcontext            string                 `json:"appcontext"`
+	Appid                 string                 `json:"appid"`
+	Token                 string                 `json:"token"`
+	Appsecret             string                 `json:"appsecret"`
+	Aboutmeurl            string                 `json:"aboutmeurl"`
+	Conactusurl           string                 `json:"conactusurl"`
+	ElasticPoolSize       int                    `json:"elasticPoolSize"`
+	Wsqurl                string                 `json:"wsqurl"`
+	EntAuthTip            string                 `json:"entAuthTip"`
+	PerAuthTip            string                 `json:"perAuthTip"`
+	OthAuthTip            string                 `json:"othAuthTip"`
+	MessageTpl            map[string]string      `json:"messagetpl"` //消息模板配置
+	WelcomeTip            string                 `json:"welcomeTip"`
+	OWelcomeTip           string                 `json:"oWelcomeTip"`
+	LoginTip              string                 `json:"loginTip"`
+	FreezeTip             string                 `json:"freezeTip"`
+	Activity              map[string]string      `json:"activity"` //活动配置
+	WeixinAutoRpl         string                 `json:"weixinautorpl"`
+	WeixinAutoRpl2        string                 `json:"weixinautorpl2"`
+	SubscribeMonitorCyc   int                    `json:"subscribemonitorcyc"`
+	SubscribeMonitorTimes int                    `json:"subscribemonitortimes"`
+	Mids                  []string               `json:"mids"`
+	Dir                   string                 `json:"dir"`
+	DistinguishWork       map[string]interface{} `json:"distinguishWork"`
+	Rpcserver             string                 `json:"rpcserver"`
+	Msgserver             string                 `json:"msgserver"`
+	Qmxcdn                string                 `json:"qmxcdn"`
 }
 
 //系统配置