Kaynağa Gözat

微信功能增强

renzheng 9 yıl önce
ebeveyn
işleme
61646c385f

+ 15 - 0
common/src/qfw/util/mongodb/mongodbutil_test.go

@@ -82,3 +82,18 @@ func Test_reg(t *testing.T) {
 	log.Println(con.ReplaceAllString(s, ""))
 
 }
+
+func Test_aggregate(t *testing.T) {
+	InitMongodbPool(1, "192.168.3.18:27080", "qfw")
+	sess := GetMgoConn()
+	defer DestoryMongoConn(sess)
+	var res []M
+	sess.DB("qfw").C("user").Pipe([]M{M{"$match": M{"l_registedate": M{"$gte": 1436326192}}},
+		M{"$group": M{"_id": "$black", "count": M{"$sum": 1}}}}).All(&res)
+	var sun int
+	for _, v := range res {
+		log.Println(v["_id"] == nil)
+	}
+	log.Println(res, sun)
+
+}

+ 1 - 2
core/src/qfw/coreutil/Int64_test.go

@@ -27,6 +27,5 @@ func TestBase64(t *testing.T) {
 }
 
 func Test_spit(t *testing.T) {
-	s := "41"
-	log.Println(s[:2])
+
 }

+ 3 - 1
weixin/src/config.json

@@ -36,6 +36,8 @@
 	},"weixinautorpl":"小主的吩咐我们已经收到了,请留下您的联系方式(手机号或qq号),企明星客服会在下一个工作日9:00-17:00给小主回复哦!",
 	"creditRpc":"127.0.0.1:8765",
 	"subscribemonitorcyc":3,
-	"subscribemonitortimes":12
+	"subscribemonitortimes":12,
+	"mids":["oJULtwzXo6EFV1Ah-XeyRBimXGM8"],
+	"dir":"/opt/mntdisk/qfw-v1.1"
 
 }

+ 6 - 0
weixin/src/qfw/weixin/msgtxtchandler.go

