Преглед на файлове

Merge branch 'develop' of 192.168.3.17:zhanghongbo/qfw into develop

wangchuanjin преди 9 години
родител
ревизия
24a05f5c2f
променени са 44 файла, в които са добавени 937 реда и са изтрити 522 реда
  1. 2 0
      common/src/qfw/util/elastic/elasticutil.go
  2. 6 0
      common/src/qfw/util/elastic/elasticutil_test.go
  3. 6 0
      common/src/qfw/util/rpc/push.go
  4. 66 4
      core/src/qfw/active/activemanage.go
  5. 36 1
      core/src/qfw/front/index.go
  6. 2 1
      core/src/qfw/manage/auditing.go
  7. 0 2
      core/src/qfw/member/credit/creditdetail.go
  8. 2 1
      core/src/timetask.json
  9. 0 1
      core/src/web/staticres/css/dev-qfw.css
  10. 70 6
      core/src/web/staticres/css/index-new.css
  11. BIN
      core/src/web/staticres/images/activeimages/btn_end.png
  12. BIN
      core/src/web/staticres/images/creditchengzhang.png
  13. BIN
      core/src/web/staticres/images/u0115.png
  14. BIN
      core/src/web/staticres/images/u0116.png
  15. BIN
      core/src/web/staticres/images/u0117.png
  16. BIN
      core/src/web/staticres/images/u0118.png
  17. BIN
      core/src/web/staticres/images/u0119.png
  18. BIN
      core/src/web/staticres/images/u0120.png
  19. BIN
      core/src/web/staticres/images/u2181.png
  20. 2 2
      core/src/web/staticres/wxswordfish/share.js
  21. 22 16
      core/src/web/templates/active/luckdraw.html
  22. 42 2
      core/src/web/templates/common/memberleft.html
  23. 122 1
      core/src/web/templates/index.html
  24. 90 2
      core/src/web/templates/member/credit/creditrule.html
  25. 1 1
      core/src/web/templates/member/credit/mycredit.html
  26. 4 0
      push/src/config.json
  27. 13 0
      push/src/main.go
  28. 9 208
      push/src/qfw/push/bid/bidpushjob.go
  29. 25 35
      push/src/qfw/push/cache.go
  30. 16 0
      push/src/qfw/push/dfa/interestanalysis_test.go
  31. 221 0
      push/src/qfw/push/dopush/dopush.go
  32. 29 0
      push/src/qfw/push/rpcpush/rpcpush.go
  33. 9 212
      push/src/qfw/push/tender/tenderpushjob.go
  34. 4 6
      weixin/src/config.json
  35. 10 0
      weixin/src/qfw/weixin/dao/logsdao.go
  36. 43 0
      weixin/src/qfw/weixin/dao/sharedao.go
  37. 2 7
      weixin/src/qfw/weixin/dao/userdao.go
  38. 9 1
      weixin/src/qfw/weixin/msgtxtchandler.go
  39. 46 0
      weixin/src/qfw/weixin/rpc/share.go
  40. 11 4
      weixin/src/qfw/weixin/subscribehandler.go
  41. 13 0
      weixin/src/qfw/weixin/txt_test.go
  42. 2 0
      weixin/src/qfw/weixin/weixinsdk.go
  43. 1 9
      weixin/src/qfw/weixinconfig/config_test.go
  44. 1 0
      weixin/src/qfw/weixinconfig/weixinconfig.go

+ 2 - 0
common/src/qfw/util/elastic/elasticutil.go