@@ -59,11 +59,17 @@ func MsgTxtHandler(w ResponseWriter, r *Request) {
 			processOIdentifyMsgTxt(us, w, r)
 		} else if us.Type == "robot" { //聊天机器人
 			processRobotMsg(r.FromUserName, r.Content, w, r)
+		} else if us.Type == "wxadmin" {
+			processWxAdmin(openid, r.Content, w, r)
 		}
 	} else if r.Content == "小星" {
 		UserSession[r.FromUserName] = NewUserSession("robot")
 		w.ReplyText("嗨,小星来陪你解闷。有什么开心的,不开心的说说来,大伙乐呵乐呵。\n输入q或Q离开。")
 		return
+	} else if r.Content == "微信管理" && mids[openid] {
+		UserSession[r.FromUserName] = NewUserSession("wxadmin")
+		w.ReplyText("您已进入微信管理,请输入指令操作:\n1.查看抽奖模式(指令:f0)\n2.切换抽奖模式(指令:c*,*为数字。如c0(自动模式),c1(手动模式1),c2(手动模式2),c3(手动模式3))\n3.统计抽奖结果(tjr*,tjr120(最近两分钟),tjr120-1200(最近两分钟至最近20分钟之间的))\n4.统计新用户数(tju*)\n5.服务器情况监测(ser0)\n6服务管理(man*,man1重启主程序(man11关闭),man2重启微信,man3重启积分(man33关闭),man4重启微信认证(man44关闭))。\n输入q或Q离开。")
+		return
 	} else if r.Content == "抽奖" { //进入抽奖环节
 		//w.ReplyText("非常抱歉!系统维护中,请稍后再试。")
 		targeturl := fmt.Sprintf("http://%s/activity/%s/%s", wf.SysConfig.Domain, wf.SysConfig.Activity["activitycode"], se.EncodeString(r.FromUserName))

+ 4 - 1
weixin/src/qfw/weixin/txt_test.go

@@ -2,6 +2,7 @@ package weixin
 
 import (
 	"log"
+	"regexp"
 	"testing"
 	"time"
 )
@@ -13,5 +14,7 @@ func TestWeek(t *testing.T) {
 }
 
 func TestWord(t *testing.T) {
-	log.Println(len("内部报名"))
+	reg := regexp.MustCompile("^([a-z]+)(\\d.*)$")
+	s := reg.FindSubmatch([]byte("esddfdsf23s-15s"))
+	log.Println(len(s))
 }

+ 345 - 0
weixin/src/qfw/weixin/wxadmin.go

@@ -0,0 +1,345 @@
+package weixin
+
+import (
+	"fmt"
+	. "gopkg.in/mgo.v2/bson"
+	"io/ioutil"
+	"os/exec"
+	"qfw/util"
+	"qfw/util/mongodb"
+	"qfw/util/redis"
+	"qfw/weixinconfig"
+	"regexp"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var mids = map[string]bool{}
+var reg = regexp.MustCompile("^([a-z]+)(\\d.*)$")
+var subreg = regexp.MustCompile("^(\\d+)([smhd]{0,1})$")
+var DIR = ""
+
+func init() {
+	for _, v := range weixinconfig.SysConfig.Mids {
+		mids[v] = true
+	}
+	DIR = weixinconfig.SysConfig.Dir
+}
+
+func processWxAdmin(openid, content string, w ResponseWriter, r *Request) {
+	/*
+		reg := regexp.MustCompile("^([a-z]+)(\\d.*)$")
+		reg2 := regexp.MustCompile("^(\\d+)([smhd])$")
+		s := reg.FindSubmatch([]byte("aaaaa23s-15s"))
+		s2 := strings.Split(string(s[2]), "-")
+		s2s := reg2.FindSubmatch([]byte(s2[0]))
+	*/
+	if openid != "" {
+		b, cmd, qleng, unit, var1, var2 := checkContent(content)
+		if b {
+			resStr := ""
+			switch cmd {
+			case "f":
+				//查看抽奖模式
+				resStr = getMode()
+			case "c":
+				//切换抽奖模式
+				if var1 >= 0 && var1 <= 3 {
+					br := redis.Put("other", "s_luckydraw_mode", fmt.Sprintf("%d", var1), 0)
+					if br {
+						resStr = "模式已切换:" + getMode()
+					}
+				}
+			case "tjr":
+				//数据库抽奖查看
+				var1, var2 = getTimes(qleng, unit, var1, var2)
+				qu1 := M{"$gte": var1}
+				if qleng == 2 { //取区间
+					qu1 = M{"$gte": var2, "$lte": var1}
+				} else {
+					w.ReplyText("指令异常,请重新输入。")
+					return
+				}
+				util.Try(func() {
+					sess := mongodb.GetMgoConn()
+					defer mongodb.DestoryMongoConn(sess)
+					var res []M
+					sess.DB("qfw").C("winningrecord").Pipe([]M{M{"$match": M{"l_timestamp": qu1}},
+						M{"$group": M{"_id": "$s_prize", "count": M{"$sum": 1}}}}).All(&res)
+					if res != nil && len(res) > 0 {
+						sum := 0
+						for _, v := range res {
+							resStr += "\n" + v["_id"].(string) + ":" + fmt.Sprintf("%x", v["count"])
+							sum += v["count"].(int)
+						}
+						resStr += "\n" + "总数:" + fmt.Sprintf("%d", sum)
+					}
+				}, func(e interface{}) {})
+			case "tju":
+				//新用户查看
+				var1, var2 = getTimes(qleng, unit, var1, var2)
+				qu1 := M{"$gte": var1}
+				if qleng == 2 { //取区间
+					qu1 = M{"$gte": var2, "$lte": var1}
+				} else {
+					w.ReplyText("指令异常,请重新输入。")
+					return
+				}
+				util.Try(func() {
+					sess := mongodb.GetMgoConn()
+					defer mongodb.DestoryMongoConn(sess)
+					var res []M
+					sess.DB("qfw").C("user").Pipe([]M{M{"$match": M{"l_registedate": qu1}},
+						M{"$group": M{"_id": "$black", "count": M{"$sum": 1}}}}).All(&res)
+					if res != nil && len(res) > 0 {
+						sum := 0
+						for _, v := range res {
+							resStr += "\n" + util.If(v["_id"] == nil, "黑名单用户", "正常用户").(string) + ":" + fmt.Sprintf("%x", v["count"])
+							sum += v["count"].(int)
+						}
+						resStr += "\n" + "总数:" + fmt.Sprintf("%d", sum)
+					}
+				}, func(e interface{}) {})
+			case "ser":
+				//服务器实时统计情况
+				//各端口,及连接数
+				//总连接数
+				resStr = getServer()
+			case "man":
+				switch var1 {
+				case 1:
+					//重启core
+					cmdstr := getNewCmd(DIR, "core2016")
+					if len(cmdstr) > 0 {
+						execCmd(DIR, "core2016", cmdstr, true)
+					}
+					resStr = "重启主程序完成"
+				case 11:
+					//关闭core
+					cmdstr := getNewCmd(DIR, "core2016")
+					if len(cmdstr) > 0 {
+						execCmd(DIR, "core2016", cmdstr, false)
+					}
+					resStr = "关闭主程序完成"
+				case 2:
+					//重启weixin
+					cmdstr := getNewCmd(DIR+"/weixin", "weixin")
+					if len(cmdstr) > 0 {
+						execCmd(DIR+"/weixin", "weixin", cmdstr, true)
+					}
+					resStr = "重启微信程序完成"
+				case 22:
+				//不能关闭微信
+				case 3:
+					//重启积分
+					cmdstr := getNewCmd(DIR+"/credit", "credit")
+					if len(cmdstr) > 0 {
+						execCmd(DIR+"/credit", "credit", cmdstr, true)
+					}
+					resStr = "重启积分程序完成"
+				case 33:
+					cmdstr := getNewCmd(DIR+"/credit", "credit")
+					if len(cmdstr) > 0 {
+						execCmd(DIR+"/credit", "credit", cmdstr, false)
+					}
+					resStr = "关闭积分程序完成"
+				//关闭积分
+				case 4:
+					//重启oauth
+					cmdstr := getNewCmd(DIR+"/proxy", "oauth")
+					if len(cmdstr) > 0 {
+						execCmd(DIR+"/proxy", "oauth", cmdstr, true)
+					}
+					resStr = "重启微信程认证序完成"
+				case 44:
+					//关闭oauth
+					cmdstr := getNewCmd(DIR+"/proxy", "oauth")
+					if len(cmdstr) > 0 {
+						execCmd(DIR+"/proxy", "oauth", cmdstr, false)
+					}
+					resStr = "关闭微信程认证序完成"
+				}
+			}
+			w.ReplyText(resStr)
+		} else {
+			w.ReplyText("指令不存在,请重新输入。")
+		}
+	} else {
+		w.ReplyText("用户信息不存在,请重新进入。")
+		delete(UserSession, openid)
+	}
+}
+
+func getNewCmd(dir, substr string) string {
+	return getServerCmd(fmt.Sprintf(`ls -lt %s | grep %s |awk '{print $9}' |head -1`, dir, substr))
+}
+
+func execCmd(dir, subcmdstr, cmdstr string, bstart bool) bool {
+	exec.Command("/bin/sh", "-c", fmt.Sprintf(`ps -ef | grep %s | grep -v "grep" | awk '{print $2}' |xargs kill -9`, subcmdstr)).Run()
+	if bstart {
+		cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf(`cd %s&& nohup ./%s &`, dir, cmdstr))
+		err := cmd.Run()
+		if err != nil {
+			return false
+		} else {
+			return true
+		}
+	} else {
+		return true
+	}
+}
+
+//获取服务器状态
+func getServer() (str string) {
+	util.Try(func() {
+		tmpStr := getServerCmd(`lsof -i|awk '{print $1}' | uniq -c | sort -nr`)
+		str = tmpStr
+		strs := strings.Split(tmpStr, "\n")
+		n := 0
+		for _, v := range strs {
+			tmps := strings.Split(strings.TrimSpace(v), " ")
+			if len(tmps) == 2 {
+				v, _ := strconv.Atoi(tmps[0])
+				n += v
+			}
+		}
+		str += "\n总连接数:" + fmt.Sprintf("%d", n)
+	}, func(e interface{}) {})
+	return
+}
+
+func getServerCmd(c string) (str string) {
+	cmd := exec.Command("/bin/bash", "-c", c)
+	stdout, err := cmd.StdoutPipe()
+	if err != nil {
+		str = "StdoutPipe: " + err.Error()
+		return
+	}
+	stderr, err := cmd.StderrPipe()
+	if err != nil {
+		str = "StderrPipe: " + err.Error()
+		return
+	}
+	if err := cmd.Start(); err != nil {
+		str = "Start: " + err.Error()
+		return
+	}
+	bytesErr, err := ioutil.ReadAll(stderr)
+	if err != nil {
+		str = "ReadAll stderr: " + err.Error()
+		return
+	}
+	if len(bytesErr) != 0 {
+		str = fmt.Sprintf("stderr is not nil: %s", bytesErr)
+		return
+	}
+	bytes, err := ioutil.ReadAll(stdout)
+	if err != nil {
+		str = "ReadAll stdout: " + err.Error()
+		return
+	}
+	if err := cmd.Wait(); err != nil {
+		str = "Wait: " + err.Error()
+		return
+	}
+	tmpStr := string(bytes)
+	str = strings.Trim(tmpStr, "\n")
+	return
+}
+
+//根据区间算时间0没取
+func getTimes(qlen int, unit string, var1, var2 int64) (v1, v2 int64) {
+	now := time.Now().Unix()
+	switch unit {
+	case "m":
+		var1 = var1 * 60
+		var2 = var2 * 60
+	case "h":
+		var1 = var1 * 3600
+		var2 = var2 * 3600
+	case "d":
+		var1 = var1 * 86400
+		var2 = var2 * 86400
+	}
+	v1 = now - var1
+	v2 = now - var2
+	return
+
+}
+
+//取抽奖模式
+func getMode() (resStr string) {
+	mode := redis.GetStr("other", "s_luckydraw_mode")
+	if mode == "0" {
+		resStr = "自动模式"
+	} else {
+		if mode == "" {
+			mode = "3"
+		}
+		resStr = "手动模式-" + mode
+	}
+	return
+}
+
+//解析内容
+func checkContent(con string) (b bool, cmd string, qleng int, unit string, var1, var2 int64) {
+	conOne := reg.FindSubmatch([]byte(con))
+	if len(conOne) == 3 {
+		str2 := strings.Split(string(conOne[2]), "-")
+		cmd = string(conOne[1])
+		if len(str2) == 1 {
+			qleng = 1
+			conTwo := subreg.FindSubmatch([]byte(str2[0]))
+			if len(conTwo) == 2 {
+				unit = "s"
+			} else if len(conTwo) == 3 {
+				if len(conTwo[2]) > 0 {
+					unit = string(conTwo[2])
+				} else if unit == "" {
+					unit = "s"
+				}
+			} else {
+				return
+			}
+			b = true
+			vartemp, _ := strconv.Atoi(string(conTwo[1]))
+			var1 = int64(vartemp)
+		} else if len(str2) == 2 {
+			qleng = 2
+			conTwo := subreg.FindSubmatch([]byte(str2[0]))
+			if len(conTwo) == 2 {
+				unit = "s"
+			} else if len(conTwo) == 3 {
+				if len(conTwo[2]) > 0 {
+					unit = string(conTwo[2])
+				} else if unit == "" {
+					unit = "s"
+				}
+			} else {
+				return
+			}
+			vartemp, _ := strconv.Atoi(string(conTwo[1]))
+			var1 = int64(vartemp)
+
+			conTwo2 := subreg.FindSubmatch([]byte(str2[1]))
+			if len(conTwo2) == 2 && unit == "" {
+				unit = "s"
+			} else if len(conTwo2) == 3 {
+				if len(conTwo2[2]) > 0 {
+					unit = string(conTwo2[2])
+				} else if unit == "" {
+					unit = "s"
+				}
+			} else {
+				return
+			}
+			vartemp2, _ := strconv.Atoi(string(conTwo2[1]))
+			var2 = int64(vartemp2)
+			b = true
+		} else {
+			return
+		}
+	}
+	return
+}

+ 10 - 2
weixin/src/qfw/weixinconfig/config_test.go

@@ -1,8 +1,16 @@
 package weixinconfig
 
-import ()
+import (
+	"log"
+	"regexp"
+	"testing"
+)
 
 //初始化
 func TestReadConfig(t *testing.T) {
-
+	r := regexp.MustCompile("^([a-z]+)(\\d.*)$")
+	s := r.FindSubmatch([]byte("esddfdsf23s-15s"))
+	for _, v := range s {
+		log.Println(string(v))
+	}
 }

+ 32 - 30
weixin/src/qfw/weixinconfig/weixinconfig.go

@@ -2,36 +2,38 @@ 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"`
-	SubscribeMonitorCyc int `json:"subscribemonitorcyc"`
-	SubscribeMonitorTimes int `json:"subscribemonitortimes"`
+	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"`
+	SubscribeMonitorCyc   int               `json:"subscribemonitorcyc"`
+	SubscribeMonitorTimes int               `json:"subscribemonitortimes"`
+	Mids                  []string          `json:"mids"`
+	Dir                   string            `json:"dir"`
 }
 
 //系统配置