@@ -580,6 +580,8 @@ func ConverData(ent *map[string]interface{}) map[string]interface{} {
 	tmp2["OpScope"] = tmp["OpScope"]
 	tmp2["OpState"] = tmp["OpState"]
 	tmp2["s_submitid"] = tmp["s_submitid"]
+	tmp2["l_submittime"] = tmp["l_submittime"]
+	tmp2["s_submitname"] = tmp["s_submitname"]
 	//增加营业状态排序
 	if tmp2["OpState"] == "06" {
 		tmp2["OpSint"] = true

+ 6 - 0
common/src/qfw/util/elastic/elasticutil_test.go

@@ -183,3 +183,9 @@ func Test_date(t *testing.T) {
 	s := time.Now().UnixNano()
 	log.Println(s, time.Now().Unix(), fmt.Sprintf("%d", s)[4:12], 999999/60/60)
 }
+
+func Test_Getpage(t *testing.T) {
+	InitElasticSize("http://192.168.3.18:9800", 1)
+	data := *GetPage("enterprise", "enterprise", `{"s_action":"01"}`, `{"l_submittime":-1}`, `"EntName","l_submittime","_id"`, 0, 8)
+	log.Println("data:", data)
+}

+ 6 - 0
common/src/qfw/util/rpc/push.go

@@ -0,0 +1,6 @@
+package rpc
+
+type PushData struct {
+	Mopenid  string
+	PushType map[string]string
+}

+ 66 - 4
core/src/qfw/active/activemanage.go

@@ -6,11 +6,14 @@ package active
 import (
 	"fmt"
 	"github.com/go-xweb/xweb"
+	"gopkg.in/mgo.v2/bson"
 	"math/rand"
 	. "qfw/coreconfig"
+	"qfw/coreutil"
 	mob "qfw/mobile"
 	. "qfw/util"
 	. "qfw/util/mongodb"
+	qrpc "qfw/util/rpc"
 	"strconv"
 	"time"
 )
@@ -26,13 +29,24 @@ func (a *Activemanage) Luckdraw(activecode, id string) error {
 	if activecode == "topcj" {
 		se := SimpleEncrypt{Key: "topnet2015topnet2015"}
 		openid := se.DecodeString(id)
+		f := FindOne("user", "{'s_m_openid':'"+openid+"'}")
+		username := (*f)["s_bindweixin"]
+		userid := (*f)["_id"]
+		if *f == nil {
+			a.T["flog"] = "B"
+			a.T["msg"] = "您的微信号无效!!"
+			return a.Render("/active/luckdraw.html", &a.T)
+		}
 		a.T["signature"] = mob.GetSignature(a.Url())
 		u := FindOne("winningrecord", "{'s_openid':'"+openid+"'}")
 		if *u != nil {
 			//a.T = *u
 			a.T["flog"] = "A"
+			a.T["msg"] = "小主莫贪心,每人只有一次抽奖机会呦!<br/><br/>  小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)"
 			return a.Render("/active/luckdraw.html", &a.T)
 		}
+		a.SetSession("username", username)
+		a.SetSession("userid", userid)
 		a.SetSession("openid", openid)
 		a.SetSession("s_actcode", activecode)
 		return a.Render("/active/luckdraw.html", &a.T)
@@ -44,22 +58,28 @@ func (a *Activemanage) Luckdraw(activecode, id string) error {
 //
 func (a *Activemanage) Getluckdraw() error {
 	flog := "F"
+	//提示语
+	msg := ""
 	id := ""
+	today := time.Now()
 	openid := a.GetSession("openid").(string)
 	s_actcode := a.GetSession("s_actcode").(string)
 	if openid == "" {
-		return a.Write(`{"flog":"` + flog + `"}`)
+		msg = "  小主你太长时间没点击开始抽奖了,重新进来吧!"
+		return a.Write(`{"flog":"` + flog + `","msg":"` + msg + `"}`)
 	} else {
 		u := FindOne("winningrecord", "{'s_openid':'"+openid+"'}")
 		if *u != nil {
 			flog = "A"
-			return a.Write(`{"flog":"` + flog + `"}`)
+			msg = "  小主莫贪心,每人只有一次抽奖机会呦!<br/><br/>  小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)"
+			return a.Write(`{"flog":"` + flog + `","msg":"` + msg + `"}`)
 		}
 	}
 	data := make(map[string]interface{})
 	data["s_openid"] = openid
 	data["s_actcode"] = s_actcode
 	i := getLuckDraw()
+
 	s_prize := getPrize(i)
 	data["s_prize"] = s_prize
 	data["l_timestamp"] = time.Now().Unix()
@@ -67,12 +87,54 @@ func (a *Activemanage) Getluckdraw() error {
 	enddate := LuckDraw.EndDate
 	if nowdate < enddate {
 		id = Save("winningrecord", data)
-		fmt.Println("nowdate:", nowdate, "enddate:", enddate, len(id))
 	}
 	if len(id) > 0 {
 		flog = "T"
 	}
-	return a.Write(`{"flog":"` + flog + `","prize":"` + s_prize + `","rotate":` + strconv.Itoa(int(i)) + `}`)
+	if i > 185 && i < 220 {
+		amount := 500 //红包金额以“元”为单位,微信红包以“分”为单位
+		bm := qrpc.BonusMsg{Mchbillno: fmt.Sprint(today.Unix()),
+			Sendname:    LuckDraw.Weixin["sendname"].(string),
+			Reopenid:    openid,
+			Totalamount: amount,
+			Totalnum:    1,
+			Wishing:     "企明星新年大抽奖",
+			Actname:     "企明星新年大抽奖",
+			Remark:      "欢迎参加企明星新年大抽奖活动!",
+		}
+		if coreutil.PayBonus(&bm) {
+			redpackage := make(bson.M)
+			redpackage["s_userid"] = a.GetSession("userid")
+			redpackage["s_username"] = a.GetSession("username")
+			redpackage["s_openid"] = openid
+			redpackage["i_amount"] = amount
+			redpackage["s_billno"] = bm.Mchbillno
+			redpackage["s_name"] = bm.Actname
+			redpackage["l_createdate"] = today.Unix()
+			redpackage["i_year"] = today.Year()
+			redpackage["i_month"] = today.Month()
+			redpackage["i_day"] = today.Day()
+			redpackage["s_actcode"] = s_actcode
+			Save("redpackage", redpackage)
+		}
+	}
+	if i > 185 && i < 220 {
+		msg = "  小主是真真的好运气,五元现金红包落入您囊中!<br/><br/>  小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)"
+	} else if (i > 275 && i < 310) || (i > 95 && i < 130) {
+		//时间判断,提醒不同
+		now := time.Now()
+		//不在工作时间
+		if now.Weekday() == 6 || now.Weekday() == 0 || (now.Hour() > 18 || now.Hour() < 9) {
+			//
+			msg = "  小主是真真的好运气," + s_prize + "落入您囊中!<br/>  请在微信留下您的联系方式(手机号或qq号),企明星客服会在下一个工作日9:00-17:00给小主回复哦!<br/>  小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)"
+		} else { //在工作时间
+			msg = "  小主是真真的好运气," + s_prize + "落入您囊中,请速速微信联系企明星确认领奖事宜!<br/><br/>  小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)"
+		}
+
+	} else { //不中奖
+		msg = "  小主不要桑心,这次没有中奖不代表什么,猴年依然会好运气爆棚滴~~<br/><br/>  小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)"
+	}
+	return a.Write(`{"flog":"` + flog + `","msg":"` + msg + `","rotate":` + strconv.Itoa(int(i)) + `}`)
 
 }
 

+ 36 - 1
core/src/qfw/front/index.go

@@ -56,13 +56,48 @@ func (i *Index) LoadIndex() error {
 		return i.SetBody([]byte(ret.(string)))
 	} else {
 		i.T["serviceClassify"] = coreconfig.ServiceClassify
+		//企业快报
 		querymap := map[string]string{
 			"perPage":     i.GetString("perPage"),
 			"currentPage": i.GetString("currentPage"),
 			"contentType": "qykb",
 			"query":       i.GetString("query")}
 		data, pagination := searhWebContent(querymap)
-		content, _ := i.Render4Cache("/index.html", &xweb.T{"data": data, "pagination": pagination})
+		//知识库
+		zkquerymap := map[string]string{
+			"perPage":     "8",
+			"currentPage": i.GetString("currentPage"),
+			"contentType": "zhsk",
+			"query":       i.GetString("query")}
+		zkdata, _ := searhWebContent(zkquerymap)
+		if zkdata != nil {
+			for _, v := range *zkdata {
+				release := v["releasetime"].(string)
+				v["releasetime"] = release[:4] + "." + release[5:7] + "." + release[8:10]
+			}
+		}
+		//认证企业
+		entquery := `{"i_identificationstatus":1,"i_freeze":{"$ne":2}}`
+		entdata := *Find("identification", entquery, []string{"-l_auditdate"}, `{"s_enterprisename":1,"l_auditdate":1,"s_enterpriseid":1}`, false, 0, 8)
+		if entdata != nil {
+			for _, v := range entdata {
+				auditdate := v["l_auditdate"].(int64)
+				v["l_auditdate"] = time.Unix(auditdate, 0).Format("2006.01.02")
+			}
+		}
+		//剑鱼最新消息
+		now := time.Now()
+		unix := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()-2, now.Minute(), now.Second(), now.Nanosecond(), time.Local).Unix()
+		sfdata := *Find("bidding", M{"comeintime": M{"$lte": unix}}, `{"comeintime":-1}`, `{"title":1,"href":1,"publishtime":1}`, false, 0, 8)
+		if sfdata != nil {
+			for _, v := range sfdata {
+				publishtime := v["publishtime"].(int64)
+				//:= util.FormatDateWithObj(&data_2, util.Date_Short_Layout)
+				v["publishtime"] = time.Unix(publishtime, 0).Format("2006.01.02")
+			}
+		}
+		//
+		content, _ := i.Render4Cache("/index.html", &xweb.T{"data": data, "pagination": pagination, "zkdata": zkdata, "entdata": entdata, "sfdata": sfdata})
 		redis.Put("other", "/", string(content), 0) //设置首页缓存
 		return i.SetBody(content)
 	}

+ 2 - 1
core/src/qfw/manage/auditing.go

@@ -548,7 +548,7 @@ func (s *SystemManage) Updateaudit() error {
 				tm := fmt.Sprintf("%d", time.Now().Unix())
 				Update("enterprise", &map[string]interface{}{
 					"_id": ObjectIdHex(s_enterpriseid),
-				}, `{'$set':{'s_action':'`+s_action+`','s_avatar':'`+s_avatar+`','EntName':'`+s_enterprisename+`','RegNo':'`+s_id+`','s_submitid':'`+s_submitid+`','s_submitname':'`+s_submitname+`','l_timestamp':`+tm+`}}`, false, false)
+				}, `{'$set':{'s_action':'`+s_action+`','s_avatar':'`+s_avatar+`','EntName':'`+s_enterprisename+`','RegNo':'`+s_id+`','s_submitid':'`+s_submitid+`','s_submitname':'`+s_submitname+`','l_submittime':`+tm+`}}`, false, false)
 				elastic.UpdateEntDoc(s_enterpriseid)
 				if i_identificationtype == "5" {
 					per := FindOne("enterprise", M{"RegNo": s_id_new})
@@ -738,6 +738,7 @@ func (s *SystemManage) Updateaudit() error {
 				}
 				m.SaveMsg()
 			}
+			redis.Del("other", "/")
 			flag = "true"
 			msg = "审核成功!"
 			if (*f)["s_m_openid"] != nil {

+ 0 - 2
core/src/qfw/member/credit/creditdetail.go

@@ -6,7 +6,6 @@ package credit
 import (
 	"github.com/go-xweb/xweb"
 	. "gopkg.in/mgo.v2/bson"
-	"log"
 	"qfw/util"
 	cd "qfw/util/credit"
 	"qfw/util/mongodb"
@@ -162,7 +161,6 @@ func (c *credit) CreditList() error {
 			r[i]["l_date"] = util.FormatDateWithObj(&d, util.Date_Full_Layout)
 		}
 		c.ServeJson(M{"list": r, "count": count})
-		log.Println(r)
 		return nil
 	}
 }

+ 2 - 1
core/src/timetask.json

@@ -1 +1,2 @@
-{"comment":{"c_rate":720,"commentrate":900},"market":{"demand":{"attr":["i_hits","i_bids","i_status"],"timepoint":"2016-01-16 15:02:30"},"service":{"attr":["i_hits","i_sales","i_comments","i_score","i_appcounts"],"timepoint":"2016-01-16 15:02:30"}},"marketisstart":true,"marketrate":300}
+{"comment":{"c_rate":720,"commentrate":900},"market":{"demand":{"attr":["i_hits","i_bids","i_status"],"timepoint":"2016-01-18 14:14:51"},"service":{"attr":["i_hits","i_sales","i_comments","i_score","i_appcounts"],"timepoint":"2016-01-18 14:14:51"}},"marketisstart":true,"marketrate":300}
+

+ 0 - 1
core/src/web/staticres/css/dev-qfw.css

@@ -1003,7 +1003,6 @@ a{
 
 .a-com-ul-block {
 	width: 250px;
-	height:230px;
 }
 .a-com-ul-blocknew {
 	margin-left:1px;

+ 70 - 6
core/src/web/staticres/css/index-new.css

@@ -195,7 +195,7 @@ a:focus, a:hover{
 	margin-right:8px;
 }
 .a-index  .index-new-xwzx-con .index-new-xwzx-title{
-	width:210px;
+	width:200px;
     font-weight: 700;
     font-size: 16px;
 	white-space:nowrap;
@@ -210,7 +210,7 @@ a:focus, a:hover{
 }
 .a-index  .index-new-xwzx-con .index-new-xwzx-content{
 	height:40px;
-	width:210px;
+	width:200px;
     font-family: '宋体 Regular', '宋体';
     font-size: 12px;
     color: #A0A0A0;
@@ -388,7 +388,7 @@ a:focus, a:hover{
 .index-new-wgw-nameent{
 	position:absolute; 
 	z-index:4; 
-	top:184px; 
+	top:199px; 
 	left:10px;
 }
 .index-new-rmfw-nameent a {
@@ -401,7 +401,7 @@ a:focus, a:hover{
 	top:163px; 
 	left:-1px;
 }
-.index-new-rmfw-bg1 span,.index-new-wgw-bg1 span{
+.index-new-rmfw-bg1 span{
 	border-top:3px solid #FF5A5F;
 	display:inline-block;
 	width:250px; 
@@ -411,6 +411,21 @@ a:focus, a:hover{
 	background-position:-1px -2px;
 	background-size: 252px 67px;
 }
+.index-new-wgw-bg1 span{
+	border-top:3px solid #FF5A5F;
+	display:inline-block;
+	width:250px; 
+	height:45px;
+	background-image:url(/images/u46.png);
+	background-repeat:no-repeat;
+	background-position:-1px -2px;
+	background-size: 252px 45px;	
+}
+.index-new-wgw-bg1 {
+	position: absolute;
+	top: 185px;
+	left: -1px;
+}
 .index-new-rmfw-remarktitle{
     font-size: 16px;
     color: #FFFFFF;
@@ -530,6 +545,55 @@ a:focus, a:hover{
 .fw-new-content .fw-new-zh span,.fw-new-content .fw-new-yzm span{
 	float:right;margin:10px -5px 0px 0px;
 }
-.fw-new-content .afterSendIdentCode{
-	
+.index-new-tg{
+	padding: 20px 30px;
+	margin-bottom:30px;
+}
+.index-new-tg .row{
+	border:1px solid #f0f0f0;
+}
+.index-new-tg-tb img{
+	width:40px;
+	height:39px;
+	margin-bottom:1px;
+}
+.index-new-tg-tb{
+	height:120px;
+	padding-right:0px;
+}
+.index-new-mingcheng div{
+	background-color:#FF5A5F;
+	color:#FFF;
+	padding:24px 6px;
+	height:120px;
+	width:40px; 
+	border:1px solid #FF5A5F;
+	font-size: 16px;
+}
+.index-new-tg-con ul li{
+	padding:5px;
+}    
+.index-new-tg-con>ul>li>span:nth-child(1){
+	display:inline-block;
+	margin-left: 45px;
+	margin-bottom: 8px;
+	width: 4px;
+	height: 4px;
+	border:1px solid #D1D1D1;
+	background-color:#D1D1D1;
+}
+.index-new-tg-con>ul>li>span:nth-child(2){
+	display:inline-block;
+	width:330px;
+	padding-left:10px;
+	padding-right: 10px;
+	color:#4E5051;
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.index-new-tg-con>ul>li>span:nth-child(3){
+	font-family: '宋体 Regular', '宋体';
+	color:#A0A0A0;
+	font-size:12px;
 }

BIN
core/src/web/staticres/images/activeimages/btn_end.png


BIN
core/src/web/staticres/images/creditchengzhang.png


BIN
core/src/web/staticres/images/u0115.png


BIN
core/src/web/staticres/images/u0116.png


BIN
core/src/web/staticres/images/u0117.png


BIN
core/src/web/staticres/images/u0118.png


BIN
core/src/web/staticres/images/u0119.png


BIN
core/src/web/staticres/images/u0120.png


BIN
core/src/web/staticres/images/u2181.png


+ 2 - 2
core/src/web/staticres/wxswordfish/share.js

@@ -10,7 +10,7 @@ function initShare(signature){
 		});
 		wx.ready(function () {
 	        wx.onMenuShareTimeline({
-			    title: '剑鱼招标订阅免费用,关注即可抽取iPadmini。', // 分享标题
+			    title: '剑鱼招标订阅免费用,关注即可抽取iPad mini。', // 分享标题
 			    link: 'http://www.qimingxing.info/swordfish/share', // 分享链接
 			    imgUrl: 'http://www.qimingxing.info/wxswordfish/images/share-icon.png', // 分享图标
 			    success: function () { 
@@ -22,7 +22,7 @@ function initShare(signature){
 			});
 			
 			wx.onMenuShareAppMessage({
-			    title: '剑鱼招标订阅免费用,关注即可抽取iPadmini。', // 分享标题
+			    title: '剑鱼招标订阅免费用,关注即可抽取iPad mini。', // 分享标题
 			    desc: '关注微信并设置剑鱼关键词,全国招标信息统统推送给您!', // 分享描述
 			    link: 'http://www.qimingxing.info/swordfish/share', // 分享链接
 			    imgUrl: 'http://www.qimingxing.info/wxswordfish/images/share-icon.png', // 分享图标

+ 22 - 16
core/src/web/templates/active/luckdraw.html

@@ -32,17 +32,23 @@
 </button>
 <!-- 模态框(Modal) -->
 <div class="modal fade" id="myModal" tabindex="-1" role="dialog" 
-   aria-labelledby="myModalLabel" aria-hidden="true" style="margin-top: 25%;
-">
+   aria-labelledby="myModalLabel" aria-hidden="true" style="padding-top: 25%;">
    <div class="modal-dialog">
       <div class="modal-content">
+	
+         <div class="modal-header">
+            <button type="button" class="close" 
+               data-dismiss="modal" aria-hidden="true" style="width: 40px;height: 30px;">
+                  &times;
+            </button>
+            <h4 class="modal-title" id="myModalLabel">
+               企明星新年大抽奖
+            </h4>
+         </div>
          <div class="modal-body">
             
          </div>
          <div class="modal-footer">
-            <button type="button" class="btn btn-primary" 
-               data-dismiss="modal">关闭
-            </button>
          </div>
       </div><!-- /.modal-content -->
 </div><!-- /.modal -->
@@ -58,9 +64,13 @@
 $(function(){ 
     var flog = {{.T.flog}};
 	if (flog == "A"){
-		$(".modal-body").html("小主莫贪心,每人只有一次抽奖机会呦!<br/><br/>小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)")
+		$(".modal-body").html("{{.T.msg}}")
+		$(".modstart").click();
+		$("#btn_run").attr('disabled',true).css("cursor","pointer").css("background","url(/images/activeimages/btn_end.png) no-repeat").css("background-size","100% 100%");
+	}else if (flog == "B"){
+		$(".modal-body").html("{{.T.msg}}")
 		$(".modstart").click();
-		$("#btn_run").attr('disabled',true).css("cursor","pointer");
+		$("#btn_run").attr('disabled',true).css("cursor","pointer").css("background","url(/images/activeimages/btn_end.png) no-repeat").css("background-size","100% 100%");
 	}
      $("#btn_run").click(function(){
 		$("#btn_run").attr('disabled',true).css("cursor","default"); 
@@ -84,21 +94,17 @@ function lottery(){
 					easing: $.easing.easeOutSine, 
 					callback: function(){ 
 						//alert(obj.results); 
-						$("#btn_run").attr('disabled',true).css("cursor","pointer"); 
-						if (obj.prize == "谢谢参与"){
-							$(".modal-body").html("小主不要桑心,这次没有中奖不代表什么,猴年依然会好运气爆棚滴~~<br/><br/>小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)")
-							$(".modstart").click();
-						}else{
-							$(".modal-body").html("小主是真真的好运气,"+obj.prize+"落入您囊中,请速速微信联系企明星确认领奖事宜!<br/><br/>小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)")
+						$("#btn_run").attr('disabled',true).css("cursor","pointer").css("background","url(/images/activeimages/btn_end.png) no-repeat").css("background-size","100% 100%"); 
+							$(".modal-body").html(obj.msg)
 							$(".modstart").click();
-						}
+							$("#btn_run").attr('disabled',true).css("cursor","pointer").css("background","url(/images/activeimages/btn_end.png) no-repeat").css("background-size","100% 100%");
 					} 
 				});
 			}else if (obj.flog=="A"){
-				$(".modal-body").html("小主莫贪心,每人只有一次抽奖机会呦!<br/><br/>小主翻个牌子,动动小手分享活动,么么哒……(分享点击页面右上方···分享到朋友圈)")
+				$(".modal-body").html(obj.msg)
 				$(".modstart").click();
 			}else if (obj.flog=="F"){
-				$(".modal-body").html("小主来晚了,抽奖活动已过期!如果有疑问请联系企明星!")
+				$(".modal-body").html("  小主来晚了,抽奖活动已过期!如果有疑问请联系企明星!")
 				$(".modstart").click();
 			}
         } 

+ 42 - 2
core/src/web/templates/common/memberleft.html

@@ -114,6 +114,21 @@
 	<a class="list-group-item" onclick="window.location.href = '/member/swordfish/rssset'"><i class="glyphicon iconfontcolor71"></i>剑鱼(信息订阅)</a>
 	<a class="list-group-item" onclick="window.location.href = '/member/msgcenter'" id="msgCenter"><i class="glyphicon xiaoxi"></i>消息中心</a>
 </div>
+<!-- vipcreditModal -->
+<div class="modal fade b-modal" id="vipcreditModal" tabindex="-1" role="dialog" aria-labelledby="vipcreditModalLabel">
+  	<div class="modal-dialog" role="document">
+		<div class="modal-content">
+		  	<div class="modal-header">
+				<span data-dismiss="modal" aria-label="Close" class="close glyphicon guanbi1"></span>
+				<span class="modal-title" id="vipcreditModalLabel">提示信息</span>
+			</div>
+			<div>
+				<div><img style="padding:45px" src="/images/creditchengzhang.png"></img></div>
+				<div style="padding:0px 100px 20px 200px"><button  style="width:200px" class="btn btn-primary" onclick="toMyCredit()">开启成长之旅</button></div>
+			</div>
+		</div>
+	</div>
+</div>
 <script type="text/javascript">
 var role = "{{$s_role}}"=="<nil>"?"":"{{$s_role}}";
 var identWay = "{{$identWay}}";
@@ -218,11 +233,11 @@ var MemberLeftMenu = {
 	},
 	//我的积分
 	myCredit: function(){
-		return '<a onclick="window.location.href=\'/member/credit/myCredit\'" class="menu-childnode2 list-group-item"><i class="glyphicon"></i>我的积分</a>';
+		return '<a onclick="creditModel(1)" class="menu-childnode2 list-group-item" data-target="#vipcreditModal"><i class="glyphicon"></i>我的积分</a>';
 	},
 	//积分规则
 	creditRule: function(){
-		return '<a onclick="window.location.href=\'/member/credit/creditRule\'" class="menu-childnode2 list-group-item"><i class="glyphicon"></i>积分规则</a>';
+		return '<a onclick="creditModel(2)" class="menu-childnode2 list-group-item"><i class="glyphicon"></i>积分规则</a>';
 	}
  };
 $(function (){
@@ -234,6 +249,7 @@ $(function (){
 			$("#credit_qd").removeClass("btn-primary");
 		}
 	});
+	
 });
 function openSChat() {
 	try {
@@ -248,4 +264,28 @@ function qd(){
 		}
 	});
 }
+ 
+function creditModel(type){
+	var num={{session "credit_a"}}
+	if (num>2){
+		if(type=="1"){
+			window.location.href="/member/credit/myCredit";
+		}else{
+			window.location.href="/member/credit/creditRule";
+		}
+	}else{
+		$("#vipcreditModal").modal("show");
+		$('#vipcreditModal').on('hidden.bs.modal', function () {
+			if(type=="1"){
+				window.location.href="/member/credit/myCredit";
+			}else{
+				window.location.href="/member/credit/creditRule";
+			}
+		})	
+	}
+}
+function toMyCredit(){
+	$("#vipcreditModal").modal("hide");
+	window.location.href="/member/credit/myCredit";
+}
 </script>

+ 122 - 1
core/src/web/templates/index.html

@@ -199,10 +199,131 @@
 			{{end}}
  			{{end}}
 		</div>
+		
+		<div class="index-new-tg index-new-bmzhsk">
+		<div class="row">
+		<div class="col-sm-1 index-new-tg-tb">
+		<ul>
+		<li>
+		<div class="bmzhsk"><img src="/images/u0115.png"/></div>
+		<div class="bmjy"><img src="/images/u0117.png"/></div>
+		<div class="bmrzqy"><img src="/images/u0119.png"/></div>
+		</li>
+		<li class="index-new-mingcheng"><div class="text-center" style="height: 119px;">知识库</div></li>
+		</ul>
+		</div>
+		<div class="col-sm-5 index-new-tg-con">
+		<ul>
+		{{range $k,$v:=.T.zkdata}}
+		{{ if lt $k 8}}
+		<li><span></span><span><a target="_blank" href="/front/webcontent/{{index $v "_id"}}.html"/>{{index $v "s_title"}}</a></span><span style="float:right;">{{if eq (index $v "releasetime") ""}}{{index $v "l_createdate"}}{{else}}{{index $v "releasetime"}}{{end}}</span></li>
+		{{if ge $k 3}}
+		{{if lt $k 4}}
+		</ul>
+		</div>
+		<div class="col-sm-1"></div>
+		<div class="col-sm-5 index-new-tg-con">
+		<ul>
+		{{end}}
+		{{end}}
+			
+		{{end}}
+		{{end}}
+		</ul>
+		</div>
+		</div>
+		</div>
+		
+		
+		<div class="index-new-tg index-new-bmjy hidden">
+		<div class="row">
+		<div class="col-sm-1 index-new-tg-tb">
+		<ul>
+		<li>
+		<div class="bmzhsk"><img src="/images/u0116.png"/></div>
+		<div class="bmjy"><img src="/images/u0118.png"/></div>
+		<div class="bmrzqy"><img src="/images/u0119.png"/></div>
+		</li>
+		<li class="index-new-mingcheng"><div class="text-center" style="padding-top: 35px;height: 119px;">剑鱼</div></li>
+		</ul>
+		</div>
+		<div class="col-sm-5 index-new-tg-con">
+		<ul>
+		{{range $k,$v:=.T.sfdata}}
+		{{ if lt $k 8}}
+		<li><span></span><span><a target="_blank" href="http://{{index $v "href"}}"/>{{index $v "title"}}</a></span><span style="float:right;">{{if (index $v "publishtime")}}{{index $v "publishtime"}}{{else}}------{{end}}</span></li>
+		{{if ge $k 3}}
+		{{if lt $k 4}}
+		</ul>
+		</div>
+		<div class="col-sm-1"></div>
+		<div class="col-sm-5 index-new-tg-con">
+		<ul>
+		{{end}}
+		{{end}}
+			
+		{{end}}
+		{{end}}
+		</ul>
+		</div>
+		</div>
+		</div>
+		
+		
+		<div class="index-new-tg index-new-bmrzqy hidden">
+		<div class="row">
+		<div class="col-sm-1 index-new-tg-tb">
+		<ul>
+		<li>
+		<div class="bmzhsk"><img src="/images/u0116.png"/></div>
+		<div class="bmjy"><img src="/images/u0117.png"/></div>
+		<div class="bmrzqy"><img src="/images/u0120.png"/></div>
+		</li>
+		<li class="index-new-mingcheng"><div class="text-center" style="padding-top: 15px;height: 119px;">认证企业</div></li>
+		</ul>
+		</div>
+		<div class="col-sm-5 index-new-tg-con">
+		<ul>
+		{{range $k,$v:=.T.entdata}}
+		{{ if lt $k 8}}
+		<li><span></span><span><a target="_blank" href="/enterprise/{{index $v "s_enterpriseid"}}.html"/>{{index $v "s_enterprisename"}}</a></span><span style="float:right;">{{if (index $v "l_auditdate")}}{{index $v "l_auditdate"}}{{else}}------{{end}}</span></li>
+		{{if ge $k 3}}
+		{{if lt $k 4}}
+		</ul>
+		</div>
+		<div class="col-sm-1"></div>
+		<div class="col-sm-5 index-new-tg-con">
+		<ul>
+		{{end}}
+		{{end}}
+			
+		{{end}}
+		{{end}}
+		</ul>
+		</div>
+		</div>
+		</div>
+		
 	</div>
+	
 </div>
 {{include "/common/bottom.html"}}
 <script>
+$(".bmzhsk").mouseover(function(){
+	$(".index-new-bmrzqy").addClass("hidden");
+	$(".index-new-bmjy").addClass("hidden");
+	$(".index-new-bmzhsk").removeClass("hidden");
+});
+$(".bmjy").mouseover(function(){
+	$(".index-new-bmrzqy").addClass("hidden");
+	$(".index-new-bmzhsk").addClass("hidden");
+	$(".index-new-bmjy").removeClass("hidden");
+});
+$(".bmrzqy").mouseover(function(){
+	$(".index-new-bmzhsk").addClass("hidden");
+	$(".index-new-bmjy").addClass("hidden");
+	$(".index-new-bmrzqy").removeClass("hidden");
+});
 function gomarket(code){
 	$("#c_fwtype").val(code);
 	$("form#searchForm").submit();
@@ -263,7 +384,7 @@ $(function(){
 	}else{
 		//活动处理
 		if(hasNewActive){
-			$(".a-index-hd").append('<img src="/images/activeimages/chjhd.png" onclick="window.open(\'/front/webactivitycontent/5697403b7e1eac37d5000001.html\')" class="cursor-pointer">');
+			$(".a-index-hd").append('<img src="/images/activeimages/chjhd.png" onclick="window.open(\'/front/webactivitycontent/56986e31af53740ecf000001.html\')" class="cursor-pointer">');
 			/*扫码送红包活动
 			$(".a-index-hd").append('<img src="/images/smshb.png" onclick="window.open(\'/p\')" class="cursor-pointer"><div class="smshb"><ul id="hd-smshb" class="text-center"></ul></div>');
 			$.post("/front/showAmount",null,function(r){

+ 90 - 2
core/src/web/templates/member/credit/creditrule.html

@@ -3,7 +3,47 @@
 <title>积分规则</title>
 {{include "/common/inc.html"}}
 <style>
- 
+.credit-explain {
+    background-color: #EEEEEE;
+    padding: 10px 10px;
+    text-indent: 1em;
+	margin-top:20px;
+	line-height:30px;
+}
+.rule{
+	 padding: 20px 10px 0 50px;
+}
+.ruleinfo{
+	padding: 20px 0 0 30px;
+ 	text-indent: 2em;
+	line-height:30px;
+}
+.ptext{
+	text-indent: 1.5em;
+	line-height:30px;
+}
+.sptext{
+	font-weight:bold;
+	line-height:50px;
+}
+.dataintable {
+    margin-top: 10px;
+    border-collapse: collapse;
+    border: 1px solid #aaa;
+    width: 300px;
+	line-height:30px;
+}
+.dataintable th {
+    vertical-align: baseline;
+    background-color: #F2F2F2;
+    border: 1px solid #aaa;
+	text-align:center;
+}
+.dataintable td {
+    vertical-align: text-top;
+    border: 1px solid #aaa;
+	text-align:center;
+}
 </style>
 </head>
 <body>
@@ -16,7 +56,55 @@
 		{{include "/common/memberleft.html"}}
 	</div>
 	<div class="member-right">
-		积分规则...
+		<div class="member-panel">
+			<div class="panel-title-out">
+				<i class="glyphicon jinbi" style="color:#FF5A5F;"></i><span>积分规则</span>
+			</div>
+			<div class="a-line"></div>	
+			<div class="credit-explain">积分获取方法与计算规则</div>
+			<div>
+				<div class="rule">
+					<span  class="sptext">一、积分说明</span>
+					<p class="ptext">
+					会员总积分由操作积分、充值积分组成,其中操作积分是由会员的日常操作得分,
+					充值积分是因为充值产生的,因为违规操作引起的扣分行为将影响会员积分
+					(发布无意义和重复信息扣除200积分,发布违反国家相关法规信息永久封号)。
+					</p>
+				</div>
+				<div class="rule">
+				<span class="sptext">二、积分获得方法</span>
+					<div style="padding-left:30px">
+						<span class="sptext">1、做任务赚积分</span>
+						<p class="ptext">
+						企明星为你准备了简单操作的新手任务,引导你对网站功能快速上手的同事,
+						还能获取相应的积分。全部完成更能一次额外获得1001积分哦~
+						</p>
+						<span class="sptext">2、日常任务</span>
+						<p class="ptext">完成5次企业查询,得50积分(每天上限50经验值)</p>
+						<p class="ptext">发布3条服务信息,得60积分(每天上限60经验值)</p>
+						<p class="ptext">发布3条需求信息,得60积分(每天上限60经验值)</p>
+						<p class="ptext">分享2条服务信息/交易信息,得40积分(每天上限40经验值)</p>
+						<span class="sptext">3、连续登录(签到)</span>
+						<table class="dataintable">
+						<tbody><tr><th style="">连续签到天数</th><th style="">会员奖励经验值</th></tr>
+						<tr><td>1</td><td>10</td></tr>
+						<tr><td>2</td><td>20</td></tr>
+						<tr><td>3</td><td>30</td></tr>
+						<tr><td>4</td><td>40</td></tr>
+						<tr><td>5</td><td>50</td></tr>
+						<tr><td>6</td><td>60</td></tr>
+						<tr><td>7</td><td>70</td></tr>
+						</tbody></table>
+						<span class="sptext">4、增送</span>
+						<p class="ptext">邀请新用户加入,邀请成功后,每人次可获得150积分。</p>
+						<span class="sptext">5、充值</span>
+						<p class="ptext">充值可以快速获得积分,充值1元兑换100积分。充值积分不可用于会员升级,只可用于功能使用。</p>
+						<span class="sptext">6、活动增送</span>
+						<p class="ptext">企明星不定期开放各种任务,为活跃用户提供更多获取经验值得方式,加速成长,获得积分。所以,常来看看哦~</p>
+					</div>
+				</div>
+			</div>
+		</div>
 	</div>
 </div>
  

+ 1 - 1
core/src/web/templates/member/credit/mycredit.html

@@ -281,7 +281,7 @@
 							<tr class="rowtwo">
 								<td width="60%" style="text-indent: 7em;">邀请一个新用户(微信剑鱼分享邀请新用户),得150积分</td>
 								<td width="10%" align="center"></td>
-								<td width="30%" style="padding:110px">去<span class="mx" onclick="toUrl('')">邀请</span></td>
+								<td width="30%" style="padding:110px"></td>
 							</tr>
 						</table>
 						</div>

+ 4 - 0
push/src/config.json

@@ -6,6 +6,7 @@
     "bidStartTime": "2015-12-17 14:10:11",
     "bidTitle": "亲!剑鱼为您速报最新鲜的中标信息啦",
     "bidViewDomain": "192.168.3.132",
+    "bidrStartTime": "2015-12-30 17:27:31",
     "durationMinutes": 1,
     "fixPush": "oJULtwzXo6EFV1Ah-XeyRBimXGM8",
     "mail_bid": "\u003cdiv\u003e%s\u003c/div\u003e,想了解更多信息,请访问http://www.qimingxing.info。",
@@ -48,6 +49,8 @@
         "香港": 33,
         "黑龙江": 8
     },
+    "pushInfoScopeDays": 1,
+    "rpcPort": 8766,
     "smtpAddr": "smtp.exmail.qq.com",
     "smtpFromUser": "企明星",
     "smtpPort": 465,
@@ -55,6 +58,7 @@
     "smtpUser": "qyfw@topnet.net.cn",
     "tenderStartTime": "2015-12-17 14:10:11",
     "tenderTitle": "亲!剑鱼为您速报最新鲜的招标信息啦",
+    "tenderrStartTime": "2015-12-30 17:27:29",
     "weixinRpcServer": "127.0.0.1:82",
     "weixin_bid": "\u003cdiv\u003e%s最新招标信息\u003c/div\u003e\u003cdiv\u003e%s\u003c/div\u003e",
     "wxRpcRemark": "请到网站个人中心查看详细."

+ 13 - 0
push/src/main.go

@@ -4,8 +4,13 @@
 package main
 
 import (
+	"log"
+	"net"
+	"net/http"
+	"net/rpc"
 	"qfw/push"
 	"qfw/push/bid"
+	"qfw/push/rpcpush"
 	"qfw/push/tender"
 	"qfw/util"
 	"qfw/util/mongodb"
@@ -21,6 +26,7 @@ func init() {
 		push.City[k] = uint(v.(float64))
 	}
 	bid.MaxPushSize = util.IntAll(push.PushConfig["maxPushSize"])
+	rpcpush.PushInfoScopeDays = util.IntAll(push.PushConfig["pushInfoScopeDays"])
 	tender.MaxPushSize = bid.MaxPushSize
 	mongodb.InitMongodbPool(util.IntAll(push.PushConfig["mgoSize"]), push.PushConfig["mgoAddr"].(string), "qfw")
 }
@@ -50,6 +56,13 @@ func runJob() {
 //主应用,定时任务
 func main() {
 	go runJob()
+	crpc := new(rpcpush.PushInfo)
+	rpc.Register(crpc)
+	rpc.HandleHTTP()
+	port, _ := push.PushConfig["rpcPort"].(string)
+	l, _ := net.Listen("tcp", ":"+port)
+	go http.Serve(l, nil)
+	log.Println("启动推送系统", port)
 	flag := make(chan bool)
 	<-flag
 }

+ 9 - 208
push/src/qfw/push/bid/bidpushjob.go

@@ -9,223 +9,24 @@
 package bid
 
 import (
-	"container/list"
-	"fmt"
-	"log"
-	"math/rand"
 	"qfw/push"
-	"qfw/push/dfa"
+	"qfw/push/dopush"
 	"qfw/util"
-	"qfw/util/mongodb"
-	qrpc "qfw/util/rpc"
-	"runtime"
-	"strconv"
-	"strings"
 	"time"
 )
 
 type BidPushJob struct {
-	dfa *dfa.DFA
 }
 
-//构造用户兴趣词库
-func (b *BidPushJob) createUserInterestWord() {
-	b.dfa = &dfa.DFA{}
-	words := make([]string, 0)
-	for k, _ := range push.Cache {
-		words = append(words, k)
-	}
-	b.dfa.AddWord(words...)
-}
-
-var TITLEA string = "[中标信息]" //tender
 var MaxPushSize int
 
-//遍历查到的
-func (b *BidPushJob) eachAllBidInfo() {
-	defer func() {
-		if r := recover(); r != nil {
-			fmt.Println("推送开始[E]", r)
-		}
-	}()
-	session := mongodb.GetMgoConn()
-	defer mongodb.DestoryMongoConn(session)
-	startTime := push.PushConfig["bidStartTime"].(string)
-	st, _ := time.ParseInLocation(util.Date_Full_Layout, startTime, time.Local)
-	q := `{"comeintime":{"$gt":` + fmt.Sprintf("%d", st.Unix()) + `},"type":"bid"}`
-	n, _ := session.DB("qfw").C("bidding").Find(mongodb.ObjToOth(q)).Count()
-	log.Println(q, "查询推送信息:", n, ",时间", startTime)
-	if n == 0 {
-		//没有查询到结果
-		return
-	}
-	query := session.DB("qfw").C("bidding").Find(mongodb.ObjToOth(q)).Sort("-publishtime").Iter()
-	userMap := &map[*push.MemberInterest]*list.List{}
-	for tmp := new(map[string]interface{}); query.Next(tmp); {
-		title := util.ObjToString((*tmp)["title"])
-		if title != "" {
-			//返回匹配到的词组
-			res := b.dfa.Analy(title)
-			if len(res) > 0 {
-				province := (*tmp)["area"].(string)
-				provinceVal := push.GetChoiceCode(province)
-				for _, v := range res {
-					//根据关键词返回用户指针
-					tw := push.Cache[v]
-					if tw != nil {
-						//遍历用户加入到此条信息上
-						for _, v2 := range *tw {
-							if v2.Province == "A" || v2.ProvinceVal&provinceVal > 0 {
-								s := (*userMap)[v2]
-								if s == nil {
-									//s = &map[*map[string]interface{}]bool{}
-									s = list.New()
-									(*userMap)[v2] = s
-								}
-								s.PushBack(tmp)
-							}
-						}
-					}
-				}
-			}
-		}
-		tmp = new(map[string]interface{})
-	}
-
-	now := time.Now()
-	nowtime := util.FormatDate(&now, util.Date_Full_Layout)
-	//更改开始时间
-	push.PushConfig["bidStartTime"] = nowtime
-	//date := util.FormatDate(&now, util.Date_Short_Layout)
-
-	for k, v := range *(userMap) {
-		kk := *k
-		vv := *v
-		time.Sleep(50 * time.Millisecond)
-		go send(&kk, &vv, now, nowtime)
-	}
-}
-
-func send(k *push.MemberInterest, v *list.List, now time.Time, nowtime string) {
-	defer func() {
-		if r := recover(); r != nil {
-			log.Println("[E]", r)
-			for skip := 1; ; skip++ {
-				_, file, line, ok := runtime.Caller(skip)
-				if !ok {
-					break
-				}
-				go log.Printf("%v,%v\n", file, line)
-			}
-		}
-	}()
-	//wxstr := ""
-	str := fmt.Sprintf("<div>根据您设置的关键词(%s),给您推送以下信息:</div>", strings.Join(k.Interest, ";"))
-
-	//发送内容组合
-	i := 0
-	lastInfoDate := int64(0)
-	firstTitle := ""
-	publishTimes := map[string]interface{}{}
-	for ks := v.Front(); ks != nil; ks = ks.Next() {
-		k2 := *(ks.Value.(*map[string]interface{}))
-		i++
-		if i == 1 {
-			firstTitle = strings.Replace(k2["title"].(string), "\n", "", -1)
-			lastInfoDate = k2["publishtime"].(int64)
-		}
-		str += "<div class='tslist'><span class='xh'>" + fmt.Sprintf("%d", i) + ".</span><a class='bt' target='_blank' href='" + k2["href"].(string) + "'>" + strings.Replace(k2["title"].(string), "\n", "", -1) + "</a></div>"
-		publishTimes[strconv.Itoa(i)] = k2["publishtime"]
-
-		if i >= MaxPushSize {
-			//限制最大信息条数
-			break
-		}
-
-	}
-	TITLE := TITLEA + fmt.Sprintf("%d条,关键词(%s)", i, strings.Join(k.Interest, ";"))
-	WXTitle := fmt.Sprintf("%s《%s》%s", func() string {
-		minute := now.Unix() - lastInfoDate
-		if minute > -1 && minute < 61 {
-			return fmt.Sprintf("%d秒前发布的", minute)
-		} else {
-			minute = minute / 60
-			if minute > 121 {
-				return ""
-			} else {
-				if minute < 1 {
-					minute = 1
-				}
-				return fmt.Sprintf("%d分钟前发布的", minute)
-			}
-		}
-	}(), firstTitle, func() string {
-		if i == 1 {
-			return ""
-		} else {
-			return "等" + strconv.Itoa(i) + "条"
-		}
-	}())
-
-	//发送微信
-	if len(k.Openid) > 0 {
-		sendWeixin(k, TITLE, str, nowtime, "", now, "", WXTitle, publishTimes)
-	}
-
-}
-
-//推送微信
-func sendWeixin(k *push.MemberInterest, TITLE, str, nowtime, wxstr string, now time.Time, msgid, WXTitle string, publishTimes map[string]interface{}) {
-	defer func() {
-		if r := recover(); r != nil {
-			fmt.Println("发送微信[E]", r)
-		}
-	}()
-	time.Sleep(time.Millisecond * 100)
-	//详情存库
-	wxpush := map[string]interface{}{
-		"s_m_openid":    k.Openid,
-		"l_date":        now.Unix(),
-		"s_words":       k.Interest,
-		"s_email":       k.Email,
-		"s_uid":         k.Id,
-		"s_province":    k.Province,
-		"a_interest":    k.Interest,
-		"s_content":     str,
-		"s_type":        "bid",
-		"a_publishtime": publishTimes,
-		"i_size":        len(publishTimes),
-	}
-	wid := mongodb.Save("wxpush", &wxpush)
-	wxstr = "\n点击下方“详情”查看详细信息。\n以上中标信息,是剑鱼根据关键字“" + strings.Join(k.Interest, ";") + "”奋力查找并推送,如不合您心意,请猛戳企明星菜单“会员服务—剑鱼”进行修改。"
-
-	wxDate := ""
-	if k.InterestDate > 0 {
-		mt1 := interface{}(k.InterestDate)
-		wxDate = util.FormatDateWithObj(&mt1, util.Date_Full_Layout)
-	} else {
-		r := rand.New(rand.NewSource(time.Now().UnixNano()))
-		n1 := r.Int63n(9)
-		n2 := r.Int63n(7200)
-		wxDate = time.Now().Local().Add(time.Duration(-n2) * time.Second).Add(time.Duration(-n1*24) * time.Hour).Format(util.Date_Full_Layout)
-	}
-
-	push.SendWinXin(&qrpc.NotifyMsg{
-		Openid:  k.Openid,
-		Title:   push.PushConfig["bidTitle"].(string),
-		Remark:  wxstr,
-		Detail:  WXTitle,
-		Date:    wxDate,
-		Service: "剑鱼君",
-		Url:     push.PushConfig["bidViewDomain"].(string) + "/wxpush/bid/" + k.Openid + "/" + wid + "/a"})
-
-}
-
-//执行日常招标中标公告的消息推送
+//执行日常招标的消息推送
 func (b *BidPushJob) Execute() bool {
-	log.Println("开始执行中标任务:", push.PushConfig["bidStartTime"])
-	push.InitCache("bid")
-	b.createUserInterestWord()
-	b.eachAllBidInfo()
-	return false
+	pj := dopush.Pjob{
+		MaxPushSize: MaxPushSize,
+		Stype:       "bid",
+		StypeName:   "中标",
+	}
+	st, _ := time.ParseInLocation(util.Date_Full_Layout, push.PushConfig["bidStartTime"].(string), time.Local)
+	return pj.DoPush("", push.PushConfig["bidStartTime"].(string), 1, st.Unix())
 }

+ 25 - 35
push/src/qfw/push/cache.go

@@ -14,36 +14,32 @@ import (
 )
 
 type MemberInterest struct {
-	Id          string   //mongoid
-	Province    string   //省份
-	ProvinceVal uint64   //可选多个省份的处理
-	Interest    []string //用户兴趣
-	//Type     string   //兴趣类型
-	//SendMode     []string //发送方式
-	Unionid      string
+	Id           string   //mongoid
+	Province     string   //省份
+	ProvinceVal  uint64   //可选多个省份的处理
+	Interest     []string //用户兴趣
 	Openid       string
-	Email        string
 	InterestDate int64
 }
 
-var Cache map[string]*[]*MemberInterest //缓存
 //初始化缓存,在每次执行任务时调用,
-//加载用户数据到Cache中
-func InitCache(flag string) {
-	Cache = make(map[string]*[]*MemberInterest)
-	//TODO 查Mogo数据库
-	fixPush := util.ObjToString(PushConfig["fixPush"])
+func InitCache(flag, m_openid string) map[string]*[]*MemberInterest {
+	cache := make(map[string]*[]*MemberInterest)
 	q := map[string]interface{}{}
-	if len(fixPush) > 5 {
-		log.Println("推指定的人", fixPush)
-		q["s_m_openid"] = map[string]interface{}{
-			"$in": strings.Split(fixPush, ","),
-		}
+	if m_openid != "" {
+		q["s_m_openid"] = m_openid
 	} else {
-		q = map[string]interface{}{
-			"o_msgset." + flag: map[string]interface{}{
-				"$exists": true,
-			},
+		fixPush := util.ObjToString(PushConfig["fixPush"])
+		if len(fixPush) > 5 {
+			log.Println("推指定的人", fixPush)
+			q["s_m_openid"] = map[string]interface{}{
+				"$in": strings.Split(fixPush, ","),
+			}
+		} else {
+			q = map[string]interface{}{
+				"o_msgset." + flag + ".i_switchstatus": 1,
+				"o_msgset." + flag + ".i_status":       1,
+			}
 		}
 	}
 	session := mongodb.GetMgoConn()
@@ -52,9 +48,7 @@ func InitCache(flag string) {
 		"_id":                   1,
 		"o_msgset." + flag:      1,
 		"o_msgset.l_modifydate": 1,
-		"s_unionid":             1,
 		"s_m_openid":            1,
-		"s_email":               1,
 	}).Iter()
 	for tmp := make(map[string]interface{}); query.Next(tmp); {
 		util.Try(func() {
@@ -62,18 +56,14 @@ func InitCache(flag string) {
 			o_msgset := tmp["o_msgset"].(map[string]interface{})
 			flagModule := o_msgset[flag].(map[string]interface{})
 			a_key := util.ObjArrToStringArr(flagModule["a_key"].([]interface{}))
-			//a_mode := util.ObjArrToStringArr(flagModule["a_mode"].([]interface{}))
 			s_scope := util.ObjToString(flagModule["s_scope"])
 			if len(a_key) > 0 && len(s_scope) > 0 {
 				user := MemberInterest{
-					Id: _id,
-					//SendMode:    a_mode,
+					Id:          _id,
 					Province:    s_scope,
 					ProvinceVal: GetChoiceCode(strings.Split(s_scope, ",")...),
 					Interest:    a_key,
-					Unionid:     util.ObjToString(tmp["s_unionid"]),
 					Openid:      util.ObjToString(tmp["s_m_openid"]),
-					Email:       util.ObjToString(tmp["s_email"]),
 				}
 				date := o_msgset["l_modifydate"]
 				if date != nil {
@@ -83,12 +73,12 @@ func InitCache(flag string) {
 				}
 				for i := 0; i < len(a_key) && a_key[i] != ""; i++ {
 					var arr []*MemberInterest
-					if nil == Cache[a_key[i]] {
+					if nil == cache[a_key[i]] {
 						arr = make([]*MemberInterest, 0)
-						Cache[a_key[i]] = &arr
+						cache[a_key[i]] = &arr
 					} else {
-						arr = *Cache[a_key[i]]
-						Cache[a_key[i]] = &arr
+						arr = *cache[a_key[i]]
+						cache[a_key[i]] = &arr
 					}
 					arr = append(arr, &user)
 				}
@@ -97,8 +87,8 @@ func InitCache(flag string) {
 			log.Println(e)
 		})
 		tmp = make(map[string]interface{})
-		//log.Println(_id, o_msgset)
 	}
+	return cache
 }
 
 //各省份排序,最终会占某个2进制位

+ 16 - 0
push/src/qfw/push/dfa/interestanalysis_test.go

@@ -27,3 +27,19 @@ func TestAnaly(t *testing.T) {
 	//log.Println(d.Analy("这是胡锦涛写给江泽民的信啊。"))
 
 }
+
+func Test_Label(t *testing.T) {
+	log.Println("000----")
+
+	for _, v := range []int{1, 2, 3, 4, 5} {
+		log.Println(v)
+	L1:
+		for _, vv := range []string{"a", "b", "c", "d"} {
+			log.Println(vv)
+			if vv == "add" {
+				break L1
+			}
+		}
+	}
+	log.Println("111----")
+}

+ 221 - 0
push/src/qfw/push/dopush/dopush.go

@@ -0,0 +1,221 @@
+package dopush
+
+import (
+	"container/list"
+	"fmt"
+	"log"
+	"math/rand"
+	"qfw/push"
+	"qfw/push/dfa"
+	"qfw/util"
+	"qfw/util/mongodb"
+	qrpc "qfw/util/rpc"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type Pjob struct {
+	Dfa         *dfa.DFA
+	Cache       *map[string]*[]*push.MemberInterest
+	MaxPushSize int
+	Stype       string
+	StypeName   string
+}
+
+//构造用户兴趣词库
+func (b *Pjob) CreateUserInterestWord() {
+	b.Dfa = &dfa.DFA{}
+	words := make([]string, 0)
+	for k, _ := range *b.Cache {
+		words = append(words, k)
+	}
+	b.Dfa.AddWord(words...)
+}
+
+func (p *Pjob) DoPush(mopenid, stime string, opr int, ltime int64) bool {
+	log.Println("开始执行任务:", p.StypeName, stime)
+	p.Cache = new(map[string]*[]*push.MemberInterest)
+	*p.Cache = push.InitCache(p.Stype, mopenid)
+	p.CreateUserInterestWord()
+	EachAllBidInfo(p.Stype, "["+p.StypeName+"信息]", p.StypeName, ltime, p.MaxPushSize, p.Dfa, p.Cache, opr)
+	return false
+}
+
+//遍历数据并执行推送操作
+func EachAllBidInfo(stype, TITLEA, ShortTitle string, lastTime int64, MaxPushSize int, dfas *dfa.DFA, cache *map[string]*[]*push.MemberInterest, pushType int) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("推送开始[E]", r)
+		}
+	}()
+	session := mongodb.GetMgoConn()
+	defer mongodb.DestoryMongoConn(session)
+	q := `{"comeintime":{"$gt":` + fmt.Sprintf("%d", lastTime) + `},"type":"` + stype + `"}`
+	n, _ := session.DB("qfw").C("bidding").Find(mongodb.ObjToOth(q)).Count()
+	if n == 0 {
+		log.Println("执行推送任务", stype, "没有数据。")
+		return
+	}
+	query := session.DB("qfw").C("bidding").Find(mongodb.ObjToOth(q)).Sort("-publishtime").Iter()
+	userMap := &map[*push.MemberInterest]*list.List{}
+	var returnLastTime interface{}
+L1:
+	for tmp := new(map[string]interface{}); query.Next(tmp); {
+		title := util.ObjToString((*tmp)["title"])
+		if title != "" {
+			//返回匹配到的词组
+			res := dfas.Analy(title)
+			if len(res) > 0 {
+				province := (*tmp)["area"].(string)
+				provinceVal := push.GetChoiceCode(province)
+				for _, v := range res {
+					//根据关键词返回用户指针
+					tw := (*cache)[v]
+					if tw != nil {
+						//遍历用户加入到此条信息上
+						for _, v2 := range *tw {
+							if v2.Province == "A" || v2.ProvinceVal&provinceVal > 0 {
+								s := (*userMap)[v2]
+								if s == nil {
+									s = list.New()
+									(*userMap)[v2] = s
+								}
+								s.PushBack(tmp)
+								if pushType == 2 && s.Len() > MaxPushSize {
+									break L1
+								}
+							}
+						}
+					}
+				}
+			}
+			if returnLastTime == nil {
+				returnLastTime = (*tmp)["comeintime"]
+			}
+		}
+		tmp = new(map[string]interface{})
+	}
+	now := time.Now()
+	if pushType == 1 && returnLastTime != nil {
+		push.PushConfig[stype+"rStartTime"] = util.FormatDateWithObj(&returnLastTime, util.Date_Full_Layout)
+	}
+	for k, v := range *(userMap) {
+		kk := *k
+		vv := *v
+		time.Sleep(50 * time.Millisecond)
+		go Send(&kk, &vv, now, TITLEA, ShortTitle, MaxPushSize)
+	}
+}
+
+//全局推送功能
+func Send(k *push.MemberInterest, v *list.List, now time.Time, TITLEA, ShortTitle string, MaxPushSize int) {
+	defer func() {
+		if r := recover(); r != nil {
+			log.Println("[E]", r)
+			for skip := 1; ; skip++ {
+				_, file, line, ok := runtime.Caller(skip)
+				if !ok {
+					break
+				}
+				go log.Printf("%v,%v\n", file, line)
+			}
+		}
+	}()
+	str := fmt.Sprintf("<div>根据您设置的关键词(%s),给您推送以下信息:</div>", strings.Join(k.Interest, ";"))
+	//发送内容组合
+	i := 0
+	lastInfoDate := int64(0)
+	firstTitle := ""
+	publishTimes := map[string]interface{}{}
+	for ks := v.Front(); ks != nil; ks = ks.Next() {
+		k2 := *(ks.Value.(*map[string]interface{}))
+		i++
+		if i == 1 {
+			firstTitle = strings.Replace(k2["title"].(string), "\n", "", -1)
+			lastInfoDate = k2["publishtime"].(int64)
+		}
+		str += "<div class='tslist'><span class='xh'>" + fmt.Sprintf("%d", i) + ".</span><a class='bt' target='_blank' href='" + k2["href"].(string) + "'>" + strings.Replace(k2["title"].(string), "\n", "", -1) + "</a></div>"
+		publishTimes[strconv.Itoa(i)] = k2["publishtime"]
+		if i >= MaxPushSize {
+			//限制最大信息条数
+			break
+		}
+
+	}
+	TITLE := TITLEA + fmt.Sprintf("%d条,关键词(%s)", i, strings.Join(k.Interest, ";"))
+	WXTitle := fmt.Sprintf("%s《%s》%s", func() string {
+		minute := now.Unix() - lastInfoDate
+		if minute > -1 && minute < 61 {
+			return fmt.Sprintf("%d秒前发布的", minute)
+		} else {
+			minute = minute / 60
+			if minute > 121 {
+				return ""
+			} else {
+				if minute < 1 {
+					minute = 1
+				}
+				return fmt.Sprintf("%d分钟前发布的", minute)
+			}
+		}
+	}(), firstTitle, func() string {
+		if i == 1 {
+			return ""
+		} else {
+			return "等" + strconv.Itoa(i) + "条"
+		}
+	}())
+
+	//3、发送微信
+	if len(k.Openid) > 0 {
+		SendWeixin(k, TITLE, ShortTitle, str, "", now, WXTitle, publishTimes)
+	}
+
+}
+
+//推送微信
+func SendWeixin(k *push.MemberInterest, TITLE, ShortTitle, str, wxstr string, now time.Time, WXTitle string, publishTimes map[string]interface{}) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("发送微信[E]", r)
+		}
+	}()
+	time.Sleep(time.Millisecond * 100)
+	//详情存库
+	wxpush := map[string]interface{}{
+		"s_m_openid":    k.Openid,
+		"l_date":        now.Unix(),
+		"s_words":       k.Interest,
+		"s_uid":         k.Id,
+		"s_province":    k.Province,
+		"a_interest":    k.Interest,
+		"s_content":     str,
+		"s_type":        "tender",
+		"a_publishtime": publishTimes,
+		"i_size":        len(publishTimes),
+	}
+	wid := mongodb.Save("wxpush", &wxpush)
+	wxDate := ""
+	if k.InterestDate > 0 {
+		mt1 := interface{}(k.InterestDate)
+		wxDate = util.FormatDateWithObj(&mt1, util.Date_Full_Layout)
+	} else {
+		r := rand.New(rand.NewSource(time.Now().UnixNano()))
+		n1 := r.Int63n(9)
+		n2 := r.Int63n(7200)
+		wxDate = time.Now().Local().Add(time.Duration(-n2) * time.Second).Add(time.Duration(-n1*24) * time.Hour).Format(util.Date_Full_Layout)
+	}
+
+	wxstr = "\n点击下方“详情”查看详细信息。\n以上" + ShortTitle + "信息,是剑鱼根据关键字“" + strings.Join(k.Interest, ";") + "”奋力查找并推送,如不合您心意,请猛戳企明星菜单“会员服务—剑鱼”进行修改。"
+	push.SendWinXin(&qrpc.NotifyMsg{
+		Openid:  k.Openid,
+		Title:   push.PushConfig["tenderTitle"].(string),
+		Remark:  wxstr,
+		Detail:  WXTitle,
+		Date:    wxDate,
+		Service: "剑鱼君",
+		Url:     push.PushConfig["bidViewDomain"].(string) + "/wxpush/bid/" + k.Openid + "/" + wid + "/aa"})
+
+}

+ 29 - 0
push/src/qfw/push/rpcpush/rpcpush.go

@@ -0,0 +1,29 @@
+package rpcpush
+
+import (
+	"fmt"
+	"qfw/push/bid"
+	"qfw/push/dopush"
+	qrpc "qfw/util/rpc"
+	"time"
+)
+
+type PushInfo struct {
+}
+
+var PushInfoScopeDays int
+
+func (p *PushInfo) PushMsg(data *qrpc.PushData, Reply *int) error {
+	for k, v := range data.PushType {
+		//昨天到今天的数据
+		pj := dopush.Pjob{
+			MaxPushSize: bid.MaxPushSize,
+			Stype:       k,
+			StypeName:   v,
+		}
+		now := time.Now()
+		tom := time.Date(now.Year(), now.Month(), now.Day()-PushInfoScopeDays, 0, 0, 0, 0, time.Local)
+		pj.DoPush(data.Mopenid, fmt.Sprintf("%d days", PushInfoScopeDays), 2, tom.Unix())
+	}
+	return nil
+}

+ 9 - 212
push/src/qfw/push/tender/tenderpushjob.go

@@ -1,227 +1,24 @@
-/**
- *招标,中标公告的推送消息,在兴趣词分析上,存在一定的难度
- *现在采用DFA算法分析,兴趣词会构造Map结构,前期应该不会出问题。
- *后期需要改进(用户量达到5千以上)
- *可行策略:每日产生的新数据有限,大概不超过5000条,可以把标题全加到内存
- *        用户兴趣词分批次加入,每次加入3000个左右的用户的兴趣词,过滤
- *        今日产生的招标、中标数据,并完成推送,第二批载入后3000个用户的数据
- */
 package tender
 
 import (
-	"container/list"
-	"fmt"
-	"log"
-	"math/rand"
 	"qfw/push"
-	"qfw/push/dfa"
+	"qfw/push/dopush"
 	"qfw/util"
-	"qfw/util/mongodb"
-	qrpc "qfw/util/rpc"
-	"runtime"
-	"strconv"
-	"strings"
 	"time"
 )
 
 type TenderPushJob struct {
-	dfa *dfa.DFA
 }
 
-//构造用户兴趣词库
-func (b *TenderPushJob) createUserInterestWord() {
-	b.dfa = &dfa.DFA{}
-	words := make([]string, 0)
-	for k, _ := range push.Cache {
-		words = append(words, k)
-	}
-	b.dfa.AddWord(words...)
-}
-
-var TITLEA string = "[招标信息]" //tender
 var MaxPushSize int
 
-//遍历查到的
-func (b *TenderPushJob) eachAllBidInfo() {
-	defer func() {
-		if r := recover(); r != nil {
-			fmt.Println("推送开始[E]", r)
-		}
-	}()
-	session := mongodb.GetMgoConn()
-	defer mongodb.DestoryMongoConn(session)
-	startTime := push.PushConfig["tenderStartTime"].(string)
-	st, _ := time.ParseInLocation(util.Date_Full_Layout, startTime, time.Local)
-	q := `{"comeintime":{"$gt":` + fmt.Sprintf("%d", st.Unix()) + `},"type":"tender"}`
-	n, _ := session.DB("qfw").C("bidding").Find(mongodb.ObjToOth(q)).Count()
-	log.Println(q, "查询推送信息:", n, ",时间", startTime)
-	if n == 0 {
-		//没有查询到结果
-		return
-	}
-	query := session.DB("qfw").C("bidding").Find(mongodb.ObjToOth(q)).Sort("-publishtime").Iter()
-	userMap := &map[*push.MemberInterest]*list.List{}
-	for tmp := new(map[string]interface{}); query.Next(tmp); {
-		title := util.ObjToString((*tmp)["title"])
-		if title != "" {
-			//返回匹配到的词组
-			res := b.dfa.Analy(title)
-			if len(res) > 0 {
-				province := (*tmp)["area"].(string)
-				provinceVal := push.GetChoiceCode(province)
-				for _, v := range res {
-					//根据关键词返回用户指针
-					tw := push.Cache[v]
-					if tw != nil {
-						//遍历用户加入到此条信息上
-						for _, v2 := range *tw {
-							if v2.Province == "A" || v2.ProvinceVal&provinceVal > 0 {
-								s := (*userMap)[v2]
-								if s == nil {
-									s = list.New()
-									(*userMap)[v2] = s
-								}
-								s.PushBack(tmp)
-							}
-						}
-					}
-				}
-			}
-		}
-		tmp = new(map[string]interface{})
-	}
-	now := time.Now()
-	nowtime := util.FormatDate(&now, util.Date_Full_Layout)
-	//更改开始时间
-	push.PushConfig["tenderStartTime"] = nowtime
-	//date := util.FormatDate(&now, util.Date_Short_Layout)
-	for k, v := range *(userMap) {
-		kk := *k
-		vv := *v
-
-		time.Sleep(50 * time.Millisecond)
-		go send(&kk, &vv, now, nowtime)
-	}
-}
-
-func send(k *push.MemberInterest, v *list.List, now time.Time, nowtime string) {
-	defer func() {
-		if r := recover(); r != nil {
-			log.Println("[E]", r)
-			for skip := 1; ; skip++ {
-				_, file, line, ok := runtime.Caller(skip)
-				if !ok {
-					break
-				}
-				go log.Printf("%v,%v\n", file, line)
-			}
-		}
-	}()
-
-	//wxstr := ""
-	str := fmt.Sprintf("<div>根据您设置的关键词(%s),给您推送以下信息:</div>", strings.Join(k.Interest, ";"))
-	//发送内容组合
-	i := 0
-	lastInfoDate := int64(0)
-	firstTitle := ""
-	publishTimes := map[string]interface{}{}
-	for ks := v.Front(); ks != nil; ks = ks.Next() {
-		k2 := *(ks.Value.(*map[string]interface{}))
-		i++
-		if i == 1 {
-			firstTitle = strings.Replace(k2["title"].(string), "\n", "", -1)
-			lastInfoDate = k2["publishtime"].(int64)
-		}
-		str += "<div class='tslist'><span class='xh'>" + fmt.Sprintf("%d", i) + ".</span><a class='bt' target='_blank' href='" + k2["href"].(string) + "'>" + strings.Replace(k2["title"].(string), "\n", "", -1) + "</a></div>"
-		publishTimes[strconv.Itoa(i)] = k2["publishtime"]
-		if i >= MaxPushSize {
-			//限制最大信息条数
-			break
-		}
-
-	}
-	TITLE := TITLEA + fmt.Sprintf("%d条,关键词(%s)", i, strings.Join(k.Interest, ";"))
-	WXTitle := fmt.Sprintf("%s《%s》%s", func() string {
-		minute := now.Unix() - lastInfoDate
-		if minute > -1 && minute < 61 {
-			return fmt.Sprintf("%d秒前发布的", minute)
-		} else {
-			minute = minute / 60
-			if minute > 121 {
-				return ""
-			} else {
-				if minute < 1 {
-					minute = 1
-				}
-				return fmt.Sprintf("%d分钟前发布的", minute)
-			}
-		}
-	}(), firstTitle, func() string {
-		if i == 1 {
-			return ""
-		} else {
-			return "等" + strconv.Itoa(i) + "条"
-		}
-	}())
-
-	//3、发送微信
-	if len(k.Openid) > 0 {
-		sendWeixin(k, TITLE, str, nowtime, "", now, "", WXTitle, publishTimes)
-	}
-
-}
-
-//推送微信
-func sendWeixin(k *push.MemberInterest, TITLE, str, nowtime, wxstr string, now time.Time, msgid, WXTitle string, publishTimes map[string]interface{}) {
-	defer func() {
-		if r := recover(); r != nil {
-			fmt.Println("发送微信[E]", r)
-		}
-	}()
-	time.Sleep(time.Millisecond * 100)
-	//详情存库
-	wxpush := map[string]interface{}{
-		"s_m_openid":    k.Openid,
-		"l_date":        now.Unix(),
-		"s_words":       k.Interest,
-		"s_email":       k.Email,
-		"s_uid":         k.Id,
-		"s_province":    k.Province,
-		"a_interest":    k.Interest,
-		"s_content":     str,
-		"s_type":        "tender",
-		"a_publishtime": publishTimes,
-		"i_size":        len(publishTimes),
-	}
-	wid := mongodb.Save("wxpush", &wxpush)
-	wxDate := ""
-	if k.InterestDate > 0 {
-		mt1 := interface{}(k.InterestDate)
-		wxDate = util.FormatDateWithObj(&mt1, util.Date_Full_Layout)
-	} else {
-		r := rand.New(rand.NewSource(time.Now().UnixNano()))
-		n1 := r.Int63n(9)
-		n2 := r.Int63n(7200)
-		wxDate = time.Now().Local().Add(time.Duration(-n2) * time.Second).Add(time.Duration(-n1*24) * time.Hour).Format(util.Date_Full_Layout)
-	}
-
-	wxstr = "\n点击下方“详情”查看详细信息。\n以上招标信息,是剑鱼根据关键字“" + strings.Join(k.Interest, ";") + "”奋力查找并推送,如不合您心意,请猛戳企明星菜单“会员服务—剑鱼”进行修改。"
-	push.SendWinXin(&qrpc.NotifyMsg{
-		Openid:  k.Openid,
-		Title:   push.PushConfig["tenderTitle"].(string),
-		Remark:  wxstr,
-		Detail:  WXTitle,
-		Date:    wxDate,
-		Service: "剑鱼君",
-		Url:     push.PushConfig["bidViewDomain"].(string) + "/wxpush/bid/" + k.Openid + "/" + wid + "/aa"})
-
-}
-
-//执行日常招标中标公告的消息推送
+//执行日常招标的消息推送
 func (b *TenderPushJob) Execute() bool {
-	log.Println("开始执行招标任务:", push.PushConfig["tenderStartTime"])
-	push.InitCache("tender")
-	b.createUserInterestWord()
-	b.eachAllBidInfo()
-	return false
+	pj := dopush.Pjob{
+		MaxPushSize: MaxPushSize,
+		Stype:       "tender",
+		StypeName:   "招标",
+	}
+	st, _ := time.ParseInLocation(util.Date_Full_Layout, push.PushConfig["tenderStartTime"].(string), time.Local)
+	return pj.DoPush("", push.PushConfig["tenderStartTime"].(string), 1, st.Unix())
 }

+ 4 - 6
weixin/src/config.json

@@ -20,8 +20,7 @@
 	"entAuthTip":",请按向导进行操作。第1步(共2步):请输入完整的企业名称。\n(认证过程只涉及您所在企业的公开信息。除非事先获得您的授权,企明星不会将您的个人隐私信息公开或透露给第三方机构。输入q或Q,退出认证操作。)",
 	"perAuthTip":",请按向导进行操作。第1步(共2步):请输入商家名称。\n(除非事先获得您的授权,企明星不会将您的个人隐私信息公开或透露给第三方机构。输入q或Q,退出认证操作。)",
 	"othAuthTip":",请按向导进行操作。第1步(共2步):请输入完整的组织机构名称。\n(认证过程只涉及您所在机构的公开信息。除非事先获得您的授权,企明星不会将您的个人隐私信息公开或透露给第三方机构。输入q或Q,退出认证操作。)",
-	"oWelcomeTip":"您已成功注册企明星!\n企明星是一个为全国企业提供专业化服务的互联网平台。
-",
+	"oWelcomeTip":"您已成功注册企明星!\n企明星是一个为全国企业提供专业化服务的互联网平台。",
         "loginTip":"您已经成功登录企明星,请在电脑端操作。",
         "freezeTip":"您的帐号已经冻结,请联系管理员。",
         "messagetpl":{
@@ -29,11 +28,10 @@
                 "offLinemsgtplid":"ExIeyFfoDNVJXhRDq09JbsjH_zbEJCB6gw6rxcV7atw",
                 "msgnotifytplid":"b7iuAMiTCIolnPhTdueKBVYThEMf2D-Bh2M_9v3J-68",
                 "managernotifytplid":"dplgu5Q644vzPdqcPXY7RqgItS3eXACmU1XDl27CvTA"
-        },
-        "activity":{
+        },"activity":{
                 "activitycode":"topcj",
                 "title":"企明星新年抽奖活动进行中",
                 "picurl":"http://www.qimingxing.info/images/choujiang.png"
-        }
-
+        },"weixinautorpl":"小主的吩咐我们已经收到了,请留下您的联系方式(手机号或qq号),企明星客服会在下一个工作日9:00-17:00给小主回复哦!",
+		"creditRpc":"http://127.0.0.1:8765"
 }

+ 10 - 0
weixin/src/qfw/weixin/dao/logsdao.go

@@ -51,3 +51,13 @@ func FindWinningRecord(openid, activitycode string) bool {
 	ret := mongodb.FindOne("winningrecord", M{"s_openid": openid, "s_actcode": activitycode})
 	return ret != nil && len(*ret) > 0
 }
+
+//存微信的离线消息
+func SaveWeixinOfflineMessage(openid, msg string, timestamp int64) {
+	data := map[string]interface{}{
+		"s_openid":    openid,
+		"s_msg":       msg,
+		"l_timestamp": timestamp,
+	}
+	mongodb.Save("weixinoffline", &data)
+}

+ 43 - 0
weixin/src/qfw/weixin/dao/sharedao.go

@@ -0,0 +1,43 @@
+package dao
+
+//分享,邀请类dao
+import (
+	"fmt"
+	. "gopkg.in/mgo.v2/bson"
+	"qfw/util/credit"
+	. "qfw/util/mongodb"
+	"time"
+)
+
+//
+var sharelock chan bool = make(chan bool, 10)
+
+//保存用户邀请关系,走线程池
+func SaveInviteLink(shareid string, myopenid string) {
+	//先找邀请人信息
+	sharelock <- true
+	ret := FindOne("person_share", M{"i_shareid": shareid})
+	if *ret == nil {
+		<-sharelock
+		return
+	}
+	source_opendid := (*ret)["s_openid"]
+	data := map[string]interface{}{
+		"s_target_openid": myopenid,
+		"s_source_openid": source_opendid,
+		"l_timestamp":     time.Now().Unix(),
+		"i_shareid":       shareid,
+		"s_businesscode":  (*ret)["s_businesscode"],
+	}
+	Save("person_invitelink", data)
+	//取用户ID
+	ret = FindOne("user", M{"s_m_openid": source_opendid})
+	if *ret == nil {
+		<-sharelock
+		return
+	}
+	smid := fmt.Sprintf("%x", string(((*ret)["_id"]).(ObjectId)))
+	//积分处理,RPC
+	credit.InCreditB(smid, credit.C_TG, nil)
+	<-sharelock
+}

+ 2 - 7
weixin/src/qfw/weixin/dao/userdao.go

@@ -40,13 +40,8 @@ func AddUser(openid, unionid, bindweixin, userphoto string) (err error, flag int
 		}
 		data["i_identificationway"] = 0
 		data["s_m_openid"] = openid //微信手机端openid
-		if len(Save("user", data)) > 0 {
-			//注册送积分
-			m := FindOne("user", `{"s_m_openid":"`+openid+`"}`)
-			if m != nil {
-				id := fmt.Sprintf("%x", string((*m)["_id"].(ObjectId)))
-				credit.InCreditA(id, credit.A_ZC, 0)
-			}
+		if id := Save("user", data); len(id) > 0 {
+			go credit.InCreditA(id, credit.A_ZC, 0)
 			return nil, 1
 		} else {
 			return errors.New("保存用户失败"), 0

+ 9 - 1
weixin/src/qfw/weixin/msgtxtchandler.go

@@ -73,7 +73,15 @@ func MsgTxtHandler(w ResponseWriter, r *Request) {
 		}
 	} else {
 		//属于在线咨询,暂时直接中转到微信客服系统
-		w.Reply2CustomerService()
+		//w.Reply2CustomerService()
+		//"小主的吩咐我们已经收到了,请耐心等待或留下您的联系方式(手机号或qq号),企明星客服会在下一个工作日9:00-17:00给小主回复哦!"
+		now := time.Now()
+		if now.Weekday() == 6 || now.Weekday() == 0 || (now.Hour() > 17 || now.Hour() < 9) {
+			dao.SaveWeixinOfflineMessage(r.FromUserName, r.Content, now.Unix())
+			w.ReplyText(wf.SysConfig.WeixinAutoRpl)
+		} else {
+			w.Reply2CustomerService()
+		}
 	}
 }
 

+ 46 - 0
weixin/src/qfw/weixin/rpc/share.go

@@ -0,0 +1,46 @@
+package rpc
+
+import (
+	"encoding/json"
+	"github.com/SKatiyar/qr"
+	"log"
+	"qfw/util/redis"
+	"strconv"
+)
+
+/**生成分享二维码
+规则:自动生成二维码,存储并存储到redis中
+	开发在使用时,先查看redis,没有的话再调用此RPC方法
+	生成的二维码有效期为一个月
+**/
+func (wxrpc *WeiXinRpc) GetShareQR(shareid int, ret *string) (err error) {
+	//构造自定义消息文本
+	var msg struct {
+		Expire int    `json:"expire_seconds"`
+		Name   string `json:"action_name"`
+		Info   struct {
+			Scene struct {
+				Id int `json:"scene_id"`
+			} `json:"scene"`
+		} `json:"action_info"`
+	}
+	msg.Expire = 2592000
+	msg.Name = "QR_SCENE"
+	msg.Info.Scene.Id = shareid
+	data, err := wxrpc.wx.PostCustomMsg("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=", &msg)
+	if err != nil {
+		*ret = "faile"
+		log.Println(err.Error())
+		return nil
+	}
+	tmp := map[string]interface{}{}
+	json.Unmarshal(data, &tmp)
+	url := tmp["url"].(string)
+	//生二维码
+	r, _ := qr.Encode(url, qr.L)
+	pngdat := r.PNG()
+	//存储到redis
+	redis.PutBytes("sso", "p_share_"+strconv.Itoa(shareid), &pngdat, msg.Expire)
+	*ret = "ok"
+	return nil
+}

+ 11 - 4
weixin/src/qfw/weixin/subscribehandler.go

@@ -12,6 +12,7 @@ import (
 	"qfw/weixin/dao"
 	"qfw/weixinconfig"
 	"regexp"
+	"strings"
 	"time"
 )
 
@@ -37,6 +38,7 @@ func SubscribeHandler(w ResponseWriter, r *Request) {
 		bindweixin, _ = ret["nickname"].(string)
 		//取得用户头像
 		headimgurl, _ := ret["headimgurl"].(string)
+		log.Println("download userface :", headimgurl)
 		userphoto = downloadUserFace(headimgurl)
 	}
 	_, flag := dao.AddUser(openid, unionid, bindweixin, userphoto)
@@ -49,12 +51,15 @@ func SubscribeHandler(w ResponseWriter, r *Request) {
 	}
 
 	if digitreg.MatchString(source) {
-		//
-		//log.Println("user-key:", source)
 		dao.SaveSubscribeLogs(openid, unionid, bindweixin, "wangzhan", "subscribe")
 		if flag == 1 {
 			w.ReplyText(WELCOME_MSG) // 有新人关注,返回欢迎消息
 			redis.Put("sso", "new_"+source, openid, 900)
+			//TODO 处理分享(邀请)类的二维码,记录邀请关系
+			if strings.HasPrefix(source, "32") {
+				//shareid, _ := strconv.Atoi(source)
+				go dao.SaveInviteLink(source, r.FromUserName)
+			}
 		} else {
 			w.ReplyText(OWELCOME_MSG) // 有旧人关注,返回欢迎消息
 		}
@@ -90,8 +95,8 @@ func UnSubscribeHandler(w ResponseWriter, r *Request) {
 
 //扫描二维码事件处理
 func ScanHandler(w ResponseWriter, r *Request) {
-	//log.Println("扫码事件::", r.EventKey, r.Event)
-	//log.Println("user-key:", r.EventKey)
+	log.Println("扫码事件::", r.EventKey, r.Event)
+	log.Println("user-key:", r.EventKey)
 	w.ReplyText(weixinconfig.SysConfig.LoginTip)
 	DoLogin(r.EventKey, r.FromUserName)
 
@@ -119,6 +124,8 @@ func downloadUserFace(url string) string {
 		defer resp.Body.Close()
 		if err == nil {
 			io.Copy(fi, resp.Body)
+		} else {
+			log.Println("download userface err:", err.Error())
 		}
 	}, func(e interface{}) {})
 	return filename

+ 13 - 0
weixin/src/qfw/weixin/txt_test.go

@@ -0,0 +1,13 @@
+package weixin
+
+import (
+	"log"
+	"testing"
+	"time"
+)
+
+func TestWeek(t *testing.T) {
+	d := time.Now()
+	d = d.AddDate(0, 0, 2)
+	log.Println(d.Hour(), d.Weekday(), int(d.Weekday()), d.Weekday() == 5)
+}

+ 2 - 0
weixin/src/qfw/weixin/weixinsdk.go

@@ -1133,10 +1133,12 @@ func (rw responseWriter) GetUserBaseInfo(openid string) (map[string]interface{},
 func (w *Weixin) GetUserBaseInfo(openid string) (map[string]interface{}, error) {
 	bs, err := sendGetRequest(weixinUserInfo+"?openid="+openid+"&lang=zh_CN&access_token=", w.tokenChan)
 	if err == nil {
+		log.Println("get userinfo ", string(bs))
 		ret := map[string]interface{}{}
 		err = json.Unmarshal(bs, &ret)
 		return ret, err
 	} else {
+		log.Println("get userinfo err ", err.Error())
 		return nil, err
 	}
 }

+ 1 - 9
weixin/src/qfw/weixinconfig/config_test.go

@@ -1,16 +1,8 @@
 package weixinconfig
 
-import (
-	"log"
-
-	"qfw/util"
-	"testing"
-)
+import ()
 
 //初始化
 func TestReadConfig(t *testing.T) {
 
-	//读取配置
-	util.ReadConfig("../../config.json", &SysConfig)
-	log.Println(SysConfig)
 }

+ 1 - 0
weixin/src/qfw/weixinconfig/weixinconfig.go

@@ -29,6 +29,7 @@ type wxconfig struct {
 	LoginTip        string            `json:"loginTip"`
 	FreezeTip       string            `json:"freezeTip"`
 	Activity        map[string]string `json:"activity"` //活动配置
+	WeixinAutoRpl   string            `json:"weixinautorpl"`
 }
 
 //系统配置