Ver código fonte

Merge branch 'dev2.8.5' of http://192.168.3.207:10080/qmx/jy into dev2.8.5

wangkaiyue 5 anos atrás
pai
commit
bc587a64ce
63 arquivos alterados com 2281 adições e 605 exclusões
  1. 2 2
      README.md
  2. 2 1
      src/config.json
  3. 25 2
      src/jfw/front/shorturl.go
  4. 1 1
      src/jfw/jyutil/sessionkeep.go
  5. 2 2
      src/jfw/modules/pushent/src/config.json
  6. 1 1
      src/jfw/modules/pushent/src/followpush/push.go
  7. 1 2
      src/jfw/modules/pushent/src/rpccall/weixinrpc.go
  8. BIN
      src/jfw/modules/pushent/src/src
  9. 2 2
      src/jfw/modules/pushproject/src/config.json
  10. 1 1
      src/jfw/modules/pushproject/src/followpush/push.go
  11. 1 2
      src/jfw/modules/pushproject/src/rpccall/weixinrpc.go
  12. BIN
      src/jfw/modules/pushproject/src/src
  13. 7 8
      src/jfw/modules/pushsubscribe/src/match/job/matchjob.go
  14. 1 2
      src/jfw/modules/pushsubscribe/src/match/main.go
  15. BIN
      src/jfw/modules/pushsubscribe/src/match/match
  16. 0 13
      src/jfw/modules/pushsubscribe/src/match/util/util.go
  17. 34 15
      src/jfw/modules/pushsubscribe/src/public/util.go
  18. 0 3
      src/jfw/modules/pushsubscribe/src/push/config/config.go
  19. 5 5
      src/jfw/modules/pushsubscribe/src/push/job/movejob.go
  20. 4 4
      src/jfw/modules/pushsubscribe/src/push/job/projectjob.go
  21. BIN
      src/jfw/modules/pushsubscribe/src/push/push
  22. 3 3
      src/jfw/modules/pushsubscribe/src/push/pusher/normalpush.go
  23. 2 1
      src/jfw/modules/pushsubscribe/src/push/pusher/repairpush.go
  24. 3 3
      src/jfw/modules/pushsubscribe/src/push/pusher/specialpush.go
  25. 1 3
      src/jfw/modules/pushsubscribe/src/push/util/db.go
  26. 3 0
      src/jfw/modules/pushsubscribe/src/push/util/entity.go
  27. 1 9
      src/jfw/modules/pushsubscribe/src/push/util/util.go
  28. 43 0
      src/jfw/modules/pushsubscribe/src/report/config.json
  29. 54 0
      src/jfw/modules/pushsubscribe/src/report/config/config.go
  30. 9 0
      src/jfw/modules/pushsubscribe/src/report/job/jobs.go
  31. 147 0
      src/jfw/modules/pushsubscribe/src/report/job/pushjob.go
  32. 349 0
      src/jfw/modules/pushsubscribe/src/report/job/statisticjob.go
  33. 56 0
      src/jfw/modules/pushsubscribe/src/report/job/timetask.go
  34. 42 0
      src/jfw/modules/pushsubscribe/src/report/main.go
  35. 27 0
      src/jfw/modules/pushsubscribe/src/report/util/db.go
  36. 2 0
      src/jfw/modules/subscribepay/src/a/init.go
  37. 8 15
      src/jfw/modules/subscribepay/src/config.json
  38. 2 6
      src/jfw/modules/subscribepay/src/config/config.go
  39. 406 0
      src/jfw/modules/subscribepay/src/report/report.go
  40. 9 7
      src/jfw/modules/subscribepay/src/util/db.go
  41. 40 30
      src/jfw/public/public.go
  42. 9 3
      src/jfw/qrmanager/qrmanager.go
  43. 467 401
      src/seo.json
  44. 3 0
      src/web/staticres/css/pc.css
  45. 9 10
      src/web/staticres/css/wxlist.css
  46. BIN
      src/web/staticres/images/pc/sem.jpg
  47. 3 0
      src/web/staticres/js/login.js
  48. 2 2
      src/web/staticres/js/public-nav.js
  49. BIN
      src/web/staticres/upload/2018/11/15/201811151709277155.jpg
  50. BIN
      src/web/staticres/upload/2018/12/10/201812100929403970.jpg
  51. BIN
      src/web/staticres/upload/2019/02/26/201902261001565574.jpg
  52. BIN
      src/web/staticres/upload/2019/02/26/201902261025438255.jpg
  53. BIN
      src/web/staticres/upload/2019/02/26/201902261036379066.jpg
  54. 21 25
      src/web/staticres/vipsubscribe/css/subscribe_list.css
  55. 76 0
      src/web/staticres/vipsubscribe/css/vipreport_dialog.css
  56. 3 0
      src/web/staticres/vipsubscribe/image/vipreport/close.svg
  57. BIN
      src/web/staticres/vipsubscribe/image/vipreport/dialog-image.png
  58. BIN
      src/web/staticres/vipsubscribe/image/vipreport/report.png
  59. 296 0
      src/web/templates/pc/biddetail_bd.html
  60. 1 1
      src/web/templates/pchelper/pushView.html
  61. 87 12
      src/web/templates/weixin/historypush.html
  62. 5 5
      src/web/templates/weixin/my.html
  63. 3 3
      src/web/templates/weixin/search/mainSearch.html

+ 2 - 2
README.md

@@ -3,5 +3,5 @@
 weixin sdk https://github.com/wizjin/weixin
 web用xweb框架
 
-v2.8.5
-微信端vip订阅
+v2.8.7
+订阅报告

+ 2 - 1
src/config.json

@@ -65,7 +65,8 @@
         "mymenu": "/front/wxMyOrder/myMenu",
 		"historypush": "/swordfish/historypush?times=%s",
 		"msgremind": "/front/vipsubscribe/msgremind?%s",
-		"treasurebox":"/jyTreasureBox/treasureBox"
+		"treasurebox":"/jyTreasureBox/treasureBox",
+		"vipreport":"/subscribepay/report/wxtplmsg?start=%s&end=%s&pushcount=%s"
     },
     "jy_activeset": {
         "activitystartcode": "3201000000",

+ 25 - 2
src/jfw/front/shorturl.go

@@ -31,6 +31,7 @@ var Map_stype = map[string]bool{
 	"content":     true,
 	"bdprivate":   true,
 	"mailprivate": true,
+	"bdcontent":   true,
 }
 
 func (s *Short) Article(stype, id string) error {
@@ -50,7 +51,7 @@ func (s *Short) Article(stype, id string) error {
 	if !Map_stype[stype] {
 		s.Redirect("/not/nottype", 302)
 		return nil
-	} else if stype == "content" {
+	} else if stype == "content" || stype == "bdcontent" {
 		if s.Session().Get("userId") == nil {
 			if s.GetString("state") == "wx" {
 				//微信跳回来的
@@ -79,10 +80,32 @@ func (s *Short) Article(stype, id string) error {
 			if bm { //是否是移动端访问
 				s.Redirect(aboutUrl, 302)
 			} else {
-				s.Redirect("/notin/page", 302)
+				if stype == "bdcontent" {
+					var retMap = make(map[string]interface{})
+					stype = "content"
+					_id := util.CommonDecodeArticle(stype, id)[0]
+					_, _, _, obj := pcVRT(_id, "")
+					if obj != nil && len(obj) > 0 {
+						retMap["_id"] = id
+						retMap["title"], _ = obj["title"].(string)
+						retMap["area"], _ = obj["area"].(string)
+						retMap["subtype"], _ = obj["subtype"].(string)
+						retMap["subscopeclass"], _ = obj["s_subscopeclass"].(string)
+						retMap["publishtime"] = util.IntAll(obj["publishtime"])
+					}
+					s.T["shareid"] = config.Seoconfig["baiduSEM-p"].(string)
+					s.T["logid"] = config.Seoconfig["baiduSEM-p"].(string)
+					s.T["obj"] = retMap
+					s.Render("/pc/biddetail_bd.html", &s.T)
+				} else {
+					s.Redirect("/notin/page", 302)
+				}
 			}
 			return nil
 		}
+		if stype == "bdcontent" {
+			stype = "content"
+		}
 	}
 	ssOpenid := s.Session().Get("s_m_openid")
 	userId, _ := s.GetSession("userId").(string)

+ 1 - 1
src/jfw/jyutil/sessionkeep.go

@@ -119,7 +119,7 @@ func (sk *SessionKeep) Do(w http.ResponseWriter, r *http.Request) bool {
 			}
 		} else {
 			if strings.HasPrefix(rqu, "/article/") {
-				if strings.HasPrefix(rqu, "/article/mailprivate") || strings.HasPrefix(rqu, "/article/bdprivate") || reg.MatchString(rhdua) {
+				if strings.HasPrefix(rqu, "/article/mailprivate") || strings.HasPrefix(rqu, "/article/bdprivate") || strings.HasPrefix(rqu, "/article/bdcontent") || reg.MatchString(rhdua) {
 					return true
 				} else { //只处理pc
 					session.Set("referer", r.RequestURI)

+ 2 - 2
src/jfw/modules/pushent/src/config.json

@@ -16,7 +16,7 @@
     "mongodbName": "qfw",
     "mongodbPoolSize": "20",
     "mongodbServers": "192.168.3.128:27080",
-    "redisServers": "sso=192.168.3.128:3379,other=192.168.3.128:3379,push=192.168.3.128:3379",
+    "redisServers": "push=192.168.3.128:5001",
     "viewDomain": "https://web-jydev-wcj.jianyu360.cn",
     "weixinRpcServer": "127.0.0.1:8083",
     "wxcolor": "#25c78c",
@@ -25,7 +25,7 @@
     "wxtitle": "您关注的企业“%s”有新的公告信息!如果不想继续收到此类信息,可进入发现-我关注的企业进行取消。",
 	"wxdetailcolor":"#686868",
 	"appPushServiceRpc":"127.0.0.1:5566",
-	"testids":[],
+	"testids":["5d81c5a525ef8723ac0036f9"],
 	"pushPool": 30,
 	"eachPool": 30
 }

+ 1 - 1
src/jfw/modules/pushent/src/followpush/push.go

@@ -403,7 +403,7 @@ func push(fid, sname, userId string, res *[]map[string]interface{}) {
 					descriptAppend = fmt.Sprintf("\n...(共%d条)", pushnum)
 					jpushtitle = fmt.Sprintf("1. %s", jpushtitle)
 				}
-				isPushOk := jy.AppPush(Sysconfig["appPushServiceRpc"].(string), map[string]interface{}{
+				isPushOk := qrpc.AppPush(Sysconfig["appPushServiceRpc"].(string), map[string]interface{}{
 					"phoneType":      phoneType,
 					"otherPushId":    opushid,
 					"jgPushId":       jpushid,

+ 1 - 2
src/jfw/modules/pushent/src/rpccall/weixinrpc.go

@@ -2,7 +2,6 @@ package rpccall
 
 import (
 	"config"
-	"qfw/util/jy"
 	qrpc "qfw/util/rpc"
 	"strings"
 	"time"
@@ -12,7 +11,7 @@ import (
 //微信远程调用,实现模板发送消息
 func SendWinXin(p *qrpc.NotifyMsg, userId string) bool {
 	time.Sleep(10 * time.Millisecond)
-	ok, res := jy.WxPush(config.Sysconfig["weixinRpcServer"].(string), "WeiXinRpc.SendPushMsg", p)
+	ok, res := qrpc.WxPush(config.Sysconfig["weixinRpcServer"].(string), "WeiXinRpc.SendPushMsg", p)
 	if !ok && (strings.Contains(res, "[46004]") || strings.Contains(res, "[65302]") || strings.Contains(res, "[43004]") || strings.Contains(res, "[40003]")) {
 		tools.MQFW.UpdateById("user", userId, map[string]interface{}{
 			"$set": map[string]interface{}{

BIN
src/jfw/modules/pushent/src/src


+ 2 - 2
src/jfw/modules/pushproject/src/config.json

@@ -14,7 +14,7 @@
 	"mongodbName": "qfw",
 	"mongodbPoolSize": "20",
 	"mongodbServers": "192.168.3.128:27080",
-	"redisServers": "sso=192.168.3.128:3379,other=192.168.3.128:3379,push=192.168.3.128:3379",
+	"redisServers": "push=192.168.3.128:5001",
 	"rpcPort": "8759",
 	"viewDomain": "http://web-jydev-wcj.jianyu360.cn",
 	"weixinRpcServer": "127.0.0.1:8083",
@@ -24,7 +24,7 @@
 	"wxtitle": "您关注的项目《%s》有新的公告信息!如果不想继续收到此类信息,可进入发现-我关注的项目进行取消。",
 	"wxdetailcolor":"#686868",
 	"appPushServiceRpc":"127.0.0.1:5566",
-	"testids":[],
+	"testids":["5d81c5a525ef8723ac0036f9"],
 	"pushPool": 30,
 	"eachPool": 30
 }

+ 1 - 1
src/jfw/modules/pushproject/src/followpush/push.go

@@ -511,7 +511,7 @@ func push(fid interface{}, sname, scode, title, userId string, res *[]map[string
 							descriptAppend = fmt.Sprintf("\n...(共%d条)", pushnum)
 							jpushtitle = fmt.Sprintf("1. %s", jpushtitle)
 						}
-						isPushOk := jy.AppPush(Sysconfig["appPushServiceRpc"].(string), map[string]interface{}{
+						isPushOk := qrpc.AppPush(Sysconfig["appPushServiceRpc"].(string), map[string]interface{}{
 							"phoneType":      phoneType,
 							"otherPushId":    opushid,
 							"jgPushId":       jpushid,

+ 1 - 2
src/jfw/modules/pushproject/src/rpccall/weixinrpc.go

@@ -2,7 +2,6 @@ package rpccall
 
 import (
 	"config"
-	"qfw/util/jy"
 	qrpc "qfw/util/rpc"
 	"strings"
 	"time"
@@ -12,7 +11,7 @@ import (
 //微信远程调用,实现模板发送消息
 func SendWinXin(p *qrpc.NotifyMsg, userId string) bool {
 	time.Sleep(10 * time.Millisecond)
-	ok, res := jy.WxPush(config.Sysconfig["weixinRpcServer"].(string), "WeiXinRpc.SendPushMsg", p)
+	ok, res := qrpc.WxPush(config.Sysconfig["weixinRpcServer"].(string), "WeiXinRpc.SendPushMsg", p)
 	if !ok && (strings.Contains(res, "[46004]") || strings.Contains(res, "[65302]") || strings.Contains(res, "[43004]") || strings.Contains(res, "[40003]")) {
 		tools.MQFW.UpdateById("user", userId, map[string]interface{}{
 			"$set": map[string]interface{}{

BIN
src/jfw/modules/pushproject/src/src


+ 7 - 8
src/jfw/modules/pushsubscribe/src/match/job/matchjob.go

@@ -5,8 +5,6 @@ import (
 	"fmt"
 	. "match/config"
 	. "match/matcher"
-	mutil "match/util"
-	"public"
 	. "public"
 	"qfw/util"
 	"qfw/util/elastic"
@@ -22,6 +20,7 @@ import (
 )
 
 const (
+	DbName       = "qfw"
 	DB           = "bidding"
 	MaxId        = `{"query":{"filtered":{"filter":{"bool":{"must":{"range":{"id":{"gt":"%s"}}}}}}},"_source":["_id","comeintime"],"sort":{"id":"desc"},"from":0,"size":1}`
 	ProjectQuery = `{"query":{"filtered":{"filter":{"term":{"list.infoid":"%s"}}}},"_source":["_id","list.infoid"],"sort":{"id":"desc"},"from":0,"size":1}`
@@ -140,7 +139,7 @@ func (m *MatchJob) LoadBidding(lastId, newId string, lastTime int64) *[]map[stri
 		res = append(res, temp)
 		//信息缓存3天
 		info := map[string]interface{}{}
-		for _, v := range public.InfoSaveFields {
+		for _, v := range InfoSaveFields {
 			if v == "_id" || temp[v] == nil {
 				continue
 			}
@@ -166,7 +165,7 @@ func (m *MatchJob) OnceUserBatch(batchIndex int, lastUserId *string) (int, *VipU
 	}
 	_idq := map[string]interface{}{}
 	if len(Config.TestIds) > 0 {
-		_idq["$in"] = mutil.ToObjectIds(Config.TestIds)
+		_idq["$in"] = ToObjectIds(Config.TestIds)
 	}
 	if *lastUserId != "" {
 		_idq["$gt"] = bson.ObjectIdHex(*lastUserId)
@@ -177,7 +176,7 @@ func (m *MatchJob) OnceUserBatch(batchIndex int, lastUserId *string) (int, *VipU
 	logger.Info("开始加载第", batchIndex, "批用户", q)
 	session := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(session)
-	query := session.DB(DbName).C(User).Find(&q).Select(public.UserCollFields).Sort("_id").Iter()
+	query := session.DB(DbName).C(User).Find(&q).Select(UserCollFields).Sort("_id").Iter()
 	n := 0
 	freeUser := NewFreeUser() //免费所有用户
 	vipUser := NewVipUser()   //vip所有用户
@@ -202,7 +201,7 @@ func (m *MatchJob) OnceUserBatch(batchIndex int, lastUserId *string) (int, *VipU
 				<-loadUserPool
 				loadUserWaitGroup.Done()
 			}()
-			user, o_msgset := public.NewUserInfoByUserColl(Config.PcHelper, Config.PcHelperSleep, temp)
+			user, o_msgset := NewUserInfoByUserColl(Config.PcHelper, Config.PcHelperSleep, temp)
 			if user == nil {
 				return
 			}
@@ -529,7 +528,7 @@ func (m *MatchJob) ToMatch(batchIndex int, matcher Matcher, datas *[]map[string]
 				}
 				matchTitle[title] = true
 				info := map[string]interface{}{}
-				for _, field := range public.InfoSaveFields {
+				for _, field := range InfoSaveFields {
 					if (*v2.Info)[field] == nil {
 						continue
 					}
@@ -646,7 +645,7 @@ func (m *MatchJob) ToRelationProject(projectUser *map[*UserInfo]*[]string, myMat
 					projectId = project.Id
 					list_last_infoid = project.List_last_infoid
 				} else {
-					projects := elastic.Get("projectset", "projectset", fmt.Sprintf(ProjectQuery, _id))
+					projects := elastic.Get(Projectset, Projectset, fmt.Sprintf(ProjectQuery, _id))
 					if projects == nil || len(*projects) == 0 {
 						continue
 					}

+ 1 - 2
src/jfw/modules/pushsubscribe/src/match/main.go

@@ -6,7 +6,6 @@ import (
 	"log"
 	. "match/config"
 	"match/job"
-	. "public"
 	"qfw/util/elastic"
 	"qfw/util/mongodb"
 	"qfw/util/redis"
@@ -19,7 +18,7 @@ func main() {
 	flag.Parse()
 	logger.SetConsole(false)
 	logger.SetRollingDaily("./logs", "match.log")
-	mongodb.InitMongodbPool(Config.MgoSize, Config.MgoAddr, DbName)
+	mongodb.InitMongodbPool(Config.MgoSize, Config.MgoAddr, job.DbName)
 	redis.InitRedis(Config.RedisServers)
 	elastic.InitElasticSize(Config.ElasticSearch, Config.ElasticPoolSize)
 	log.Println("订阅推送-匹配数据程序启动。。。")

BIN
src/jfw/modules/pushsubscribe/src/match/match


+ 0 - 13
src/jfw/modules/pushsubscribe/src/match/util/util.go

@@ -1,13 +0,0 @@
-package util
-
-import (
-	"gopkg.in/mgo.v2/bson"
-)
-
-func ToObjectIds(ids []string) []bson.ObjectId {
-	_ids := []bson.ObjectId{}
-	for _, v := range ids {
-		_ids = append(_ids, bson.ObjectIdHex(v))
-	}
-	return _ids
-}

+ 34 - 15
src/jfw/modules/pushsubscribe/src/public/util.go

@@ -8,27 +8,30 @@ import (
 	"time"
 
 	"github.com/donnie4w/go-logger/logger"
+	"gopkg.in/mgo.v2/bson"
 )
 
 const (
-	BulkSize           = 20
-	BigBulkSize        = 100
-	OneDaySecond       = 86400
-	SevenDay           = 604800
-	User               = "user"
-	Bidding            = "bidding"
-	Pushspace_project  = "pushspace_project"
-	Pushspace_temp     = "pushspace_temp"
-	Pushspace_vip      = "pushspace_vip"
-	Pushspace_vip_fail = "pushspace_vip_fail"
-	Pushspace_fail     = "pushspace_fail"
-	Pushspace          = "pushspace"
-	Pushcache_1        = "pushcache_1"
-	Pushcache_2_a      = "pushcache_2_a"
+	BulkSize            = 20
+	BigBulkSize         = 100
+	OneDaySecond        = 86400
+	SevenDay            = 604800
+	User                = "user"
+	Bidding             = "bidding"
+	Projectset          = "projectset"
+	Pushspace_project   = "pushspace_project"
+	Pushspace_statistic = "pushspace_statistic"
+	Pushspace_temp      = "pushspace_temp"
+	Pushspace_vip       = "pushspace_vip"
+	Pushspace_vip_fail  = "pushspace_vip_fail"
+	Pushspace_fail      = "pushspace_fail"
+	Pushspace           = "pushspace"
+	Pushcache_1         = "pushcache_1"
+	Pushcache_2_a       = "pushcache_2_a"
 )
 
 var (
-	DbName         = "qfw"
+	Se             = util.SimpleEncrypt{Key: "topnet"}
 	MailReg        = regexp.MustCompile("^.+@.+$")
 	UserCollFields = map[string]interface{}{
 		"_id":             1,
@@ -50,6 +53,15 @@ var (
 		"l_firstpushtime": 1,
 	}
 	InfoSaveFields = []string{"_id", "area", "city", "buyerclass", "publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type"}
+	WeekNum        = map[string]int{
+		"Monday":    1,
+		"Tuesday":   2,
+		"Wednesday": 3,
+		"Thursday":  4,
+		"Friday":    5,
+		"Saturday":  6,
+		"Sunday":    7,
+	}
 )
 
 func IsVipUser(vipStatus int) bool {
@@ -237,3 +249,10 @@ func NewUserInfoByUserColl(address string, sleep int, temp map[string]interface{
 func PushInfoKey(userId, infoId string) string {
 	return fmt.Sprintf("pushinfo_%s_%s", userId, infoId)
 }
+func ToObjectIds(ids []string) []bson.ObjectId {
+	_ids := []bson.ObjectId{}
+	for _, v := range ids {
+		_ids = append(_ids, bson.ObjectIdHex(v))
+	}
+	return _ids
+}

+ 0 - 3
src/jfw/modules/pushsubscribe/src/push/config/config.go

@@ -3,7 +3,6 @@ package config
 import (
 	"qfw/util"
 	"qfw/util/mail"
-	"regexp"
 	"strings"
 )
 
@@ -90,8 +89,6 @@ type projectTask struct {
 
 var (
 	Gmails         []*mail.GmailAuth
-	Se             = util.SimpleEncrypt{Key: "topnet"}
-	Re             = regexp.MustCompile("<[^>]+>([^<]+)?<[^>]+>")
 	Config         *config
 	ProjectTask    *projectTask
 	WxGroupLen     int

+ 5 - 5
src/jfw/modules/pushsubscribe/src/push/job/movejob.go

@@ -46,7 +46,7 @@ func (m *MoveJob) Execute() {
 			"$in": Config.TestIds,
 		}
 	}
-	it := sess.DB(DbName).C(Pushspace_temp).Find(query).Sort("userid").Iter()
+	it := sess.DB(Config.Mongodb.DbName).C(Pushspace_temp).Find(query).Sort("userid").Iter()
 	moveUsers := map[string]*MoveUser{}
 	index, number, length := 0, 0, 0
 	//
@@ -152,7 +152,7 @@ func (m *MoveJob) merge(number *int, nowUnix int64, moveUsers map[string]*MoveUs
 			sess := mongodb.GetMgoConn()
 			defer mongodb.DestoryMongoConn(sess)
 			var data map[string]interface{}
-			sess.DB(DbName).C(Pushspace).Find(map[string]interface{}{"userid": userId}).Select(map[string]interface{}{"list": 1}).One(&data)
+			sess.DB(Config.Mongodb.DbName).C(Pushspace).Find(map[string]interface{}{"userid": userId}).Select(map[string]interface{}{"list": 1}).One(&data)
 			if data == nil { //批量新增
 				mergeLock.Lock()
 				saveArray = append(saveArray, moveUser.info)
@@ -244,7 +244,7 @@ func (m *MoveJob) saveBulk(sess *mgo.Session, saves *[]map[string]interface{}, d
 		sess = mongodb.GetMgoConn()
 		defer mongodb.DestoryMongoConn(sess)
 	}
-	coll := sess.DB(DbName).C(Pushspace)
+	coll := sess.DB(Config.Mongodb.DbName).C(Pushspace)
 	bulk := coll.Bulk()
 	for _, v := range *saves {
 		bulk.Insert(v)
@@ -262,7 +262,7 @@ func (m *MoveJob) updateBulk(sess *mgo.Session, array_q, array_s *[]map[string]i
 		sess = mongodb.GetMgoConn()
 		defer mongodb.DestoryMongoConn(sess)
 	}
-	coll := sess.DB(DbName).C(Pushspace)
+	coll := sess.DB(Config.Mongodb.DbName).C(Pushspace)
 	bulk := coll.Bulk()
 	for k, v := range *array_q {
 		bulk.Update(v, (*array_s)[k])
@@ -281,7 +281,7 @@ func (m *MoveJob) delBulk(sess *mgo.Session, array *[]interface{}) {
 		sess = mongodb.GetMgoConn()
 		defer mongodb.DestoryMongoConn(sess)
 	}
-	coll := sess.DB(DbName).C(Pushspace_temp)
+	coll := sess.DB(Config.Mongodb.DbName).C(Pushspace_temp)
 	count := 0
 	bulk := coll.Bulk()
 	for _, v := range *array {

+ 4 - 4
src/jfw/modules/pushsubscribe/src/push/job/projectjob.go

@@ -48,7 +48,7 @@ func (p *ProjectPushJob) Execute() {
 				sess := mongodb.GetMgoConn()
 				defer mongodb.DestoryMongoConn(sess)
 				var u map[string]interface{}
-				sess.DB(DbName).C(User).FindId(bson.ObjectIdHex(userId)).Select(map[string]interface{}{
+				sess.DB(Config.Mongodb.DbName).C(User).FindId(bson.ObjectIdHex(userId)).Select(map[string]interface{}{
 					"o_vipjy.i_projectmatch": 1,
 				}).One(&u)
 				if u == nil || len(u) == 0 {
@@ -213,7 +213,7 @@ func (p *ProjectPushJob) loadPushspace_project(batchIndex int, startId *string)
 	prevUserId := ""
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
-	it := sess.DB(DbName).C(Pushspace_project).Find(query).Select(map[string]interface{}{
+	it := sess.DB(Config.Mongodb.DbName).C(Pushspace_project).Find(query).Select(map[string]interface{}{
 		"_id":       1,
 		"maxid":     1,
 		"subtypes":  1,
@@ -252,7 +252,7 @@ func (p *ProjectPushJob) loadProject() *sync.Map {
 	//query = map[string]interface{}{
 	//"_id": bson.ObjectIdHex("5da828a6e138234108b4c02e"),
 	//}
-	it := sess.DB(DbName).C(Config.ProjectMongodb.CollName).Find(query).Select(map[string]interface{}{
+	it := sess.DB(Config.ProjectMongodb.DbName).C(Config.ProjectMongodb.CollName).Find(query).Select(map[string]interface{}{
 		"_id":  1,
 		"list": 1,
 	}).Sort("_id").Iter()
@@ -288,7 +288,7 @@ func (p *ProjectPushJob) Clear() {
 	logger.Info("开始清理过期的关联项目数据。。。")
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
-	_, err := sess.DB(DbName).C(Pushspace_project).RemoveAll(map[string]interface{}{
+	_, err := sess.DB(Config.Mongodb.DbName).C(Pushspace_project).RemoveAll(map[string]interface{}{
 		"createtime": map[string]interface{}{
 			"$lt": time.Now().AddDate(0, -3, 0).Unix(),
 		},

BIN
src/jfw/modules/pushsubscribe/src/push/push


+ 3 - 3
src/jfw/modules/pushsubscribe/src/push/pusher/normalpush.go

@@ -76,7 +76,7 @@ func (n *NormalPush) AfterPush(pushResult *putil.PushResult, u *UserInfo, user m
 	//判断是否要删除数据
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
-	err := sess.DB(DbName).C(Pushspace).RemoveId(user["_id"])
+	err := sess.DB(Config.Mongodb.DbName).C(Pushspace).RemoveId(user["_id"])
 	if err != nil {
 		logger.Error("推送任务", u.Id, "删除出错", err)
 	}
@@ -93,7 +93,7 @@ func (n *NormalPush) AfterPush(pushResult *putil.PushResult, u *UserInfo, user m
 		if pushResult.MailStatus == -1 {
 			user["mailfail"] = 1
 		}
-		_, err := sess.DB(DbName).C(Pushspace_fail).UpsertId(user["_id"], map[string]interface{}{"$set": user})
+		_, err := sess.DB(Config.Mongodb.DbName).C(Pushspace_fail).UpsertId(user["_id"], map[string]interface{}{"$set": user})
 		if err != nil {
 			logger.Error("推送任务", u.Id, "更新出错", err)
 		}
@@ -142,7 +142,7 @@ func (n *NormalPush) vipTempSave(u *UserInfo, pushParam *putil.PushParam) {
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
 	var data map[string]interface{}
-	coll := sess.DB(DbName).C(Pushspace_vip)
+	coll := sess.DB(Config.Mongodb.DbName).C(Pushspace_vip)
 	coll.Find(map[string]interface{}{
 		"userid":   u.Id,
 		"status":   1,

+ 2 - 1
src/jfw/modules/pushsubscribe/src/push/pusher/repairpush.go

@@ -2,6 +2,7 @@ package pusher
 
 import (
 	. "public"
+	. "push/config"
 	putil "push/util"
 	"qfw/util/mongodb"
 	"strings"
@@ -69,7 +70,7 @@ func (r *RepairPush) GetPushParam(mailPush bool, u *UserInfo, sl *SortList) *put
 func (r *RepairPush) AfterPush(pushResult *putil.PushResult, u *UserInfo, user map[string]interface{}) {
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
-	coll := sess.DB(DbName).C(Pushspace_fail)
+	coll := sess.DB(Config.Mongodb.DbName).C(Pushspace_fail)
 	if pushResult == nil || (pushResult.WxStatus != -1 && pushResult.AppStatus != -1 && pushResult.MailStatus != -1) {
 		err := coll.RemoveId(user["_id"])
 		if err != nil {

+ 3 - 3
src/jfw/modules/pushsubscribe/src/push/pusher/specialpush.go

@@ -49,7 +49,7 @@ func (s *SpecialPush) GetUserInfo(user map[string]interface{}) (*UserInfo, *puti
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
 	var u map[string]interface{}
-	sess.DB(DbName).C(User).FindId(bson.ObjectIdHex(userId)).Select(UserCollFields).One(&u)
+	sess.DB(Config.Mongodb.DbName).C(User).FindId(bson.ObjectIdHex(userId)).Select(UserCollFields).One(&u)
 	if u == nil || len(u) == 0 {
 		logger.Error(userId, "没有找到该用户信息")
 		s.deletePushspaceVip(user)
@@ -106,7 +106,7 @@ func (s *SpecialPush) AfterPush(pushResult *putil.PushResult, u *UserInfo, user
 			user["mailfail"] = 1
 		}
 		user["failtime"] = time.Now().Unix()
-		err := sess.DB(DbName).C(Pushspace_vip_fail).Insert(user)
+		err := sess.DB(Config.Mongodb.DbName).C(Pushspace_vip_fail).Insert(user)
 		if err != nil {
 			logger.Error(u.Id, "新增出错", err)
 		}
@@ -117,7 +117,7 @@ func (s *SpecialPush) AfterPush(pushResult *putil.PushResult, u *UserInfo, user
 func (s *SpecialPush) deletePushspaceVip(u map[string]interface{}) {
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
-	err := sess.DB(DbName).C(Pushspace_vip).RemoveId(u["_id"])
+	err := sess.DB(Config.Mongodb.DbName).C(Pushspace_vip).RemoveId(u["_id"])
 	if err != nil {
 		logger.Error(u["userid"], "删除出错", err)
 	}

+ 1 - 3
src/jfw/modules/pushsubscribe/src/push/util/db.go

@@ -2,7 +2,6 @@ package util
 
 import (
 	"log"
-	. "public"
 	. "push/config"
 	"qfw/util/jy"
 	"qfw/util/mongodb"
@@ -14,8 +13,7 @@ import (
 var Mysql *mysql.Mysql
 
 func init() {
-	DbName = Config.Mongodb.DbName
-	mongodb.InitMongodbPool(Config.Mongodb.Size, Config.Mongodb.Address, DbName)
+	mongodb.InitMongodbPool(Config.Mongodb.Size, Config.Mongodb.Address, Config.Mongodb.DbName)
 	project := mongoutil.PoolConfig{
 		Alias: Config.ProjectMongodb.Alias,
 		Addr:  Config.ProjectMongodb.Address,

+ 3 - 0
src/jfw/modules/pushsubscribe/src/push/util/entity.go

@@ -5,11 +5,14 @@ import (
 	. "public"
 	. "push/config"
 	"qfw/util"
+	"regexp"
 	"strings"
 
 	"github.com/donnie4w/go-logger/logger"
 )
 
+var Re = regexp.MustCompile("<[^>]+>([^<]+)?<[^>]+>")
+
 //推送返回结果
 type PushResult struct {
 	IsVipTempSave bool

+ 1 - 9
src/jfw/modules/pushsubscribe/src/push/util/util.go

@@ -12,7 +12,6 @@ import (
 	"time"
 
 	"github.com/donnie4w/go-logger/logger"
-	"gopkg.in/mgo.v2/bson"
 )
 
 var SavePool chan bool
@@ -20,13 +19,6 @@ var SavePool chan bool
 func init() {
 	SavePool = make(chan bool, Config.SavePoolSize)
 }
-func ToObjectIds(ids []string) []bson.ObjectId {
-	_ids := []bson.ObjectId{}
-	for _, v := range ids {
-		_ids = append(_ids, bson.ObjectIdHex(v))
-	}
-	return _ids
-}
 func ToSortList(list interface{}) *SortList {
 	sl := make(SortList, 0)
 	if list == nil {
@@ -99,7 +91,7 @@ func GetPushDatas(taskType, batchIndex int, collection string, startId *string,
 	i := 0
 	sess := mongodb.GetMgoConn()
 	defer mongodb.DestoryMongoConn(sess)
-	it := sess.DB(DbName).C(collection).Find(query).Sort("_id").Iter()
+	it := sess.DB(Config.Mongodb.DbName).C(collection).Find(query).Sort("_id").Iter()
 	for temp := make(map[string]interface{}); it.Next(&temp); {
 		i++
 		*startId = util.BsonIdToSId(temp["_id"])

+ 43 - 0
src/jfw/modules/pushsubscribe/src/report/config.json

@@ -0,0 +1,43 @@
+{
+	"jianyuDomain":"https://web-jydev-wcj.jianyu360.cn",
+	"weixinRpcServer":"127.0.0.1:8083",
+	"elasticPoolSize":1,
+	"elasticSearch":"http://192.168.3.128:9800",
+	"mongodb":{
+		"dbName":"qfw",
+		"address":"192.168.3.128:27080",
+		"size":5
+	},
+	"mysql":{
+        "dbName":"jianyu",
+        "address":"192.168.3.11:3366",
+        "userName":"root",
+        "passWord":"Topnet123",
+		"maxOpenConns": 60,
+		"maxIdleConns": 10
+    },
+	"pushMonth":2,
+	"pushWeek":"Tuesday",
+	"pushTime":"7:00",
+	"statisticTime":"1:30",
+	"pushPoolSize":10,
+	"statisticPoolSize":10,
+	"testids":["5d81c5a525ef8723ac0036f9"],
+	"statisticBatch":100,
+	"pushBatch":100,
+	"wxTplMsg":{
+		"id": "uOIrT3SBSfVFEY0Ybm6wyEKIiUwAytb9YUlLOqv7uSw",
+		"first":{
+			"value":"VIP订阅用户,本期数据报告已生成,快来查看吧!"
+		},
+		"keyword1": {
+			"value":"数据报告(VIP订阅)"
+		},
+		"keyword2": {
+			"value":"%s-%s"
+		},
+		"remark": {
+			"value":"点击查看详情!"
+		}
+	}
+}

+ 54 - 0
src/jfw/modules/pushsubscribe/src/report/config/config.go

@@ -0,0 +1,54 @@
+package config
+
+import (
+	"qfw/util"
+	qrpc "qfw/util/rpc"
+)
+
+type config struct {
+	JianyuDomain    string `json:"jianyuDomain"`
+	WeixinRpcServer string `json:"weixinRpcServer"`
+	ElasticPoolSize int    `json:"elasticPoolSize"`
+	ElasticSearch   string `json:"elasticSearch"`
+	Mongodb         struct {
+		Alias    string `json:"alias"`
+		DbName   string `json:"dbName"`
+		CollName string `json:"collName"`
+		Address  string `json:"address"`
+		Size     int    `json:"size"`
+	} `json:"mongodb"`
+	Mysql struct {
+		DbName       string
+		Address      string
+		UserName     string
+		PassWord     string
+		MaxOpenConns int
+		MaxIdleConns int
+	} `json:"mysql"`
+	PushMonth         int       `json:"pushMonth"`
+	PushWeek          string    `json:"pushWeek"`
+	PushTime          string    `json:"pushTime"`
+	StatisticTime     string    `json:"statisticTime"`
+	PushPoolSize      int       `json:"pushPoolSize"`
+	StatisticPoolSize int       `json:"statisticPoolSize"`
+	TestIds           []string  `json:"testids"`
+	StatisticBatch    int       `json:"statisticBatch"`
+	PushBatch         int       `json:"pushBatch"`
+	WxTplMsg          *WxTplMsg `json:"wxTplMsg"`
+}
+
+type WxTplMsg struct {
+	Id       string
+	First    *qrpc.TmplItem
+	Keyword1 *qrpc.TmplItem
+	Keyword2 *qrpc.TmplItem
+	Keyword3 *qrpc.TmplItem
+	Keyword4 *qrpc.TmplItem
+	Remark   *qrpc.TmplItem
+}
+
+var Config *config
+
+func init() {
+	util.ReadConfig(&Config)
+}

+ 9 - 0
src/jfw/modules/pushsubscribe/src/report/job/jobs.go

@@ -0,0 +1,9 @@
+package job
+
+var Jobs = struct {
+	Statistic *StatisticJob
+	Push      *PushJob
+}{
+	Statistic: &StatisticJob{},
+	Push:      &PushJob{},
+}

+ 147 - 0
src/jfw/modules/pushsubscribe/src/report/job/pushjob.go

@@ -0,0 +1,147 @@
+package job
+
+import (
+	"fmt"
+	. "public"
+	"qfw/util"
+	"qfw/util/mongodb"
+	qrpc "qfw/util/rpc"
+	. "report/config"
+	"strconv"
+	"sync"
+	"time"
+
+	"github.com/donnie4w/go-logger/logger"
+	"gopkg.in/mgo.v2/bson"
+)
+
+type PushJob struct {
+}
+
+func (p *PushJob) Execute(startDate, endDate int64) {
+	defer util.Catch()
+	logger.Info("开始推送。。。", startDate, endDate)
+	batchIndex := 0
+	startId := ""
+	//
+	pool := make(chan bool, Config.PushPoolSize)
+	wait := &sync.WaitGroup{}
+	for {
+		batchIndex++
+		isBreak, users := p.OnceBatch(batchIndex, startDate, endDate, &startId)
+		for _, temp := range *users {
+			pool <- true
+			wait.Add(1)
+			go func(v map[string]interface{}) {
+				defer func() {
+					util.Catch()
+					<-pool
+					wait.Done()
+				}()
+				sess := mongodb.GetMgoConn()
+				if sess == nil {
+					logger.Error("获取mongodb连接错误")
+					return
+				}
+				defer mongodb.DestoryMongoConn(sess)
+				userId, _ := v["userid"].(string)
+				logger.Info("开始推送用户", userId)
+				var user map[string]interface{}
+				sess.DB(Config.Mongodb.DbName).C(User).FindId(bson.ObjectIdHex(userId)).Select(map[string]interface{}{
+					"_id":           1,
+					"s_m_openid":    1,
+					"s_jpushid":     1,
+					"s_opushid":     1,
+					"i_ispush":      1,
+					"s_appponetype": 1,
+				}).One(&user)
+				s_m_openid, _ := user["s_m_openid"].(string)
+				isPushWx := util.IntAllDef(user["i_ispush"], 1)
+				//jpushid, _ := user["s_jpushid"].(string)
+				//opushid, _ := user["s_opushid"].(string)
+				//phoneType, _ := user["s_appponetype"].(string)
+				wxPushOk := false
+				start := util.FormatDateByInt64(&startDate, "2006年01月02日")
+				end := util.FormatDateByInt64(&endDate, "2006年01月02日")
+				if isPushWx == 1 && s_m_openid != "" {
+					tmplData := map[string]*qrpc.TmplItem{
+						"first": &qrpc.TmplItem{
+							Value: Config.WxTplMsg.First.Value,
+						},
+						"keyword1": &qrpc.TmplItem{
+							Value: Config.WxTplMsg.Keyword1.Value,
+						},
+						"keyword2": &qrpc.TmplItem{
+							Value: fmt.Sprintf(Config.WxTplMsg.Keyword2.Value, start, end),
+						},
+						"remark": &qrpc.TmplItem{
+							Value: Config.WxTplMsg.Remark.Value,
+						},
+					}
+					wxPushOk, _ = qrpc.WxSendTmplMsg(Config.WeixinRpcServer, &qrpc.WxTmplMsg{
+						OpenId:   s_m_openid,
+						TplId:    Config.WxTplMsg.Id,
+						TmplData: tmplData,
+						Url:      Config.JianyuDomain + "/front/sess/" + Se.EncodeString(s_m_openid+",uid,"+strconv.Itoa(int(time.Now().Unix()))+",vipreport") + "__" + fmt.Sprint(startDate) + "__" + fmt.Sprint(endDate) + "__" + fmt.Sprint(util.IntAll(v["pushcount"])),
+					})
+					logger.Info("微信推送", userId, wxPushOk)
+				}
+				if wxPushOk {
+					sess.DB(Config.Mongodb.DbName).C(Pushspace_statistic).UpdateId(v["_id"], map[string]interface{}{
+						"$set": map[string]interface{}{
+							"unread":   1,
+							"tip":      1,
+							"ispush":   1,
+							"pushtime": time.Now().Unix(),
+						},
+					})
+				}
+			}(temp)
+		}
+		if isBreak {
+			break
+		}
+	}
+	wait.Wait()
+	logger.Info("推送结束。。。")
+}
+
+//分批次加载
+func (p *PushJob) OnceBatch(batchIndex int, startDate, endDate int64, startId *string) (bool, *[]map[string]interface{}) {
+	query := map[string]interface{}{
+		"ispush":    0,
+		"startdate": startDate,
+		"enddate":   endDate,
+	}
+	if len(Config.TestIds) > 0 {
+		query["userid"] = map[string]interface{}{
+			"$in": Config.TestIds,
+		}
+	}
+	if *startId != "" {
+		query["_id"] = map[string]interface{}{
+			"$gt": bson.ObjectIdHex(*startId),
+		}
+	}
+	logger.Info("开始加载第", batchIndex, "批推送用户", query)
+	users := []map[string]interface{}{}
+	i := 0
+	sess := mongodb.GetMgoConn()
+	defer mongodb.DestoryMongoConn(sess)
+	it := sess.DB(Config.Mongodb.DbName).C(Pushspace_statistic).Find(query).Select(map[string]interface{}{
+		"_id":       1,
+		"userid":    1,
+		"pushcount": 1,
+	}).Sort("_id").Iter()
+	for temp := make(map[string]interface{}); it.Next(&temp); {
+		i++
+		*startId = util.BsonIdToSId(temp["_id"])
+		users = append(users, temp)
+		temp = make(map[string]interface{})
+		if i == Config.StatisticBatch {
+			break
+		}
+	}
+	logger.Info("第", batchIndex, "推送用户加载结束", *startId)
+	return i < Config.StatisticBatch, &users
+}

+ 349 - 0
src/jfw/modules/pushsubscribe/src/report/job/statisticjob.go

@@ -0,0 +1,349 @@
+package job
+
+import (
+	"fmt"
+	. "public"
+	"qfw/util"
+	"qfw/util/elastic"
+	"qfw/util/mongodb"
+	. "report/config"
+	. "report/util"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/donnie4w/go-logger/logger"
+	mgo "gopkg.in/mgo.v2"
+	"gopkg.in/mgo.v2/bson"
+)
+
+const (
+	ProjectQuery  = `{"query":{"filtered":{"filter":{"terms":{"list.infoid":[%s]}}}},"_source":["list.subtype","list.toptype"],"from":0,"size":%d}`
+	batchIdLength = 20
+)
+
+//时间都是,没有
+type StatisticJob struct {
+	month_start      int64 //今天所在月份开始时间,精确到年月日
+	month_end        int64 //今天所在月份结束时间,精确到年月日
+	week_start       int64 //今天所在周开始时间,精确到年月日
+	week_end         int64 //今天所在周结束时间,精确到年月日
+	today_start      int64 //今天开始时间,精确到年月日
+	today_end        int64 //今天结束时间,精确到年月日
+	today_end_ymdhms int64 //今天结束时间,精确到年月日时分秒,查询mysql推送历史用到
+}
+
+func (s *StatisticJob) Execute(now time.Time) {
+	defer util.Catch()
+	s.today_start, s.today_end, s.today_end_ymdhms = s.GetToday(now)
+	s.week_start, s.week_end = s.GetWeek(now)
+	s.month_start, s.month_end = s.GetMonth(now)
+	logger.Info("开始统计。。。", util.FormatDate(&now, util.Date_yyyyMMdd))
+	batchIndex := 0
+	startId := ""
+	//
+	pool := make(chan bool, Config.StatisticPoolSize)
+	wait := &sync.WaitGroup{}
+	for {
+		batchIndex++
+		isBreak, users := s.OnceBatch(batchIndex, &startId)
+		for _, temp := range *users {
+			pool <- true
+			wait.Add(1)
+			go func(v map[string]interface{}) {
+				defer func() {
+					util.Catch()
+					<-pool
+					wait.Done()
+				}()
+				if s.Filter(now, util.Int64All(v["l_vip_starttime"])) {
+					return
+				}
+				userId := util.BsonIdToSId(v["_id"])
+				logger.Info("开始统计用户", "userId", userId)
+				todayPushCount := Mysql.CountBySql("select count(1) from pushsubscribe where userid=? and date>=? and date<=? and isvip=1", userId, s.today_start, s.today_end_ymdhms)
+				//toptype
+				toptype := Mysql.SelectBySql("select b.name,sum(1) as sum from (select if(toptype is null,5,toptype) as toptype from pushsubscribe where userid=? and date>=? and date<=? and isvip=1) as a inner join infotype b on (a.toptype=b.id) group by a.toptype", userId, s.today_start, s.today_end_ymdhms)
+				todayToptype := map[string]int{}
+				for _, v := range *toptype {
+					todayToptype[util.ObjToString(v["name"])] = util.IntAll(v["sum"])
+				}
+				//subtype统计
+				subtype := Mysql.SelectBySql("select b.name,sum(1) as sum from (select if(subtype is null,15,subtype) as subtype from pushsubscribe where userid=? and date>=? and date<=? and toptype=1 and isvip=1) as a inner join infotype b on (a.subtype=b.id) group by a.subtype", userId, s.today_start, s.today_end_ymdhms)
+				todaySubtype := map[string]int{}
+				for _, v := range *subtype {
+					todaySubtype[util.ObjToString(v["name"])] = util.IntAll(v["sum"])
+				}
+				datas := Mysql.SelectBySql("select infoid from pushsubscribe where userid=? and date>=? and date<=? and toptype=4 and isvip=1", userId, s.today_start, s.today_end_ymdhms)
+				if datas != nil {
+					projectSubtypes := s.SearchProject(datas)
+					for _, v := range projectSubtypes {
+						todaySubtype[v] = todaySubtype[v] + 1
+					}
+				}
+				//关键词统计
+				matchkeys := Mysql.SelectBySql("select a.matchkeys,sum(1) as sum from (select matchkeys from pushsubscribe where userid=? and date>=? and date<=? and isvip=1 and matchkeys is not null) as a group by a.matchkeys", userId, s.today_start, s.today_end_ymdhms)
+				todayMatchkeys := map[string]int{}
+				for _, v := range *matchkeys {
+					todayMatchkeys[util.ObjToString(v["matchkeys"])] = util.IntAll(v["sum"])
+				}
+				//省统计
+				area := Mysql.SelectBySql("select b.name,sum(1) as sum from pushsubscribe as a inner join province b on (a.area=b.id) where a.userid=? and a.date>=? and a.date<=? and isvip=1 group by a.area", userId, s.today_start, s.today_end_ymdhms)
+				todayArea := map[string]int{}
+				for _, v := range *area {
+					todayArea[util.ObjToString(v["name"])] = util.IntAll(v["sum"])
+				}
+				//市统计
+				city := Mysql.SelectBySql("select d.name as area,c.name as city,c.sum from (select a.area,b.name,sum(1) as sum from pushsubscribe as a inner join province b on (a.city=b.id) where a.userid=? and a.date>=? and a.date<=? and isvip=1 group by a.city,a.area) as c inner join province d on (c.area=d.id)", userId, s.today_start, s.today_end_ymdhms)
+				todayCity := map[string]map[string]int{}
+				for _, v := range *city {
+					if todayCity[util.ObjToString(v["area"])] == nil {
+						todayCity[util.ObjToString(v["area"])] = map[string]int{}
+					}
+					todayCity[util.ObjToString(v["area"])][util.ObjToString(v["city"])] = util.IntAll(v["sum"])
+				}
+				//天
+				sess := mongodb.GetMgoConn()
+				if sess == nil {
+					logger.Error("获取mongodb连接错误")
+					return
+				}
+				defer mongodb.DestoryMongoConn(sess)
+				_, err := sess.DB(Config.Mongodb.DbName).C(Pushspace_statistic).Upsert(map[string]interface{}{
+					"userid":    userId,
+					"startdate": s.today_start,
+					"enddate":   s.today_end,
+					"type":      1,
+				}, map[string]interface{}{
+					"$set": map[string]interface{}{
+						"dateym":           s.GetDateym(s.today_end),
+						"createtime":       time.Now().Unix(),
+						"pushcount":        todayPushCount,
+						"toptype":          todayToptype,
+						"subtype_zhaobiao": todaySubtype,
+						"matchkeys":        todayMatchkeys,
+						"area":             todayArea,
+						"city":             todayCity,
+					},
+				})
+				if err != nil {
+					logger.Error(userId, "更新出错", err)
+				}
+				//周
+				s.Upsert(sess, 2, userId, s.week_start, s.week_end, todayPushCount, todayToptype, todaySubtype, todayMatchkeys, todayArea, todayCity)
+				//月
+				s.Upsert(sess, 3, userId, s.month_start, s.month_end, todayPushCount, todayToptype, todaySubtype, todayMatchkeys, todayArea, todayCity)
+			}(temp)
+		}
+		if isBreak {
+			break
+		}
+	}
+	wait.Wait()
+	logger.Info("统计结束。。。")
+}
+
+//过滤用户,非vip时间内,不出报告
+func (s *StatisticJob) Filter(now time.Time, l_vip_starttime int64) bool {
+	t1 := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
+	vip_starttime := time.Unix(l_vip_starttime, 0)
+	t2 := time.Date(vip_starttime.Year(), vip_starttime.Month(), vip_starttime.Day(), 0, 0, 0, 0, time.Local)
+	if t1.Before(t2) {
+		return true
+	}
+	return false
+}
+
+//分批次加载
+func (s *StatisticJob) OnceBatch(batchIndex int, startId *string) (bool, *[]map[string]interface{}) {
+	query := map[string]interface{}{
+		"i_vip_status": map[string]interface{}{
+			"$in": []int{1, 2},
+		},
+	}
+	if len(Config.TestIds) > 0 {
+		query["_id"] = map[string]interface{}{
+			"$in": ToObjectIds(Config.TestIds),
+		}
+	}
+	if *startId != "" {
+		query["_id"] = map[string]interface{}{
+			"$gt": bson.ObjectIdHex(*startId),
+		}
+	}
+	logger.Info("开始加载第", batchIndex, "批统计用户", query)
+	users := []map[string]interface{}{}
+	i := 0
+	sess := mongodb.GetMgoConn()
+	defer mongodb.DestoryMongoConn(sess)
+	it := sess.DB(Config.Mongodb.DbName).C(User).Find(query).Select(map[string]interface{}{
+		"_id":             1,
+		"l_vip_starttime": 1,
+	}).Sort("_id").Iter()
+	for temp := make(map[string]interface{}); it.Next(&temp); {
+		i++
+		*startId = util.BsonIdToSId(temp["_id"])
+		users = append(users, temp)
+		temp = make(map[string]interface{})
+		if i == Config.StatisticBatch {
+			break
+		}
+	}
+	logger.Info("第", batchIndex, "批统计用户加载结束", *startId)
+	return i < Config.StatisticBatch, &users
+}
+
+//获取月
+func (s *StatisticJob) GetDateym(unix int64) int {
+	return util.IntAll(util.FormatDateByInt64(&unix, "200601"))
+}
+
+//当前日的开始和结束时间
+func (s *StatisticJob) GetToday(now time.Time) (int64, int64, int64) {
+	start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
+	end := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
+	end_ymdhms := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, time.Local)
+	return start.Unix(), end.Unix(), end_ymdhms.Unix()
+}
+
+//当前周的开始和结束时间
+func (s *StatisticJob) GetWeek(now time.Time) (int64, int64) {
+	week := WeekNum[now.Weekday().String()]
+	start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
+	if s := week - 1; s > 0 {
+		start = start.AddDate(0, 0, -s)
+	}
+	end := start.AddDate(0, 0, 6)
+	return start.Unix(), end.Unix()
+}
+
+//当前月的开始和结束时间
+func (s *StatisticJob) GetMonth(now time.Time) (int64, int64) {
+	start := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
+	end := start.AddDate(0, 1, 0).AddDate(0, 0, -1)
+	return start.Unix(), end.Unix()
+}
+
+//新增或者更新库中月、周的数据
+func (s *StatisticJob) Upsert(session *mgo.Session, tp int, userId string, start, end, todayPushCount int64, todayToptype, todaySubtype, todayMatchkeys, todayArea map[string]int, todayCity map[string]map[string]int) {
+	coll := session.DB(Config.Mongodb.DbName).C(Pushspace_statistic)
+	var monthObj map[string]interface{}
+	coll.Find(map[string]interface{}{
+		"type":      tp,
+		"userid":    userId,
+		"startdate": start,
+		"enddate":   end,
+	}).Select(map[string]interface{}{
+		"_id":              1,
+		"pushcount":        1,
+		"matchkeys":        1,
+		"toptype":          1,
+		"subtype_zhaobiao": 1,
+		"area":             1,
+		"city":             1,
+	}).One(&monthObj)
+	if monthObj == nil {
+		err := coll.Insert(map[string]interface{}{
+			"type":             tp,
+			"userid":           userId,
+			"startdate":        start,
+			"enddate":          end,
+			"pushcount":        todayPushCount,
+			"toptype":          todayToptype,
+			"subtype_zhaobiao": todaySubtype,
+			"matchkeys":        todayMatchkeys,
+			"area":             todayArea,
+			"city":             todayCity,
+			"createtime":       time.Now().Unix(),
+			"ispush":           0,
+			"dateym":           s.GetDateym(end),
+		})
+		if err != nil {
+			logger.Error(userId, "新增出错", err)
+		}
+	} else {
+		toptype, _ := monthObj["toptype"].(map[string]interface{})
+		for k, v := range todayToptype {
+			toptype[k] = util.IntAll(toptype[k]) + v
+		}
+		subtype, _ := monthObj["subtype_zhaobiao"].(map[string]interface{})
+		for k, v := range todaySubtype {
+			subtype[k] = util.IntAll(subtype[k]) + v
+		}
+		matchkeys, _ := monthObj["matchkeys"].(map[string]interface{})
+		for k, v := range todayMatchkeys {
+			matchkeys[k] = util.IntAll(matchkeys[k]) + v
+		}
+		area, _ := monthObj["area"].(map[string]interface{})
+		for k, v := range todayArea {
+			area[k] = util.IntAll(area[k]) + v
+		}
+		city, _ := monthObj["city"].(map[string]interface{})
+		for k, v := range todayCity {
+			vm, _ := city[k].(map[string]interface{})
+			if vm == nil {
+				vm = map[string]interface{}{}
+			}
+			for kk, vv := range v {
+				vm[kk] = util.IntAll(vm[kk]) + vv
+			}
+			city[k] = vm
+		}
+		err := coll.UpdateId(monthObj["_id"], map[string]interface{}{
+			"$set": map[string]interface{}{
+				"pushcount":        util.IntAll(monthObj["pushcount"]) + int(todayPushCount),
+				"toptype":          toptype,
+				"subtype_zhaobiao": subtype,
+				"matchkeys":        matchkeys,
+				"area":             area,
+				"city":             city,
+				"updatetime":       time.Now().Unix(),
+			},
+		})
+		if err != nil {
+			logger.Error(userId, "更新出错", err)
+		}
+	}
+}
+
+//如果是中标的,去项目表里面找改信息的招标类型
+func (s *StatisticJob) SearchProject(datas *[]map[string]interface{}) []string {
+	result := []string{}
+	batchIds := []string{}
+	for _, data := range *datas {
+		batchIds = append(batchIds, util.ObjToString(data["infoid"]))
+		if len(batchIds) == batchIdLength {
+			result = append(result, s.projectSubtypes(batchIds)...)
+			batchIds = []string{}
+		}
+	}
+	if len(batchIds) > 0 {
+		result = append(result, s.projectSubtypes(batchIds)...)
+	}
+	return result
+}
+
+func (s *StatisticJob) projectSubtypes(ids []string) []string {
+	result := []string{}
+	query := fmt.Sprintf(ProjectQuery, `"`+strings.Join(ids, `","`)+`"`, batchIdLength)
+	list := elastic.Get(Projectset, Projectset, query)
+	if list == nil {
+		return result
+	}
+	for _, v := range *list {
+		array, _ := v["list"].([]interface{})
+		for _, vv := range array {
+			vvMap, _ := vv.(map[string]interface{})
+			toptype, _ := vvMap["toptype"].(string)
+			subtype, _ := vvMap["subtype"].(string)
+			if subtype == "" {
+				subtype = "其它"
+			}
+			if toptype == "招标" && subtype != "" {
+				result = append(result, subtype)
+				break
+			}
+		}
+	}
+	return result
+}

+ 56 - 0
src/jfw/modules/pushsubscribe/src/report/job/timetask.go

@@ -0,0 +1,56 @@
+package job
+
+import (
+	"log"
+	. "public"
+	"qfw/util"
+	. "report/config"
+	"strings"
+	"time"
+)
+
+type TimeTask struct{}
+
+func (t *TimeTask) Run() {
+	go t.crontab(Config.PushTime, func() {
+		isPushMonth := time.Now().Day() == Config.PushMonth
+		isPushWeek := strings.ToUpper(time.Now().Weekday().String()) == strings.ToUpper(Config.PushWeek)
+		if isPushMonth {
+			now := time.Now().AddDate(0, -1, 0)
+			startDate := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
+			endDate := startDate.AddDate(0, 1, -1)
+			Jobs.Push.Execute(startDate.Unix(), endDate.Unix())
+		} else if isPushWeek {
+			endDate := time.Now().AddDate(0, 0, -WeekNum[time.Now().Weekday().String()])
+			endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 0, 0, 0, 0, time.Local)
+			startDate := endDate.AddDate(0, 0, -6)
+			Jobs.Push.Execute(startDate.Unix(), endDate.Unix())
+		}
+	})
+	go t.crontab(Config.StatisticTime, func() {
+		Jobs.Statistic.Execute(time.Now().AddDate(0, 0, -1))
+	})
+}
+
+func (t *TimeTask) crontab(tm string, f func()) {
+	h_m := strings.Split(tm, ":")
+	if len(h_m) == 2 {
+		now := time.Now()
+		newDate := time.Date(now.Year(), now.Month(), now.Day(), util.IntAll(h_m[0]), util.IntAll(h_m[1]), 0, 0, time.Local)
+		if newDate.Before(now) {
+			newDate = newDate.AddDate(0, 0, 1)
+		}
+		sub := newDate.Sub(now)
+		log.Println("start", tm, "after", sub)
+		timer := time.NewTimer(sub)
+		for {
+			select {
+			case <-timer.C:
+				go f()
+				timer.Reset(time.Hour * 24)
+			}
+		}
+	} else {
+		log.Fatalln("crontab", tm)
+	}
+}

+ 42 - 0
src/jfw/modules/pushsubscribe/src/report/main.go

@@ -0,0 +1,42 @@
+package main
+
+import (
+	"flag"
+	"log"
+	"report/job"
+	"time"
+
+	"github.com/donnie4w/go-logger/logger"
+)
+
+func main() {
+	m := flag.Int("m", 0, "1-统计今天 2-指定时间段统计 3-指定时间段推送")
+	s := flag.Int64("s", 0, "开始时间")
+	e := flag.Int64("e", 0, "结束时间")
+	flag.Parse()
+	if (*m == 2 || *m == 3) && (*s == 0 || *e == 0) {
+		log.Fatalln("缺少-s或者-e参数")
+	}
+	log.Println("订阅报告程序启动。。。")
+	logger.SetConsole(false)
+	logger.SetRollingDaily("./logs", "report.log")
+	if *m == 1 {
+		job.Jobs.Statistic.Execute(time.Now())
+	} else if *m == 2 {
+		start := time.Unix(*s, 0)
+		end := time.Unix(*e, 0)
+		for {
+			if start.After(end) {
+				break
+			}
+			job.Jobs.Statistic.Execute(start)
+			start = start.AddDate(0, 0, 1)
+		}
+	} else if *m == 3 {
+		job.Jobs.Push.Execute(*s, *e)
+	}
+	if *m == 0 {
+		(&job.TimeTask{}).Run()
+		<-chan bool(nil)
+	}
+}

+ 27 - 0
src/jfw/modules/pushsubscribe/src/report/util/db.go

@@ -0,0 +1,27 @@
+package util
+
+import (
+	"log"
+	"qfw/util/elastic"
+	"qfw/util/mongodb"
+	"qfw/util/mysql"
+	. "report/config"
+)
+
+var Mysql *mysql.Mysql
+
+func init() {
+	elastic.InitElasticSize(Config.ElasticSearch, Config.ElasticPoolSize)
+	mongodb.InitMongodbPool(Config.Mongodb.Size, Config.Mongodb.Address, Config.Mongodb.DbName)
+	log.Println("mongodb初始化完成!")
+	Mysql = &mysql.Mysql{
+		DBName:       Config.Mysql.DbName,
+		Address:      Config.Mysql.Address,
+		UserName:     Config.Mysql.UserName,
+		PassWord:     Config.Mysql.PassWord,
+		MaxOpenConns: Config.Mysql.MaxOpenConns,
+		MaxIdleConns: Config.Mysql.MaxIdleConns,
+	}
+	Mysql.Init()
+	log.Println("mysql初始化完成!")
+}

+ 2 - 0
src/jfw/modules/subscribepay/src/a/init.go

@@ -1,6 +1,7 @@
 package initxweb
 
 import (
+	"report"
 	"service"
 	"time"
 
@@ -29,6 +30,7 @@ func init() {
 	xweb.AddRouter("/subscribepay", &service.OrderListDetails{}) //订单详情&列表
 	xweb.AddRouter("/subscribepay", &service.SubscribeChange{})  //续费&升级&订阅修改
 
+	xweb.AddRouter("/subscribepay", &report.Report{}) //订阅报告
 	//p1
 	xweb.AddRouter("/subscribepay", &service.IndexSearch{}) //续费&升级
 

+ 8 - 15
src/jfw/modules/subscribepay/src/config.json

@@ -10,21 +10,6 @@
     "webport": "86",
     "webrpcport": "8600",
     "weixinrpc": "127.0.0.1:8083",
-    "cassandra": {
-        "log": {
-            "host": [
-                "192.168.3.207"
-            ],
-            "size": 5,
-            "port": 9042
-        },
-        "push": {
-            "host": [
-                "192.168.3.207"
-            ],
-            "size": 5
-        }
-    },
     "mysql": {
         "dbName": "jianyu",
         "address": "192.168.3.11:3366",
@@ -40,6 +25,14 @@
         "passWord": "Topnet123",
 		"maxOpenConns":2000,
 		"maxIdleConns":1000
+    },
+	"cassandra": {
+        "push": {
+            "host": [
+                "192.168.3.207"
+            ],
+            "size": 5
+        }
     },
 	"appPushServiceRpc": "127.0.0.1:5566",
     "webdomain": "http://web-jydev-wky.jianyu360.cn",

+ 2 - 6
src/jfw/modules/subscribepay/src/config/config.go

@@ -18,12 +18,8 @@ type config struct {
 	Webport         string
 	Webrpcport      string
 	Weixinrpc       string
-	Cassandra       struct {
-		Host []string
-		Size int
-		Port int
-	}
-	Mysql struct {
+	Cassandra       map[string]interface{}
+	Mysql           struct {
 		DbName       string
 		Address      string
 		UserName     string

+ 406 - 0
src/jfw/modules/subscribepay/src/report/report.go

@@ -0,0 +1,406 @@
+package report
+
+import (
+	"encoding/json"
+	"fmt"
+	qutil "qfw/util"
+	"qfw/util/jy"
+	"sort"
+	"strings"
+	"time"
+	"util"
+
+	"github.com/go-xweb/xweb"
+)
+
+var (
+	subtype_zhaobiao_mapping = map[string]string{
+		"单一": "单一来源",
+		"招标": "公开招标",
+		"竞价": "公开竞价",
+		"竞谈": "竞争性谈判",
+		"询价": "询价采购",
+		"邀标": "邀请招标",
+	}
+	toptype_mapping = map[string]string{
+		"其它": "其他信息",
+		"招标": "招标公告",
+		"结果": "招标结果",
+		"预告": "招标预告",
+		"拟建": "拟建项目",
+	}
+)
+
+//vip订阅报告
+type Report struct {
+	*xweb.Action
+	index     xweb.Mapper `xweb:"/report/index"`
+	detail    xweb.Mapper `xweb:"/report/detail"`
+	tip       xweb.Mapper `xweb:"/report/tip"`
+	tipover   xweb.Mapper `xweb:"/report/tipover"`
+	wxtplmsg  xweb.Mapper `xweb:"/report/wxtplmsg"`
+	starttime xweb.Mapper `xweb:"/report/starttime"`
+}
+
+func (r *Report) Index() {
+	ym, _ := r.GetInteger("ym")
+	result := map[string]interface{}{}
+	userId, _ := r.GetSession("userId").(string)
+	list, ok := util.MQFW.Find("pushspace_statistic", map[string]interface{}{
+		"userid": userId,
+		"dateym": ym,
+		"type": map[string]interface{}{
+			"$in": []int{2, 3},
+		},
+	}, `{"startdate":-1}`, `{"startdate":1,"enddate":1,"type":1,"pushcount":1,"pushtime":1,"unread":1}`, false, -1, -1)
+	if ok && list != nil {
+		weeks := []map[string]interface{}{}
+		for _, v := range *list {
+			r := map[string]interface{}{
+				"pushtime":  v["pushtime"],
+				"pushcount": v["pushcount"],
+				"unread":    qutil.IntAll(v["unread"]),
+				"startdate": v["startdate"],
+				"enddate":   v["enddate"],
+			}
+			if qutil.IntAll(v["type"]) == 2 {
+				weeks = append(weeks, r)
+			} else if qutil.IntAll(v["type"]) == 3 {
+				result["month"] = r
+			}
+		}
+		if len(weeks) > 0 {
+			result["weeks"] = weeks
+		}
+	}
+	if len(result) == 0 {
+		result = nil
+	}
+	r.ServeJson(result)
+}
+func (r *Report) Detail() {
+	start, _ := r.GetInt("start")
+	end, _ := r.GetInt("end")
+	result := map[string]interface{}{}
+	var types []int
+	if end-start == 518400 { //周
+		types = []int{1, 2}
+	} else if end-start > 518400 { //月
+		types = []int{1, 3}
+	} else {
+		r.ServeJson(result)
+		return
+	}
+	userId, _ := r.GetSession("userId").(string)
+	list, ok := util.MQFW.Find("pushspace_statistic", map[string]interface{}{
+		"userid": userId,
+		"startdate": map[string]interface{}{
+			"$gte": start,
+		},
+		"enddate": map[string]interface{}{
+			"$lte": end,
+		},
+		"type": map[string]interface{}{
+			"$in": types,
+		},
+	}, `{"startdate":-1}`, `{"startdate":1,"type":1,"pushcount":1,"matchkeys":1,"subtype_zhaobiao":1,"toptype":1,"area":1,"city":1}`, false, -1, -1)
+	if ok && list != nil {
+		days := []map[string]interface{}{}
+		for _, v := range *list {
+			if qutil.IntAll(v["type"]) == 1 {
+				days = append(days, map[string]interface{}{
+					"pushcount": v["pushcount"],
+					"date":      v["startdate"],
+				})
+			} else {
+				matchkeys, _ := v["matchkeys"].(map[string]interface{})
+				var new_matchkeys ComSorts
+				for kk, vv := range matchkeys {
+					new_matchkeys = append(new_matchkeys, &ComSort{
+						Name:  strings.Split(strings.Split(kk, "+")[0], " ")[0],
+						Count: qutil.IntAll(vv),
+					})
+				}
+				sort.Sort(new_matchkeys)
+				result["matchkeys"] = new_matchkeys
+				subtype_zhaobiao, _ := v["subtype_zhaobiao"].(map[string]interface{})
+				new_subtype_zhaobiao := map[string]int{}
+				for kk, vv := range subtype_zhaobiao_mapping {
+					new_subtype_zhaobiao[vv] = qutil.IntAll(subtype_zhaobiao[kk])
+				}
+				result["subtype_zhaobiao"] = new_subtype_zhaobiao
+				toptype, _ := v["toptype"].(map[string]interface{})
+				new_toptype := map[string]int{}
+				for kk, vv := range toptype_mapping {
+					new_toptype[vv] = qutil.IntAll(toptype[kk])
+				}
+				result["toptype"] = new_toptype
+				area, _ := v["area"].(map[string]interface{})
+				result["area"] = area
+				city, _ := v["city"].(map[string]interface{})
+				result["city"] = formatCity(area, city)
+			}
+		}
+		result["days"] = formatDays(start, end, days)
+	}
+	//
+	subscribe := map[string]interface{}{}
+	subscribe["keys"] = []string{}
+	subscribe["area"] = map[string][]string{}
+	subscribe["industry"] = []string{}
+	result["subscribe"] = subscribe
+	userdata, ok := util.MQFW.FindById("user", userId, `{"s_m_openid":1,"a_m_openid":1,"s_phone":1,"a_mergeorder":1}`)
+	if ok {
+		dateSection := getDateSection(start, end)
+		s_m_openid, _ := (*userdata)["s_m_openid"].(string)
+		a_m_openid, _ := (*userdata)["a_m_openid"].(string)
+		s_phone, _ := (*userdata)["s_phone"].(string)
+		a_mergeorder, _ := (*userdata)["a_mergeorder"].([]interface{})
+		openid := jy.GetOldOpenid(s_m_openid, a_m_openid, s_phone, a_mergeorder)
+		//关注项目
+		follow_project := util.Ca_Push.Search(fmt.Sprintf("select pcode,pname,info from jy_pushproject where id in (%s) and openid='%s' limit 100", dateSection, openid))
+		if follow_project != nil {
+			indexMap := map[string]int{}
+			projects := []map[string]interface{}{}
+			for _, v := range follow_project {
+				projectname := qutil.ObjToString(v["pname"])
+				if projectname == "" {
+					projectname = qutil.ObjToString(v["pcode"])
+				}
+				index, ok := indexMap[projectname]
+				//合并
+				if ok {
+					infos, _ := projects[index]["infos"].([]map[string]interface{})
+					infos = append(infos, formatInfo(qutil.ObjToString(v["info"]))...)
+					projects[index]["infos"] = infos
+				} else {
+					projects = append(projects, map[string]interface{}{
+						"projectname": projectname,
+						"infos":       formatInfo(qutil.ObjToString(v["info"])),
+					})
+					indexMap[projectname] = len(projects) - 1
+				}
+			}
+			result["projects"] = projects
+		}
+		//关注企业
+		follow_ent := util.Ca_Push.Search(fmt.Sprintf("select entname,info from jy_pushent where id in (%s) and openid='%s' limit 100", dateSection, openid))
+		if follow_ent != nil {
+			indexMap := map[string]int{}
+			ents := []map[string]interface{}{}
+			for _, v := range follow_ent {
+				entname := qutil.ObjToString(v["entname"])
+				index, ok := indexMap[entname]
+				//合并
+				if ok {
+					infos, _ := ents[index]["infos"].([]map[string]interface{})
+					infos = append(infos, formatInfo(qutil.ObjToString(v["info"]))...)
+					ents[index]["infos"] = infos
+				} else {
+					ents = append(ents, map[string]interface{}{
+						"entname": entname,
+						"infos":   formatInfo(qutil.ObjToString(v["info"])),
+					})
+					indexMap[entname] = len(ents) - 1
+				}
+			}
+			result["ents"] = ents
+		}
+	}
+	go util.MQFW.Update("pushspace_statistic", map[string]interface{}{
+		"userid":    userId,
+		"startdate": start,
+		"enddate":   end,
+	}, map[string]interface{}{
+		"$set": map[string]interface{}{
+			"unread": 0,
+		},
+	}, false, true)
+	r.ServeJson(result)
+}
+func formatDays(start, end int64, days []map[string]interface{}) []map[string]interface{} {
+	if len(days) == 0 {
+		return days
+	}
+	date := qutil.Int64All(days[len(days)-1]["date"])
+	for {
+		if start < date && date < end {
+			date -= 86400
+			days = append(days, map[string]interface{}{
+				"pushcount": 0,
+				"date":      date,
+			})
+		} else {
+			break
+		}
+	}
+	return days
+}
+
+type AreaCitySort struct {
+	Area  string   `json:"area"`
+	Count int      `json:"count"`
+	Citys ComSorts `json:"citys"`
+}
+
+type AreaCitySorts []*AreaCitySort
+
+func (s AreaCitySorts) Len() int {
+	return len(s)
+}
+
+func (s AreaCitySorts) Less(i, j int) bool {
+	return s[i].Count > s[j].Count
+}
+
+func (s AreaCitySorts) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+
+//
+type ComSort struct {
+	Name  string `json:"name"`
+	Count int    `json:"count"`
+}
+
+type ComSorts []*ComSort
+
+func (s ComSorts) Len() int {
+	return len(s)
+}
+
+func (s ComSorts) Less(i, j int) bool {
+	return s[i].Count > s[j].Count
+}
+
+func (s ComSorts) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+
+func formatCity(area, city map[string]interface{}) AreaCitySorts {
+	areaCitys := AreaCitySorts{}
+	for k, v := range city {
+		countCity := 0
+		citys := ComSorts{}
+		vMap, _ := v.(map[string]interface{})
+		for kk, vv := range vMap {
+			countCity += qutil.IntAll(vv)
+			citys = append(citys, &ComSort{
+				Name:  kk,
+				Count: qutil.IntAll(vv),
+			})
+		}
+		sort.Sort(citys)
+		countArea := qutil.IntAll(area[k])
+		if countArea == 0 {
+			countArea = countCity
+		}
+		areaCitys = append(areaCitys, &AreaCitySort{
+			Area:  k,
+			Count: countArea,
+			Citys: citys,
+		})
+	}
+	sort.Sort(areaCitys)
+	return areaCitys
+}
+
+//
+func formatInfo(text string) []map[string]interface{} {
+	var relationinfo []map[string]interface{}
+	json.Unmarshal([]byte(text), &relationinfo)
+	infos := []map[string]interface{}{}
+	for _, v := range relationinfo {
+		infotype, _ := v["s_subtype"].(string)
+		if infotype == "" {
+			infotype, _ = v["s_toptype"].(string)
+		}
+		if infotype == "" {
+			infotype, _ = v["s_type"].(string)
+			if infotype == "tender" {
+				infotype = "招标"
+			} else if infotype == "bid" {
+				infotype = "中标"
+			}
+		}
+		infos = append(infos, map[string]interface{}{
+			"title":       v["s_title"],
+			"id":          qutil.EncodeArticleId2ByCheck(qutil.ObjToString(v["s_id"])),
+			"publishtime": qutil.Int64All(v["l_publishtime"]),
+			"area":        v["s_province"],
+			"infotype":    infotype,
+		})
+	}
+	return infos
+}
+
+func getDateSection(start, end int64) string {
+	array := []string{}
+	s := time.Unix(start, 0)
+	e := time.Unix(end, 0)
+	for {
+		if s.After(e) {
+			break
+		}
+		array = append(array, qutil.FormatDate(&s, qutil.Date_Short_Layout))
+		s = s.AddDate(0, 0, 1)
+	}
+	return `'` + strings.Join(array, `','`) + `'`
+}
+func (r *Report) Tip() {
+	userId, _ := r.GetSession("userId").(string)
+	unread := util.MQFW.Count("pushspace_statistic", map[string]interface{}{
+		"userid": userId,
+		"unread": 1,
+	})
+	list, ok := util.MQFW.Find("pushspace_statistic", map[string]interface{}{
+		"userid": userId,
+		"tip":    1,
+	}, `{"enddate":-1}`, `{"_id":0,"type":1,"startdate":1,"enddate":1,"pushcount":1}`, false, 0, 1)
+	result := map[string]interface{}{
+		"unread": unread,
+	}
+	if ok && list != nil && len(*list) == 1 {
+		result["tip"] = (*list)[0]
+	}
+	r.ServeJson(result)
+}
+func (r *Report) Tipover() {
+	userId, _ := r.GetSession("userId").(string)
+	r.ServeJson(map[string]interface{}{"flag": tipover(userId)})
+}
+
+func tipover(userId string) bool {
+	return util.MQFW.Update("pushspace_statistic", map[string]interface{}{
+		"userid": userId,
+		"tip":    1,
+	}, map[string]interface{}{
+		"$set": map[string]interface{}{
+			"tip": 0,
+		},
+	}, false, true)
+}
+func (r *Report) Wxtplmsg() error {
+	userId, _ := r.GetSession("userId").(string)
+	pushcount, _ := r.GetInteger("pushcount")
+	go tipover(userId)
+	return r.Redirect(fmt.Sprintf("/vipreport/page/reportdetail.html?start=%s&end=%s&pushcount=%d", r.GetString("start"), r.GetString("end"), pushcount))
+}
+
+func (r *Report) Starttime() {
+	userId, _ := r.GetSession("userId").(string)
+	list, _ := util.MQFW.Find("pushspace_statistic", map[string]interface{}{
+		"userid": userId,
+		"type": map[string]interface{}{
+			"$in": []int{2, 3},
+		},
+	}, `{"enddate":1}`, `{"enddate":1,"dateym":1}`, false, 0, 1)
+	start := 0
+	if list != nil && len(*list) == 1 {
+		enddate := qutil.Int64All((*list)[0]["enddate"])
+		if time.Now().After(time.Unix(enddate, 0).AddDate(0, 0, 1)) {
+			start = qutil.IntAll((*list)[0]["dateym"])
+		}
+	}
+	r.ServeJson(start)
+}

+ 9 - 7
src/jfw/modules/subscribepay/src/util/db.go

@@ -2,7 +2,6 @@ package util
 
 import (
 	. "config"
-
 	qutil "qfw/util"
 	"qfw/util/elastic"
 	mg "qfw/util/mongodb"
@@ -14,15 +13,18 @@ import (
 var MQFW mg.MongodbSim
 var Mysql *mysql.Mysql
 var PushMysql *mysql.Mysql
-var Ca_Log = &ca.Cassandra{}
+var Ca_Push = &ca.Cassandra{}
 
 func init() {
 	//初始化cassandra
-	Ca_Log.ViewCacheLen = true
-	Ca_Log.InitCassandra("jianyu",
-		Config.Cassandra.Size,
-		Config.Cassandra.Host,
-		map[string]int{"port": Config.Cassandra.Port},
+	ca_push := Config.Cassandra["push"].(map[string]interface{})
+	Ca_Push.ViewCacheLen = true
+	Ca_Push.InitCassandra("jianyu",
+		qutil.IntAll(ca_push["size"]),
+		qutil.ObjArrToStringArr(ca_push["host"].([]interface{})),
+		map[string]int{
+			"port": qutil.IntAll(ca_push["port"]),
+		},
 	)
 	//初始化elastic
 	elastic.InitElasticSize(

+ 40 - 30
src/jfw/public/public.go

@@ -192,37 +192,47 @@ func DelRelRedis(userid interface{}, relationinfo interface{}) {
 //sortFiled 排序字段
 //Mergefiled 判重字段
 func MapArrSortMerge(arr1, arr2 []map[string]interface{}, mergeFiled, sortFiled string) *[]map[string]interface{} {
-	var tmp []map[string]interface{}
-	i, j := 0, 0
-	var idMap = map[string]bool{}
-	MaxLenArr1, MaxLenArr2 := len(arr1), len(arr2)
-	for i < MaxLenArr1 || j < MaxLenArr2 {
-		var mergeTmp interface{}
-		var sign map[string]interface{}
-
-		if len(tmp) > 0 {
-			mergeTmp = tmp[len(tmp)-1][mergeFiled]
-		}
-
-		if i <= MaxLenArr1-1 {
-			sign = arr1[i]
-		}
-		if j <= MaxLenArr2-1 {
-			if util.Int64All(sign[sortFiled]) > util.Int64All(arr2[j][sortFiled]) {
-				i++
-			} else {
-				sign = arr2[j]
-				j++
-			}
-		} else {
-			i++
-		}
-		if mergeTmp != sign[mergeFiled] {
-			if !idMap[util.ObjToString(sign[mergeFiled])] {
-				idMap[util.ObjToString(sign[mergeFiled])] = true
-				tmp = append(tmp, sign)
+	for _, v := range arr1 {
+		for n, m := range arr2 {
+			if util.ObjToString(v["_id"]) == util.ObjToString(m["_id"]) {
+				arr2 = append((arr2)[0:n], (arr2)[n+1:]...)
+				break
 			}
 		}
 	}
-	return &tmp
+	arr1 = append(arr1, arr2...)
+	return &arr1
+	// var tmp []map[string]interface{}
+	// i, j := 0, 0
+	// var idMap = map[string]bool{}
+	// MaxLenArr1, MaxLenArr2 := len(arr1), len(arr2)
+	// for i < MaxLenArr1 || j < MaxLenArr2 {
+	// 	var mergeTmp interface{}
+	// 	var sign map[string]interface{}
+
+	// 	if len(tmp) > 0 {
+	// 		mergeTmp = tmp[len(tmp)-1][mergeFiled]
+	// 	}
+
+	// 	if i <= MaxLenArr1-1 {
+	// 		sign = arr1[i]
+	// 	}
+	// 	if j <= MaxLenArr2-1 {
+	// 		if util.Int64All(sign[sortFiled]) > util.Int64All(arr2[j][sortFiled]) {
+	// 			i++
+	// 		} else {
+	// 			sign = arr2[j]
+	// 			j++
+	// 		}
+	// 	} else {
+	// 		i++
+	// 	}
+	// 	if mergeTmp != sign[mergeFiled] {
+	// 		if !idMap[util.ObjToString(sign[mergeFiled])] {
+	// 			idMap[util.ObjToString(sign[mergeFiled])] = true
+	// 			tmp = append(tmp, sign)
+	// 		}
+	// 	}
+	// }
+	// return &tmp
 }

+ 9 - 3
src/jfw/qrmanager/qrmanager.go

@@ -42,23 +42,29 @@ func RedisInfo(oid, action, sione, sitwo string, i int, hsn *httpsession.Session
 	for k, v := range modulelist {
 		if strings.Contains(Rurl, k) {
 			hsn.Set("RModule", v)
+			break
 		}
 	}
 	if hsn.Get("RModule") == nil || util.ObjToString(hsn.Get("RModule")) == "" {
 		hsn.Set("RModule", "首页")
 	}
 	//活动页模块
-	if len(Rurl) > 1 && strings.Contains(Rurl, "id=") {
+	//需要建立剑鱼唯一的id后缀
+	if len(Rurl) > 1 && strings.Contains(Rurl, "?id=") {
 		activeCode := strings.Split(Rurl, "id=")[1]
+		if strings.Contains(activeCode, "&") { //例:?id=x&a=x&b=x 只获取id的值
+			activeCode = strings.Split(activeCode, "&")[0]
+		}
 		//首先查看是否从百度等搜索引擎过来的referer
 		sourcelist := Seoconfig["source"].(map[string]interface{})
 		for k, v := range sourcelist {
-			if strings.Contains(activeCode, k) {
+			if k == activeCode {
 				if hsn.Get("RSource") == nil {
 					hsn.Set("RSource", v)
 					hsn.Set("RModule", activeCode+"活动页")
 					hsn.Set("RActiveCode", activeCode)
 				}
+				break
 			}
 		}
 		if hsn.Get("RSource") == nil {
@@ -87,6 +93,7 @@ func RedisInfo(oid, action, sione, sitwo string, i int, hsn *httpsession.Session
 				if hsn.Get("RSource") == nil {
 					hsn.Set("RSource", util.ObjToString(v)+open)
 				}
+				break
 			}
 		}
 		if hsn.Get("RSource") == nil || util.ObjToString(hsn.Get("RSource")) == "" {
@@ -100,7 +107,6 @@ func RedisInfo(oid, action, sione, sitwo string, i int, hsn *httpsession.Session
 	userData["Rparaminfotype"] = hsn.Get("paraminfotype")
 	userData["Rprojectname"] = hsn.Get("projectname")
 	userData["action"] = action
-	//log.Println("userData:", userData)
 	if oldData != nil {
 		redis.Put("sso", "p_shareData_"+sione, oldData, i*60)
 		redis.Put("sso", "p_shareData_"+sitwo, oldData, i*60)

+ 467 - 401
src/seo.json

@@ -1,413 +1,479 @@
-{	
-	"cdn":"",
+{
+    "cdn": "",
     "qfw": {
         "swordfish": {
             "description": "剑鱼标讯为用户提供个性化定制的全行业招标信息订阅推送服务,用户只需微信关注剑鱼标讯并合理设定招标关键词,无需下载APP,即可实现海量招标信息智能推送。",
             "key": "剑鱼标讯,招标订阅,招标推送,招标信息,招标公告,中标公告",
             "title": "剑鱼标讯,全行业招标信息智能推送领导者!"
         },
-		"swordfishsl": {
+        "swordfishsl": {
             "description": "剑鱼标讯搜索功能依据用户输入的招标关键词,快速展现最新最全的行业招标信息搜索结果,招标公告与中标公告,一应俱全。",
             "key": "招标搜索结果,招标搜索,剑鱼标讯",
             "title": "_剑鱼标讯,全行业招标信息智能推送领导者!"
         }
     },
-	"version":"1412",
-	"area":{
-		"QG":{
-				"NAME":"全国",
-				"TITLE":"全国",
-				"KEYWORDS":"全国",
-				"DESCRIPTION":"全国"
-			},
-		"AH":{	"NAME":"安徽",
-				"TITLE":"安徽",
-				"KEYWORDS":"安徽",
-				"DESCRIPTION":"安徽"
-			},
-		"AM":{	"NAME":"澳门",
-				"TITLE":"澳门",
-				"KEYWORDS":"澳门",
-				"DESCRIPTION":"澳门"
-			},
-		"BJ":{	"NAME":"北京",
-				"TITLE":"北京",
-				"KEYWORDS":"北京",
-				"DESCRIPTION":"北京"
-			},
-		"CQ":{	"NAME":"重庆",
-				"TITLE":"重庆",
-				"KEYWORDS":"重庆",
-				"DESCRIPTION":"重庆"
-			},
-		"FJ":{	"NAME":"福建",
-				"TITLE":"福建",
-				"KEYWORDS":"福建",
-				"DESCRIPTION":"福建"
-			},
-		"GD":{	"NAME":"广东",
-				"TITLE":"广东",
-				"KEYWORDS":"广东",
-				"DESCRIPTION":"广东"
-			},
-		"GX":{	"NAME":"广西",
-				"TITLE":"广西",
-				"KEYWORDS":"广西",
-				"DESCRIPTION":"广西"
-			},
-		"GZ":{	"NAME":"贵州",
-				"TITLE":"贵州",
-				"KEYWORDS":"贵州",
-				"DESCRIPTION":"贵州"
-			},
-		"GS":{	"NAME":"甘肃",
-				"TITLE":"甘肃",
-				"KEYWORDS":"甘肃",
-				"DESCRIPTION":"甘肃"
-			},
-		"HB":{	"NAME":"河北",
-				"TITLE":"河北",
-				"KEYWORDS":"河北",
-				"DESCRIPTION":"河北"
-			},
-		"HBC":{	"NAME":"湖北",
-				"TITLE":"湖北",
-				"KEYWORDS":"湖北",
-				"DESCRIPTION":"湖北"
-			},
-		"HLJ":{	"NAME":"黑龙江",
-				"TITLE":"黑龙江",
-				"KEYWORDS":"黑龙江",
-				"DESCRIPTION":"黑龙江"
-			},
-		"HN":{	"NAME":"海南",
-				"TITLE":"海南",
-				"KEYWORDS":"海南",
-				"DESCRIPTION":"海南"
-			},
-		"HNC":{	"NAME":"河南",
-				"TITLE":"河南",
-				"KEYWORDS":"河南",
-				"DESCRIPTION":"河南"
-			},
-		"HNS":{	"NAME":"湖南",
-				"TITLE":"湖南",
-				"KEYWORDS":"湖南",
-				"DESCRIPTION":"湖南"
-			},
-		"JL":{	"NAME":"吉林",
-				"TITLE":"吉林",
-				"KEYWORDS":"吉林",
-				"DESCRIPTION":"吉林"
-			},
-		"JS":{	"NAME":"江苏",
-				"TITLE":"江苏",
-				"KEYWORDS":"江苏",
-				"DESCRIPTION":"江苏"
-			},
-		"JX":{	"NAME":"江西",
-				"TITLE":"江西",
-				"KEYWORDS":"江西",
-				"DESCRIPTION":"江西"
-			},
-		"LN":{	"NAME":"辽宁",
-				"TITLE":"辽宁",
-				"KEYWORDS":"辽宁",
-				"DESCRIPTION":"辽宁"
-			},
-		"NMG":{	"NAME":"内蒙古",
-				"TITLE":"内蒙古",
-				"KEYWORDS":"内蒙古",
-				"DESCRIPTION":"内蒙古"
-			},
-		"NX":{	"NAME":"宁夏",
-				"TITLE":"宁夏",
-				"KEYWORDS":"宁夏",
-				"DESCRIPTION":"宁夏"
-			},
-		"QH":{	"NAME":"青海",
-				"TITLE":"青海",
-				"KEYWORDS":"青海",
-				"DESCRIPTION":"青海"
-			},
-		"SX":{	"NAME":"山西",
-				"TITLE":"山西",
-				"KEYWORDS":"山西",
-				"DESCRIPTION":"山西"
-			},
-		"SXC":{	"NAME":"陕西",
-				"TITLE":"陕西",
-				"KEYWORDS":"陕西",
-				"DESCRIPTION":"陕西"
-			},
-		"SH":{	"NAME":"上海",
-				"TITLE":"上海",
-				"KEYWORDS":"上海",
-				"DESCRIPTION":"上海"
-			},
-		"SD":{	"NAME":"山东",
-				"TITLE":"山东",
-				"KEYWORDS":"山东",
-				"DESCRIPTION":"山东"
-			},
-		"SC":{	"NAME":"四川",
-				"TITLE":"四川",
-				"KEYWORDS":"四川",
-				"DESCRIPTION":"四川"
-			},
-		"TJ":{	"NAME":"天津",
-				"TITLE":"天津",
-				"KEYWORDS":"天津",
-				"DESCRIPTION":"天津"
-			},
-		"XJ":{	"NAME":"新疆",
-				"TITLE":"新疆",
-				"KEYWORDS":"新疆",
-				"DESCRIPTION":"新疆"
-			},
-		"TW":{	"NAME":"台湾",
-				"TITLE":"台湾",
-				"KEYWORDS":"台湾",
-				"DESCRIPTION":"台湾"
-			},
-		"XZ":{	"NAME":"西藏",
-				"TITLE":"西藏",
-				"KEYWORDS":"西藏",
-				"DESCRIPTION":"西藏"
-			},
-		"XG":{	"NAME":"香港",
-				"TITLE":"香港",
-				"KEYWORDS":"香港",
-				"DESCRIPTION":"香港"
-			},
-		"YN":{	"NAME":"云南",
-				"TITLE":"安徽标题",
-				"KEYWORDS":"安徽关键词",
-				"DESCRIPTION":"安徽描述"
-			},
-		"ZJ":{	"NAME":"浙江",
-				"TITLE":"浙江",
-				"KEYWORDS":"浙江",
-				"DESCRIPTION":"浙江"
-			}
-	},
-	"stype":{
-		"NJ":{	"NAME":"拟建",
-				"TITLE":"拟建项目_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"拟建项目,拟在建项目,拟建项目网,拟建项目信息",
-				"DESCRIPTION":"剑鱼标讯拟建项目专栏,包含国家发改委和各部委提供的尚处于前期立项、审批阶段的招投标项目,各供应商应在立项阶段就开始掌握最新的项目信息,做到早介入,早准备,稳拿单。"
-			},
-		"YG":{	"NAME":"预告",
-				"TITLE":"招标预告_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"招标预告,招标预告信息,招标预公告",
-				"DESCRIPTION":"剑鱼标讯招标预告栏目,每天发布国内最新的招标预告信息,提供各行业招标预告信息的搜索查询服务,不仅及时准确,而且更加专业。"
-			},
-		"ZB":{	"NAME":"招标",
-				"TITLE":"公开招标_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"公开招标,公开招标信息,公开招标公告,公开招标网",
-				"DESCRIPTION":"剑鱼标讯公开招标栏目,提供国内各行业最新最全的公开招标信息,出色的搜索查询服务,可以让用户更加快速高效的获取想要的信息。"
-			},
-		"YB":{	"NAME":"邀标",
-				"TITLE":"邀请招标_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"邀请招标,邀请招标信息,邀请招标公告",
-				"DESCRIPTION":"剑鱼标讯邀请招标栏目,及时准确的提供国内各行业最新的邀请招标信息,出色的搜索查询服务,可以让用户更加高效的获取想要的信息。"
-			},
-		"XJ":{	"NAME":"询价",
-				"TITLE":"询价采购_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"询价采购,询价采购信息,询价采购公告",
-				"DESCRIPTION":"获取全国各行业最新的询价采购信息,就来剑鱼标讯询价采购专栏,数据多而全,搜索查询更全面,专业性更高。"
-			},
-		"JT":{	"NAME":"竞谈",
-				"TITLE":"竞争性谈判_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"竞争性谈判,竞争性谈判采购,竞争性谈判信息,竞争性谈判公告",
-				"DESCRIPTION":"剑鱼标讯竞争性谈判栏目,专业为广大用户提供国内各省、各行业最新的竞争性谈判采购信息和查询服务。招标数据每天保持更新,及时而且准确。"
-			},
-		"DY":{	"NAME":"单一",
-				"TITLE":"单一来源_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"单一来源,单一来源采购,单一来源信息,单一来源采购公告",
-				"DESCRIPTION":"剑鱼标讯单一来源栏目,包含国内各省、各行业最新的单一来源采购公告,使用招标搜索功能,可以帮助用户更快速的获取这些信息。"
-			},
-		"JJ":{	"NAME":"竞价",
-				"TITLE":"公开竞价_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"公开竞价,网上竞价,公开竞价信息,公开竞价采购",
-				"DESCRIPTION":"剑鱼标讯公开竞价专栏,提供全国各省和更行业最新的公开竞价信息,你想看的这里都有,使用公开竞价的搜索查询服务更省心。"
-			},
-		"BG":{	"NAME":"变更",
-				"TITLE":"变更公告_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"变更公告,更正公告,变更公告信息,招标变更公告",
-				"DESCRIPTION":"变更公告是招标公告发布后,针对该公告的的地址、时间、招标内容等信息的变更通知。及时查询和获取全国最新的变更公告,就在剑鱼标讯变更公告专栏。"
-			},
-		"ZHB":{	"NAME":"中标",
-				"TITLE":"中标公示_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"中标公示,中标公示信息,中标公告结果,中标公示网",
-				"DESCRIPTION":"剑鱼标讯中标公示栏目,涵盖全国各省各行业最新的中标公示信息,可以帮助用户轻松查询到想看的中标信息,好用又省心。"
-			},
-		"CJ":{	"NAME":"成交",
-				"TITLE":"成交公告_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"成交公告,成交公告信息,成交结果,成交结果公告",
-				"DESCRIPTION":"剑鱼标讯成交公告栏目,提供专业的成交公告查询,成交结果查看等功能,全国各省和各个行业的成交公告信息都可以查看和查询。"
-			},
-		"FB":{	"NAME":"废标",
-				"TITLE":"废标公告_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"废标公告,废标公告信息,终止公告",
-				"DESCRIPTION":"剑鱼标讯废标公告栏目,提供全国各省,各行业最新的废标公告信息,出色的废标公告查询功能,支持多条件筛选,使用更简单。"
-			},
-		"LB":{	"NAME":"流标",
-				"TITLE":"流标公告_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"流标公告,流标公示,招标失败公告,采购失败公告",
-				"DESCRIPTION":"剑鱼标讯流标公告栏目,帮助用户准确获取和查询最新的流标公告信息,提前掌握招投标的进展情况,工作更轻松。"
-			},
-		"HT":{	"NAME":"合同",
-				"TITLE":"合同公告_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"合同公告,合同公告信息,采购合同公告",
-				"DESCRIPTION":"剑鱼标讯合同公告专栏,包含当前国内各省和各行业最全面的合同公告信息,使用合同公告搜索查询功能,获取信息更快更准确。"
-			},
-		"YS":{	"NAME":"验收",
-				"TITLE":"验收公告_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"验收公告,验收公告信息,验收项目",
-				"DESCRIPTION":"剑鱼标讯验收公告专栏,涵盖当前国内各省和各行业最全面的验收公告信息,使用验收公告搜索查询功能,获取信息更快更准确。"
-			},
-		"WG":{	"NAME":"违规",
-				"TITLE":"违规处理_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"违规处理,违规处理信息,违规招投标",
-				"DESCRIPTION":"剑鱼标讯违规处理栏目,每天汇总全国招投标行业最新的违规处理信息,搜索查询功能可以让用户更全面的了解招投标违规信息。"
-			},
-		"QT":{	"NAME":"其它",
-				"TITLE":"其他招标信息_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"结果公告,土地拍卖,国有产权拍卖,矿权拍卖",
-				"DESCRIPTION":"剑鱼标讯其他信息专栏为您提供招投标项目的结果公告,土地拍卖信息、国有产权拍卖信息和矿权拍卖信息等内容,让你更详细、更全面的了解所有招投标信息。"
-			}
-	},
-	"industry":{
-		"JZGC":{"NAME":"建筑工程_勘察设计,建筑工程_工程施工,建筑工程_监理咨询,建筑工程_材料设备,建筑工程_机电安装",
-				"TITLE":"建筑工程_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"SLSD":{"NAME":"水利水电_水利工程,水利水电_发电工程,水利水电_航运工程,水利水电_其他工程",
-				"TITLE":"水利水电_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"NYHG":{	"NAME":"能源化工_原材料,能源化工_仪器仪表,能源化工_新能源,能源化工_设备物资,能源化工_化工产品,能源化工_设备",
-				"TITLE":"能源化工_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"RDAF":{"NAME":"弱电安防_综合布线,弱电安防_智能系统,弱电安防_智能家居",
-				"TITLE":"弱电安防_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"XXJS":{"NAME":"信息技术_系统集成及安全,信息技术_软件开发,信息技术_运维服务,信息技术_其他",
-				"TITLE":"信息技术_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"XZBG":{"NAME":"行政办公_办公家具,行政办公_通用办公设备,行政办公_专业设备,行政办公_办公用品,行政办公_生活用品",
-				"TITLE":"行政办公_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"JXSB":{"NAME":"机械设备_矿山机械,机械设备_工程机械,机械设备_机械零部件,机械设备_机床相关,机械设备_车辆,机械设备_其他机械设备",
-				"TITLE":"机械设备_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"JTGC":{"NAME":"交通工程_道路,交通工程_轨道,交通工程_桥梁,交通工程_隧道,交通工程_其他",
-				"TITLE":"交通工程_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"YLWS":{"NAME":"医疗卫生_设备,医疗卫生_耗材,医疗卫生_药品",
-				"TITLE":"医疗卫生_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"SZSS":{"NAME":"市政设施_道路,市政设施_绿化,市政设施_线路管网,市政设施_综合项目",
-				"TITLE":"市政设施_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"FWCG":{"NAME":"服务采购_法律咨询,服务采购_会计,服务采购_物业,服务采购_审计,服务采购_安保,服务采购_仓储物流,服务采购_广告宣传印刷,服务采购_其他",
-				"TITLE":"服务采购_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			},
-		"NLMY":{"NAME":"农林牧渔_生产物资,农林牧渔_生产设备,农林牧渔_相关服务",
-				"TITLE":"农林牧渔_剑鱼标讯,全行业招标信息智能推送领导者!",
-				"KEYWORDS":"",
-				"DESCRIPTION":""
-			}
-	},
-	"jyadd":"http://127.0.0.1",
-	"limitcount":20,
-	"ZBADDRESS":"",
-	"jysy":"10",
-	"jydyy":"11",
-	"jysslby":"12",
-	"jysskzy":"13",
-	"jybqy":"14",
-	"jybky":"15",
-	"jygywmy":"16",
-	"jySEMtgy":"17",
-	"jyzbqyss":"18",
-	"jynjxmy":"19",
-	"jyswhzy":"20",
-	"jyggfwy":"21",
-	"jyldy":"22",
-	"dataexport":"23",
-	"module":{
-		"subscribe":"订阅页",
-		"/list/":"标签页",
-		"supsearch/index":"搜索页",
-		"article/content":"快照页",
-		"jyblog":"博客页",
-		"aboutus":"关于我们页",
-		"bidsearchforent":"中标企业搜索页",
-		"proposedProject":"拟建项目页",
-		"busicooperation":"商务合作页",
-		"advservices":"广告服务页"
-	},
-	"referer":{
-		"baidu.com":"百度SEO",
-		"so.com":"360SEO",
-		"sogou.com":"搜狗SEO",
-		"bing.com":"必应SEO",
-		"google":"谷歌SEO",
-		"open":"open"
-	},
-	"jianyuurl":{
-		"zhaobiao.info":"网站扫码",
-		"jianyu360.com":"网站扫码",
-		"jianyu360.cn":"网站扫码"
-	},
-	"source":{
-		"baiduSEM":"百度SEM",
-		"360SEM":"360SEM",
-		"sogouSEM":"搜狗SEM",
-		"QQqun":"QQ群广告",
-		"BDwangmeng":"百度网盟",
-		"PCwailian":"PC端外链",
-		"email":"邮箱广告",
-		"JRTT":"今日头条PC端",
-		"tengxun":"腾讯网PC端广告",
-		"fenghuang":"凤凰网PC端广告",
-		"xinan":"信安CA证书精灵",
-		"xinlang":"新浪网广告",
-		"zhishiyingxiao":"百度知识营销",
-		"landpage":"新落地页",
-		"peixunwang":"招投标培训网"
-	},
-	"advList":{
-		"专属味道":"oIMvJvjdp91QL-T7kVweryz58L9I"
-	},
-	"url":{
-		"portrait_winner": "http://192.168.20.35:8080/supsearch/winner",
-		"portrait_buyer": "http://192.168.20.35:8080/supsearch/buyer"
-	},
-	"pcHelper":{
-		"downloadUrl_win":"http://w2blmjy.qmx.top/res/JianYu for Windows.exe",
-		"downloadUrl_mac":"http://w2blmjy.qmx.top/res/JianYu for Mac.dmg"
-	}
+    "version": "1412",
+    "area": {
+        "QG": {
+            "NAME": "全国",
+            "TITLE": "全国",
+            "KEYWORDS": "全国",
+            "DESCRIPTION": "全国"
+        },
+        "AH": {
+            "NAME": "安徽",
+            "TITLE": "安徽",
+            "KEYWORDS": "安徽",
+            "DESCRIPTION": "安徽"
+        },
+        "AM": {
+            "NAME": "澳门",
+            "TITLE": "澳门",
+            "KEYWORDS": "澳门",
+            "DESCRIPTION": "澳门"
+        },
+        "BJ": {
+            "NAME": "北京",
+            "TITLE": "北京",
+            "KEYWORDS": "北京",
+            "DESCRIPTION": "北京"
+        },
+        "CQ": {
+            "NAME": "重庆",
+            "TITLE": "重庆",
+            "KEYWORDS": "重庆",
+            "DESCRIPTION": "重庆"
+        },
+        "FJ": {
+            "NAME": "福建",
+            "TITLE": "福建",
+            "KEYWORDS": "福建",
+            "DESCRIPTION": "福建"
+        },
+        "GD": {
+            "NAME": "广东",
+            "TITLE": "广东",
+            "KEYWORDS": "广东",
+            "DESCRIPTION": "广东"
+        },
+        "GX": {
+            "NAME": "广西",
+            "TITLE": "广西",
+            "KEYWORDS": "广西",
+            "DESCRIPTION": "广西"
+        },
+        "GZ": {
+            "NAME": "贵州",
+            "TITLE": "贵州",
+            "KEYWORDS": "贵州",
+            "DESCRIPTION": "贵州"
+        },
+        "GS": {
+            "NAME": "甘肃",
+            "TITLE": "甘肃",
+            "KEYWORDS": "甘肃",
+            "DESCRIPTION": "甘肃"
+        },
+        "HB": {
+            "NAME": "河北",
+            "TITLE": "河北",
+            "KEYWORDS": "河北",
+            "DESCRIPTION": "河北"
+        },
+        "HBC": {
+            "NAME": "湖北",
+            "TITLE": "湖北",
+            "KEYWORDS": "湖北",
+            "DESCRIPTION": "湖北"
+        },
+        "HLJ": {
+            "NAME": "黑龙江",
+            "TITLE": "黑龙江",
+            "KEYWORDS": "黑龙江",
+            "DESCRIPTION": "黑龙江"
+        },
+        "HN": {
+            "NAME": "海南",
+            "TITLE": "海南",
+            "KEYWORDS": "海南",
+            "DESCRIPTION": "海南"
+        },
+        "HNC": {
+            "NAME": "河南",
+            "TITLE": "河南",
+            "KEYWORDS": "河南",
+            "DESCRIPTION": "河南"
+        },
+        "HNS": {
+            "NAME": "湖南",
+            "TITLE": "湖南",
+            "KEYWORDS": "湖南",
+            "DESCRIPTION": "湖南"
+        },
+        "JL": {
+            "NAME": "吉林",
+            "TITLE": "吉林",
+            "KEYWORDS": "吉林",
+            "DESCRIPTION": "吉林"
+        },
+        "JS": {
+            "NAME": "江苏",
+            "TITLE": "江苏",
+            "KEYWORDS": "江苏",
+            "DESCRIPTION": "江苏"
+        },
+        "JX": {
+            "NAME": "江西",
+            "TITLE": "江西",
+            "KEYWORDS": "江西",
+            "DESCRIPTION": "江西"
+        },
+        "LN": {
+            "NAME": "辽宁",
+            "TITLE": "辽宁",
+            "KEYWORDS": "辽宁",
+            "DESCRIPTION": "辽宁"
+        },
+        "NMG": {
+            "NAME": "内蒙古",
+            "TITLE": "内蒙古",
+            "KEYWORDS": "内蒙古",
+            "DESCRIPTION": "内蒙古"
+        },
+        "NX": {
+            "NAME": "宁夏",
+            "TITLE": "宁夏",
+            "KEYWORDS": "宁夏",
+            "DESCRIPTION": "宁夏"
+        },
+        "QH": {
+            "NAME": "青海",
+            "TITLE": "青海",
+            "KEYWORDS": "青海",
+            "DESCRIPTION": "青海"
+        },
+        "SX": {
+            "NAME": "山西",
+            "TITLE": "山西",
+            "KEYWORDS": "山西",
+            "DESCRIPTION": "山西"
+        },
+        "SXC": {
+            "NAME": "陕西",
+            "TITLE": "陕西",
+            "KEYWORDS": "陕西",
+            "DESCRIPTION": "陕西"
+        },
+        "SH": {
+            "NAME": "上海",
+            "TITLE": "上海",
+            "KEYWORDS": "上海",
+            "DESCRIPTION": "上海"
+        },
+        "SD": {
+            "NAME": "山东",
+            "TITLE": "山东",
+            "KEYWORDS": "山东",
+            "DESCRIPTION": "山东"
+        },
+        "SC": {
+            "NAME": "四川",
+            "TITLE": "四川",
+            "KEYWORDS": "四川",
+            "DESCRIPTION": "四川"
+        },
+        "TJ": {
+            "NAME": "天津",
+            "TITLE": "天津",
+            "KEYWORDS": "天津",
+            "DESCRIPTION": "天津"
+        },
+        "XJ": {
+            "NAME": "新疆",
+            "TITLE": "新疆",
+            "KEYWORDS": "新疆",
+            "DESCRIPTION": "新疆"
+        },
+        "TW": {
+            "NAME": "台湾",
+            "TITLE": "台湾",
+            "KEYWORDS": "台湾",
+            "DESCRIPTION": "台湾"
+        },
+        "XZ": {
+            "NAME": "西藏",
+            "TITLE": "西藏",
+            "KEYWORDS": "西藏",
+            "DESCRIPTION": "西藏"
+        },
+        "XG": {
+            "NAME": "香港",
+            "TITLE": "香港",
+            "KEYWORDS": "香港",
+            "DESCRIPTION": "香港"
+        },
+        "YN": {
+            "NAME": "云南",
+            "TITLE": "安徽标题",
+            "KEYWORDS": "安徽关键词",
+            "DESCRIPTION": "安徽描述"
+        },
+        "ZJ": {
+            "NAME": "浙江",
+            "TITLE": "浙江",
+            "KEYWORDS": "浙江",
+            "DESCRIPTION": "浙江"
+        }
+    },
+    "stype": {
+        "NJ": {
+            "NAME": "拟建",
+            "TITLE": "拟建项目_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "拟建项目,拟在建项目,拟建项目网,拟建项目信息",
+            "DESCRIPTION": "剑鱼标讯拟建项目专栏,包含国家发改委和各部委提供的尚处于前期立项、审批阶段的招投标项目,各供应商应在立项阶段就开始掌握最新的项目信息,做到早介入,早准备,稳拿单。"
+        },
+        "YG": {
+            "NAME": "预告",
+            "TITLE": "招标预告_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "招标预告,招标预告信息,招标预公告",
+            "DESCRIPTION": "剑鱼标讯招标预告栏目,每天发布国内最新的招标预告信息,提供各行业招标预告信息的搜索查询服务,不仅及时准确,而且更加专业。"
+        },
+        "ZB": {
+            "NAME": "招标",
+            "TITLE": "公开招标_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "公开招标,公开招标信息,公开招标公告,公开招标网",
+            "DESCRIPTION": "剑鱼标讯公开招标栏目,提供国内各行业最新最全的公开招标信息,出色的搜索查询服务,可以让用户更加快速高效的获取想要的信息。"
+        },
+        "YB": {
+            "NAME": "邀标",
+            "TITLE": "邀请招标_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "邀请招标,邀请招标信息,邀请招标公告",
+            "DESCRIPTION": "剑鱼标讯邀请招标栏目,及时准确的提供国内各行业最新的邀请招标信息,出色的搜索查询服务,可以让用户更加高效的获取想要的信息。"
+        },
+        "XJ": {
+            "NAME": "询价",
+            "TITLE": "询价采购_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "询价采购,询价采购信息,询价采购公告",
+            "DESCRIPTION": "获取全国各行业最新的询价采购信息,就来剑鱼标讯询价采购专栏,数据多而全,搜索查询更全面,专业性更高。"
+        },
+        "JT": {
+            "NAME": "竞谈",
+            "TITLE": "竞争性谈判_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "竞争性谈判,竞争性谈判采购,竞争性谈判信息,竞争性谈判公告",
+            "DESCRIPTION": "剑鱼标讯竞争性谈判栏目,专业为广大用户提供国内各省、各行业最新的竞争性谈判采购信息和查询服务。招标数据每天保持更新,及时而且准确。"
+        },
+        "DY": {
+            "NAME": "单一",
+            "TITLE": "单一来源_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "单一来源,单一来源采购,单一来源信息,单一来源采购公告",
+            "DESCRIPTION": "剑鱼标讯单一来源栏目,包含国内各省、各行业最新的单一来源采购公告,使用招标搜索功能,可以帮助用户更快速的获取这些信息。"
+        },
+        "JJ": {
+            "NAME": "竞价",
+            "TITLE": "公开竞价_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "公开竞价,网上竞价,公开竞价信息,公开竞价采购",
+            "DESCRIPTION": "剑鱼标讯公开竞价专栏,提供全国各省和更行业最新的公开竞价信息,你想看的这里都有,使用公开竞价的搜索查询服务更省心。"
+        },
+        "BG": {
+            "NAME": "变更",
+            "TITLE": "变更公告_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "变更公告,更正公告,变更公告信息,招标变更公告",
+            "DESCRIPTION": "变更公告是招标公告发布后,针对该公告的的地址、时间、招标内容等信息的变更通知。及时查询和获取全国最新的变更公告,就在剑鱼标讯变更公告专栏。"
+        },
+        "ZHB": {
+            "NAME": "中标",
+            "TITLE": "中标公示_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "中标公示,中标公示信息,中标公告结果,中标公示网",
+            "DESCRIPTION": "剑鱼标讯中标公示栏目,涵盖全国各省各行业最新的中标公示信息,可以帮助用户轻松查询到想看的中标信息,好用又省心。"
+        },
+        "CJ": {
+            "NAME": "成交",
+            "TITLE": "成交公告_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "成交公告,成交公告信息,成交结果,成交结果公告",
+            "DESCRIPTION": "剑鱼标讯成交公告栏目,提供专业的成交公告查询,成交结果查看等功能,全国各省和各个行业的成交公告信息都可以查看和查询。"
+        },
+        "FB": {
+            "NAME": "废标",
+            "TITLE": "废标公告_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "废标公告,废标公告信息,终止公告",
+            "DESCRIPTION": "剑鱼标讯废标公告栏目,提供全国各省,各行业最新的废标公告信息,出色的废标公告查询功能,支持多条件筛选,使用更简单。"
+        },
+        "LB": {
+            "NAME": "流标",
+            "TITLE": "流标公告_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "流标公告,流标公示,招标失败公告,采购失败公告",
+            "DESCRIPTION": "剑鱼标讯流标公告栏目,帮助用户准确获取和查询最新的流标公告信息,提前掌握招投标的进展情况,工作更轻松。"
+        },
+        "HT": {
+            "NAME": "合同",
+            "TITLE": "合同公告_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "合同公告,合同公告信息,采购合同公告",
+            "DESCRIPTION": "剑鱼标讯合同公告专栏,包含当前国内各省和各行业最全面的合同公告信息,使用合同公告搜索查询功能,获取信息更快更准确。"
+        },
+        "YS": {
+            "NAME": "验收",
+            "TITLE": "验收公告_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "验收公告,验收公告信息,验收项目",
+            "DESCRIPTION": "剑鱼标讯验收公告专栏,涵盖当前国内各省和各行业最全面的验收公告信息,使用验收公告搜索查询功能,获取信息更快更准确。"
+        },
+        "WG": {
+            "NAME": "违规",
+            "TITLE": "违规处理_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "违规处理,违规处理信息,违规招投标",
+            "DESCRIPTION": "剑鱼标讯违规处理栏目,每天汇总全国招投标行业最新的违规处理信息,搜索查询功能可以让用户更全面的了解招投标违规信息。"
+        },
+        "QT": {
+            "NAME": "其它",
+            "TITLE": "其他招标信息_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "结果公告,土地拍卖,国有产权拍卖,矿权拍卖",
+            "DESCRIPTION": "剑鱼标讯其他信息专栏为您提供招投标项目的结果公告,土地拍卖信息、国有产权拍卖信息和矿权拍卖信息等内容,让你更详细、更全面的了解所有招投标信息。"
+        }
+    },
+    "industry": {
+        "JZGC": {
+            "NAME": "建筑工程_勘察设计,建筑工程_工程施工,建筑工程_监理咨询,建筑工程_材料设备,建筑工程_机电安装",
+            "TITLE": "建筑工程_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "SLSD": {
+            "NAME": "水利水电_水利工程,水利水电_发电工程,水利水电_航运工程,水利水电_其他工程",
+            "TITLE": "水利水电_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "NYHG": {
+            "NAME": "能源化工_原材料,能源化工_仪器仪表,能源化工_新能源,能源化工_设备物资,能源化工_化工产品,能源化工_设备",
+            "TITLE": "能源化工_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "RDAF": {
+            "NAME": "弱电安防_综合布线,弱电安防_智能系统,弱电安防_智能家居",
+            "TITLE": "弱电安防_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "XXJS": {
+            "NAME": "信息技术_系统集成及安全,信息技术_软件开发,信息技术_运维服务,信息技术_其他",
+            "TITLE": "信息技术_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "XZBG": {
+            "NAME": "行政办公_办公家具,行政办公_通用办公设备,行政办公_专业设备,行政办公_办公用品,行政办公_生活用品",
+            "TITLE": "行政办公_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "JXSB": {
+            "NAME": "机械设备_矿山机械,机械设备_工程机械,机械设备_机械零部件,机械设备_机床相关,机械设备_车辆,机械设备_其他机械设备",
+            "TITLE": "机械设备_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "JTGC": {
+            "NAME": "交通工程_道路,交通工程_轨道,交通工程_桥梁,交通工程_隧道,交通工程_其他",
+            "TITLE": "交通工程_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "YLWS": {
+            "NAME": "医疗卫生_设备,医疗卫生_耗材,医疗卫生_药品",
+            "TITLE": "医疗卫生_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "SZSS": {
+            "NAME": "市政设施_道路,市政设施_绿化,市政设施_线路管网,市政设施_综合项目",
+            "TITLE": "市政设施_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "FWCG": {
+            "NAME": "服务采购_法律咨询,服务采购_会计,服务采购_物业,服务采购_审计,服务采购_安保,服务采购_仓储物流,服务采购_广告宣传印刷,服务采购_其他",
+            "TITLE": "服务采购_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        },
+        "NLMY": {
+            "NAME": "农林牧渔_生产物资,农林牧渔_生产设备,农林牧渔_相关服务",
+            "TITLE": "农林牧渔_剑鱼标讯,全行业招标信息智能推送领导者!",
+            "KEYWORDS": "",
+            "DESCRIPTION": ""
+        }
+    },
+    "jyadd": "http://127.0.0.1",
+    "limitcount": 20,
+    "ZBADDRESS": "",
+    "jysy": "10",
+    "jydyy": "11",
+    "jysslby": "12",
+    "jysskzy": "13",
+    "jybqy": "14",
+    "jybky": "15",
+    "jygywmy": "16",
+    "jySEMtgy": "17",
+    "jyzbqyss": "18",
+    "jynjxmy": "19",
+    "jyswhzy": "20",
+    "jyggfwy": "21",
+    "jyldy": "22",
+    "dataexport": "23",
+    "baiduSEM-p": "24",
+    "module": {
+        "subscribe": "订阅页",
+        "/list/": "标签页",
+        "supsearch/index": "搜索页",
+        "article/content": "快照页",
+        "jyblog": "博客页",
+        "aboutus": "关于我们页",
+        "bidsearchforent": "中标企业搜索页",
+        "proposedProject": "拟建项目页",
+        "busicooperation": "商务合作页",
+        "advservices": "广告服务页",
+        "article/bdcontent": "百度SEM-快照推广页"
+    },
+    "referer": {
+        "baidu.com": "百度SEO",
+        "so.com": "360SEO",
+        "sogou.com": "搜狗SEO",
+        "bing.com": "必应SEO",
+        "google": "谷歌SEO",
+        "open": "open"
+    },
+    "jianyuurl": {
+        "zhaobiao.info": "网站扫码",
+        "jianyu360.com": "网站扫码",
+        "jianyu360.cn": "网站扫码"
+    },
+    "source": {
+        "pcbaiduSEM": "百度SEM",
+        "360SEM": "360SEM",
+        "sogouSEM": "搜狗SEM",
+        "QQqun": "QQ群广告",
+        "BDwangmeng": "百度网盟",
+        "PCwailian": "PC端外链",
+        "email": "邮箱广告",
+        "JRTT": "今日头条PC端",
+        "tengxun": "腾讯网PC端广告",
+        "fenghuang": "凤凰网PC端广告",
+        "xinan": "信安CA证书精灵",
+        "xinlang": "新浪网广告",
+        "zhishiyingxiao": "百度知识营销",
+        "landpage": "新落地页",
+        "peixunwang": "招投标培训网",
+        "baiduSEM-p": "百度SEM-招标项目名称"
+    },
+    "advList": {
+        "专属味道": "oIMvJvjdp91QL-T7kVweryz58L9I"
+    },
+    "url": {
+        "portrait_winner": "http://192.168.20.35:8080/supsearch/winner",
+        "portrait_buyer": "http://192.168.20.35:8080/supsearch/buyer"
+    },
+    "pcHelper": {
+        "downloadUrl_win": "http://w2blmjy.qmx.top/res/JianYu for Windows.exe",
+        "downloadUrl_mac": "http://w2blmjy.qmx.top/res/JianYu for Mac.dmg"
+    }
 }

+ 3 - 0
src/web/staticres/css/pc.css

@@ -145,6 +145,9 @@ form{
 	color: #686868;
     border-top-left-radius: 4px;
     border-top-right-radius: 4px;
+    white-space:nowrap; 
+	overflow:hidden; 
+	text-overflow:ellipsis;
 	
 }
 .userInfo .infoList .myorderDiv{

+ 9 - 10
src/web/staticres/css/wxlist.css

@@ -3,6 +3,12 @@
 	color: #1d1d1d;
 	text-decoration: none;
 	word-break: break-all;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    max-height: 50px;
 }
 .tslist .keyword{
 	color:#2cb7ca;
@@ -12,19 +18,12 @@
 	padding: 17px 0px 17px 0px;
 }
 .resnumb .two{
-	/*font-size:16px;*/
+	font-size:16px;
 	/*font-weight:500;*/
 	padding-left:25px;
-	float:left;
 	line-height:24px;
 	color: #1D1D1D;
-    font-size: .32rem;
-    text-align: justify;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    display: -webkit-box;
-    -webkit-line-clamp: 2;
-    -webkit-box-orient: vertical;
+    /*font-size: .32rem;*/
 }
 .resnumb{
 	position: relative;
@@ -34,7 +33,7 @@
 	font-size:16px;
 	width:25px;
 	position: absolute;
-	top: 1px;
+	top: 0px;
 }
 .restime{
 	float:right; 

BIN
src/web/staticres/images/pc/sem.jpg


+ 3 - 0
src/web/staticres/js/login.js

@@ -490,6 +490,9 @@ var processpage = function(shareid,num){
 				window.open('/front/dataExport/toSieve')
 			}
 			break;
+		case "24"://百度SEM-p 快照页推广-落地页
+			window.open(semHref, '_self')
+			break
 	}
 }
 

+ 2 - 2
src/web/staticres/js/public-nav.js

@@ -9,7 +9,7 @@ $(function () {
 		    $thisWidth = $(this).width(),
 		    //当前宽度
 		$thisIndex = $(this).index();
-		if((typeof(myPageNavIsNormal)!="undefined"&&myPageNavIsNormal==true)||$href.indexOf("supsearch")>-1||$href.indexOf("bidsearchforent")>-1||$href.indexOf("promotional/topics")>-1||$href.indexOf("list")>-1||$href.indexOf("article/content")>-1||$href.indexOf("article/bdprivate")>-1||$href.indexOf("article/mailprivate")>-1||$href.indexOf("/jypc/toPushView")>-1||$href.indexOf("/jyblog")>-1||$href.indexOf("/dataExport")>-1||$href.indexOf("/front/dataService.html")>-1){
+		if((typeof(myPageNavIsNormal)!="undefined"&&myPageNavIsNormal==true)||$href.indexOf("supsearch")>-1||$href.indexOf("bidsearchforent")>-1||$href.indexOf("promotional/topics")>-1||$href.indexOf("list")>-1||$href.indexOf("article/content")>-1||$href.indexOf("article/bdprivate")>-1||$href.indexOf("article/mailprivate")>-1||$href.indexOf("article/bdcontent")>-1||$href.indexOf("/jypc/toPushView")>-1||$href.indexOf("/jyblog")>-1||$href.indexOf("/dataExport")>-1||$href.indexOf("/front/dataService.html")>-1){
 			$navLi.find("a").css({"color":"#252627"});
 		}else{
 			$navLi.find("a").css({"color":"#fff"});
@@ -39,7 +39,7 @@ function seclectNavLi(el, $index) {
 	var $slider = $(".public-nav .jynav .slider");
 	/*获取当前这个元素的css*/
 	var $thisCss = el.eq($index).width();
-	if((typeof(myPageNavIsNormal)!="undefined"&&myPageNavIsNormal==true)||$href.indexOf("supsearch")>-1||$href.indexOf("bidsearchforent")>-1||$href.indexOf("promotional/topics")>-1||$href.indexOf("list")>-1||$href.indexOf("article/content")>-1||$href.indexOf("article/bdprivate")>-1||$href.indexOf("article/mailprivate")>-1||$href.indexOf("/jyblog")>-1||$href.indexOf("/dataExport")>-1||$href.indexOf("/front/dataService.html")>-1){
+	if((typeof(myPageNavIsNormal)!="undefined"&&myPageNavIsNormal==true)||$href.indexOf("supsearch")>-1||$href.indexOf("bidsearchforent")>-1||$href.indexOf("promotional/topics")>-1||$href.indexOf("list")>-1||$href.indexOf("article/content")>-1||$href.indexOf("article/bdprivate")>-1||$href.indexOf("article/mailprivate")>-1||$href.indexOf("article/bdcontent")>-1||$href.indexOf("/jyblog")>-1||$href.indexOf("/dataExport")>-1||$href.indexOf("/front/dataService.html")>-1){
 		el.find("a").css({"color":"#252627"});
 	}else{
 		el.find("a").css({"color":"#fff"});

BIN
src/web/staticres/upload/2018/11/15/201811151709277155.jpg


BIN
src/web/staticres/upload/2018/12/10/201812100929403970.jpg


BIN
src/web/staticres/upload/2019/02/26/201902261001565574.jpg


BIN
src/web/staticres/upload/2019/02/26/201902261025438255.jpg


BIN
src/web/staticres/upload/2019/02/26/201902261036379066.jpg


+ 21 - 25
src/web/staticres/vipsubscribe/css/subscribe_list.css

@@ -108,10 +108,9 @@
 .free7days_pic,
 .noble_vip_pic {
   display: inline-block;
-  margin-right: .2rem;
-  padding-left: .4rem;
-  height: .4rem;
-  line-height: normal;
+  margin-right: 5px;
+  padding-right: 20px;
+  height: 22px;
   background: url(../image/v_icon.png) no-repeat left center;
   background-size: contain;
 }
@@ -119,12 +118,12 @@
 .free7days_pic:after {
   content: '试用7天';
   position: relative;
-  top: -0.03rem;
-  left: .05rem;
+  top: 0px;
+  left: 23px;
   display: inline-block;
-  padding: 0 .04rem;
+  padding: 0 1px;
   line-height: normal;
-  font-size: 0.18rem;
+  font-size: 12px;
   color: #fff;
   text-align: center;
   background-color: #CFAD89;
@@ -133,8 +132,8 @@
 
 .vip_banner .box {
   width: 100%;
-  height: .94rem;
-  padding: 0 .3rem;
+  height: 45px;
+  padding: 0 15px;
   box-sizing: border-box;
   background: url(../image/curve.png) no-repeat center center #34355A;
   background-size: 100% 100%;
@@ -159,11 +158,10 @@ font-weight: bold;
 
 .filter_tab {
   position: relative;
-  height: .88rem;
-  line-height: .88rem;
-  padding: 0 .3rem;
+  padding: 10px 8px;
   background: #fff;
-      border-bottom: 1px solid #E6E6E6;
+  border-bottom: 1px solid #E6E6E6;
+  font-size: 15px;
 }
 
 /*.filter_tab:after {
@@ -183,14 +181,13 @@ font-weight: bold;
 }
 
 .filter_tab .tab_left .time {
-  margin-right: .25rem;
+  margin-right: 20px;
 }
 
 .filter_tab .tab_left .time_box,
 .filter_tab .tab_left .area_box {
-  margin-right: .3rem;
+  margin-right: 5px;
   color: #686868;
-  font-size: .28rem;
 }
 
 .filter_tab .tab_left .time_box i,
@@ -201,34 +198,33 @@ font-weight: bold;
 }
 
 .filter_tab .tab_right .normal_set_box {
-  font-size: .28rem;
+  font-size: 15px;
   color: #1D1D1D;
   height: 100%;
   box-sizing: border-box;
 }
 
 .filter_tab .tab_right .normal_set_box i {
-  margin-right: .16rem;
-  font-size: .4rem;
+  margin-right: 5px;
+  font-size: 22px;
   color: #707070;
 }
 
 .filter_tab .tab_right .vip_set_box {
   position: relative;
-  padding-left: .3rem;
-  font-size: .28rem;
+  padding-left: 5px;
   color: #CFAD89;
-text-decoration: none;
+  text-decoration: none;
 }
 
 .filter_tab .tab_right .vip_set_box:before {
   content: '';
   width: 1px;
-  height: 60%;
+  height: 100%;
   background: #E0E0E0;
   position: absolute;
   left: 0;
-  top: 20%;
+  top: 0;
 }
 
 .filter_tab .area_container {

+ 76 - 0
src/web/staticres/vipsubscribe/css/vipreport_dialog.css

@@ -0,0 +1,76 @@
+@charset "UTF-8";
+/* 解决编译过程中闪烁的问题 */
+[v-cloak] {
+  display: none !important;
+}
+
+.vip_report_tip {
+  width: 100%;
+  height: 100%;
+  display: none;
+  position: fixed;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  top: 0px;
+  z-index:2000;
+}
+
+.vip_report_tip .weui-dialog {
+  width: 5.92rem;
+  height: 7.4rem;
+  border-radius: 0.16rem;
+  overflow: visible !important;
+}
+
+.vip_report_tip .weui-dialog .my-dialog__hd {
+  position: relative;
+  display: flex;
+  width: 100%;
+  height: 100%;
+  flex-direction: column;
+  align-items: center;
+}
+
+.vip_report_tip .weui-dialog .my-dialog__hd .jy_title {
+  min-width: 1.28rem;
+  height: 0.48rem;
+  font-size: 0.32rem;
+  color: #5F5E64;
+  margin-top: -0.24rem;
+}
+
+.vip_report_tip .weui-dialog .my-dialog__hd .weekly {
+  min-width: 3.2rem;
+  height: 0.6rem;
+  font-size: 0.4rem;
+  font-weight: bold;
+  line-height: inherit;
+}
+
+.vip_report_tip .weui-dialog .my-dialog__hd .term {
+  width: 100%;
+  height: 0.4rem;
+  margin-top: 0.16rem;
+  font-size: 0.26rem;
+}
+
+.vip_report_tip .weui-dialog .my-dialog__hd .vip_report_todetail {
+  width: 4.96rem;
+  height: 0.88rem;
+  background-color: #2ABED1;
+  border-radius: 0.8rem;
+  color: #FFFFFF;
+  font-size: 0.36rem;
+  margin-top: 0.8rem;
+  line-height: 0.88rem;
+}
+
+.vip_report_tip .weui-dialog .my-dialog__hd .vip_report_tip_close {
+  position: absolute;
+  right: 1%;
+  top: -10.33%;
+  width: 0.56rem;
+  height: 0.56rem;
+  color: #FFFFFF;
+}

+ 3 - 0
src/web/staticres/vipsubscribe/image/vipreport/close.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22ZM13.4143 12L16.2427 14.8284L14.8285 16.2426L12 13.4142L9.17161 16.2426L7.75739 14.8284L10.5858 12L7.75742 9.17158L9.17163 7.75736L12 10.5858L14.8285 7.75736L16.2427 9.17157L13.4143 12Z" fill="white"/>
+</svg>

BIN
src/web/staticres/vipsubscribe/image/vipreport/dialog-image.png


BIN
src/web/staticres/vipsubscribe/image/vipreport/report.png


+ 296 - 0
src/web/templates/pc/biddetail_bd.html

@@ -0,0 +1,296 @@
+<html>
+
+<head>
+<title>{{.T.obj.title}} - 剑鱼标讯</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1" />
+<meta name="Keywords" content="{{.T.obj.keywords}}"/>
+<meta name="Description" content="{{.T.obj.description}}"/>
+<meta name="renderer" content="webkit">
+<meta content="telephone=no" name="format-detection"/>
+{{include "/common/pnc.html"}}
+<link href="{{Msg "seo" "cdn"}}/css/pc.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+<script src="{{Msg "seo" "cdn"}}/js/jquery.cookie.js"></script>
+<script src="{{Msg "seo" "cdn"}}/js/pdfobject.min.js"></script>
+<link rel="stylesheet" type="text/css" href="{{Msg "seo" "cdn"}}/pccss/public-nav-1200.css?v={{Msg "seo" "version"}}" />
+<script type="text/javascript" src="{{Msg "seo" "cdn"}}/js/public-nav.js?v={{Msg "seo" "version"}}1"></script>
+<style>
+body{
+  font-family: "Microsoft YaHei",sans-serif;
+}
+.public-nav .iner .logo img{
+	width: 130px;
+}
+.fr {
+    float: right;
+}
+.public-nav{
+	background: #fff;
+    border-bottom: 1px solid #e0e0e0;
+}
+.pdfobject-container { height: 800px;}
+.pdfobject { border: 1px solid #666; }
+.noresize {
+  	resize: none;
+	border-radius: 4px;
+	background-color: #f5f5fb;
+}
+.modal-header {
+	border-bottom:0px;
+	padding: 30px 34px 0px;
+}
+.modal-footer {
+	border-top:0px;
+	padding: 0px 34px 20px;
+}
+.modal-body {
+	padding:18px 34px 25px;
+}
+.modal-header .close {
+    margin-top: -22px;
+    margin-right: -22px;
+}
+.adv-pccontent-right{
+	position:absolute;
+	top:0px; 
+	right:-5px;
+	width:200px;
+	height:200px;
+	text-align:center;
+	cursor: pointer;
+}
+.adv-pccontent-bottom{
+	width:1200px;
+	margin:0px auto;
+	height:80px;
+	margin-top: 20px;
+	text-align:left;
+	cursor: pointer;
+}
+.adv-pccontent-bottom img{
+	width:980px;
+	height:80px;
+}
+.adv-pccontent-right img{
+	width:200px;
+	height:200px;
+}
+
+/*j-wx-code Start*/
+.j-wx-code{
+	width: 335px;
+	height: 355px;
+	background-color: #fff;
+	-webkit-border-radius: 6px;
+	   -moz-border-radius: 6px;
+	        border-radius: 6px;
+	position: relative;
+	/*margin: 100px auto;*/
+}
+.j-wx-code>.code-close{
+	width: 40px;
+	height: 40px;
+	position: absolute;
+	right: -20px;
+	top: -20px;
+	cursor: pointer;
+	-webkit-transition: all 1s;
+	-o-transition: all 1s;
+	-moz-transition: all 1s;
+	transition: all 1s;
+}
+.j-wx-code>.code-close:hover{
+	-webkit-transform: scale(1.2);
+	   -moz-transform: scale(1.2);
+	    -ms-transform: scale(1.2);
+	     -o-transform: scale(1.2);
+	        transform: scale(1.2);
+}
+.j-wx-code>.code-title{
+	height: 82px;
+	background:url(/images/j-wx-code-title.png) center center no-repeat;
+	-webkit-animation: moveYun 15s infinite linear both;
+	   -moz-animation: moveYun 15s infinite linear both;
+	     -o-animation: moveYun 15s infinite linear both;
+	        animation: moveYun 15s infinite linear both;
+}
+.j-wx-code>.code-wxm{
+	text-align: center;
+	margin-bottom: -6px;
+	margin-top: -16px;
+	
+}
+.j-wx-code>.code-wxm>img{
+	width: 200px;
+	height: 200px;
+	margin-top: -5px;
+}
+.j-wx-code>.code-text{
+	text-align: center;	
+}
+.j-wx-code>.code-bottom{
+	width: 470px;
+	height: 211px;
+	position: absolute;
+	bottom: -113px;
+	left: -73px;
+	background: url(/images/j-wx-code-bottom.png) 0 0 no-repeat;
+}
+.j-wx-code>.code-bottom>img{
+	position: absolute;
+	left: 280px;
+	top: 88px;
+	-webkit-animation: codeWxMove 10s linear both;
+	   -moz-animation: codeWxMove 10s linear both;
+	     -o-animation: codeWxMove 10s linear both;
+	        animation: codeWxMove 10s linear both;
+	-webkit-animation-fill-mode:forwards;
+	   -moz-animation-fill-mode:forwards;
+	     -o-animation-fill-mode:forwards;
+	        animation-fill-mode:forwards
+}
+a{
+	text-decoration: none !important;
+}
+</style>
+</head>
+<body>
+{{include "/common/pchead.html"}}
+<script type="text/javascript">
+var semHref = "/article/content/"+{{.T.obj._id}}+".html"
+$(function(){
+	//history.replaceState("","",semHref)
+	$("#bidLogin").modal("show");
+	$(".logo img").attr("src","/images/swordfish/sf_01_new.png");
+	selcetIndexNav(8)
+})
+</script>
+
+<div class="j-content">
+<div class="main-content" style="width: 1200px; position: relative; margin: 0 auto">
+	<div class="biddetail-content" style="width:980px; margin-left:0px;">
+		<div class="com-title" id="com-title">
+			{{.T.obj.title}}
+		</div>
+		<div class="com-statusbar" id="statusbar">
+		</div>
+		
+        <div class="middle">
+            <img src="/images/pc/sem.jpg" alt="" width="910" height="920">
+        </div>
+		<center class="reward text-align">
+			<br><div>打赏</div>
+		</center>
+	</div>
+	<div  onclick="adv_statistics(this)" adv_name="PC快照页-右部"  class="adv-pccontent-right" id="B1" style="cursor:default;">
+		<script>
+			{{$s:=(Ad "jy-pccontent-right" -1)}}
+			var ADList={{$s}};
+			if(ADList){
+				var random=Math.floor(Math.random()*ADList.length);
+				var AD=ADList[random];
+				var ADHtml = "";
+				if(AD.s_pic!=undefined&&AD.s_pic){
+					if(AD.s_link){
+						ADHtml += "<a dataHref='"+AD.s_link+"' target='_blank'>";
+					}
+					ADHtml += "<img src='"+AD.s_pic+"'>";
+					if(AD.s_link){
+						ADHtml += "</a>";
+					}
+				}else {
+					ADHtml += AD.s_script;
+				}
+				$("#B1").html(ADHtml);
+			}
+		</script>
+	</div>
+</div>
+<div  onclick="adv_statistics(this)" adv_name="PC快照页-底部"  class="adv-pccontent-bottom" id="B2" style="cursor:default;">
+	<script>
+		{{$s:=(Ad "jy-pccontent-bottom" -1)}}
+		var ADList={{$s}};
+        if(ADList){
+			var random=Math.floor(Math.random()*ADList.length);
+            var AD=ADList[random];
+            var ADHtml = "";
+            if(AD.s_pic!=undefined&&AD.s_pic){
+                if(AD.s_link){
+                    ADHtml += "<a dataHref='"+AD.s_link+"' target='_blank'>";
+                }
+                ADHtml += "<img src='"+AD.s_pic+"'>";
+                if(AD.s_link){
+                    ADHtml += "</a>";
+                }
+            }else {
+                ADHtml += AD.s_script;
+            }
+            $("#B2").html(ADHtml);
+        }
+	</script>
+</div>
+</div>
+{{include "/common/pcbottom.html"}}
+<!--支付二维码-->
+<div class="payQRcode">
+	<div class="mark"></div>
+	<div class="reward-dialog">
+		<img src="{{Msg "seo" "cdn"}}/images/reward-close.png" class="reward-close">
+		<front>请微信扫码</front><br>
+		<img src="/jypay/weixin/reward/qr/{{.T.obj._id}}" class="qrcode">
+	</div>
+</div>
+<script type="text/javascript">
+$(function(){
+	haslogin({{.T.logid}},"","D");
+	JYLogin({{.T.logid}})
+	$.post("/front/pcAjaxReq",{reqType:"rewardText"},function(r){
+		$(".reward").prepend(r);
+	},"text");
+	$(".reward>div").click(function(){
+		$(".payQRcode").show();
+	});
+	$(".payQRcode .reward-close").click(function(){
+		$(".payQRcode").hide();
+	});
+	
+	$(window).scroll(function(){
+		if($(this).scrollTop() > 0){
+			$("#backTop").show();
+		}else{
+			$("#backTop").hide();
+		}
+	});
+	
+})
+var publishtime = {{.T.obj.publishtime}};
+var type = {{.T.obj.subtype}};
+var area = {{.T.obj.area}};
+var subscopeclass = {{.T.obj.subscopeclass}};
+
+if (area !="" && area != "A"){
+	$(".com-statusbar").append('<span class="com-area"><a href="#">'+area+'</a></span>');
+}
+if(typeof(type) == "undefined" || type == null || type == ""){
+	type = {{.T.obj.toptype}};
+}
+if(typeof(type) != "undefined" && type != null && type != ""){
+		$(".com-statusbar").append('<span class="com-type"><a href="#">'+type+'</a></span>');
+}
+//
+if(subscopeclass){
+	var suclass = subscopeclass.split(",")[0];
+	$(".com-statusbar").append('<span class="com-industry"><a href="#">'+suclass.split("_")[0]+'</a></span>');
+}
+//
+if(publishtime != ""){
+	var diff = timeDiff(new Date(Number(publishtime+"000")));
+	if(diff != null){
+		$(".com-statusbar").append('<span class="com-time"><i class="glyphicon bofangjilu"></i>'+diff+'</span>');
+	}
+}
+</script>
+<!--百度统计start-->
+{{include "/common/baiducc.html"}}
+<!--百度统计end-->
+</body>
+</html>

+ 1 - 1
src/web/templates/pchelper/pushView.html

@@ -507,7 +507,7 @@
 				<a class="active" href="javascript:;" style="width:100px;">最新订阅信息</a>
 			</li>
 		</ul>
-		<div class="right-tabBtn">
+		<div class="right-tabBtn" style="visibility:hidden;">
 			<button class="active" id="right-list">列表</button>
 			<button id="right-table">表格</button>
 		</div>

+ 87 - 12
src/web/templates/weixin/historypush.html

@@ -24,7 +24,8 @@
 	<link rel="stylesheet" href="{{Msg "seo" "cdn"}}/vipsubscribe/iconfont/iconfont.css" />
 	<link rel="stylesheet" href="{{Msg "seo" "cdn"}}/vipsubscribe/css/base.css?v={{Msg "seo" "version"}}" />
 	<link rel="stylesheet" href="{{Msg "seo" "cdn"}}/vipsubscribe/css/public.css?v={{Msg "seo" "version"}}">
-	<link rel="stylesheet" href="{{Msg "seo" "cdn"}}/vipsubscribe/css/subscribe_list.css?v={{Msg "seo" "version"}}11211">
+	<link rel="stylesheet" href="{{Msg "seo" "cdn"}}/vipsubscribe/css/subscribe_list.css?v={{Msg "seo" "version"}}">
+	<link rel="stylesheet" href="{{Msg "seo" "cdn"}}/vipsubscribe/css/vipreport_dialog.css?v={{Msg "seo" "version"}}">
 	<script>
 		var zbadd = {{Msg "seo" "ZBADDRESS"}};
 		var firstPage = null;
@@ -245,7 +246,7 @@
 				$(".normal_set").show();
 				$(".tab_left .area").hide();
 				$(".vip_banner").show();
-				$(".subscribe").css("margin-top","2rem");
+				$(".subscribe").css("margin-top","105px");
 				if(isPassCount){
 					$(".open_remind").show();
 				}
@@ -296,6 +297,7 @@
 						}
 					}
 				}else{
+          $('.filter_tab').css("font-size","14px");
 					if(parseInt(isExpire)>1){
 						$("._renew_toast .isExpire").text(parseInt(isExpire));
 						$("._renew_toast").show();
@@ -306,7 +308,32 @@
 					}
 				}
 				$(".vip_set").show();
+				$(".vip_report").show();
 				$(".tab_left .area").show();
+				$.post("/subscribepay/report/tip",null,function(r){
+					if(r.unread>0){
+						$(".vip_report>span>a").show();
+					}
+					if(r.tip){
+						if(r.tip.type==2){
+							$(".vip_report_tip .weekly>span").text("周");	
+						}else{
+							$(".vip_report_tip .weekly>span").text("月");
+						}
+						$(".vip_report_tip .term").text(new Date(Number(r.tip.startdate+"000")).Format("yyyy年M月d日")+"-"+new Date(Number(r.tip.enddate+"000")).Format("yyyy年M月d日"));	
+						$('.vip_report_tip').fadeIn();
+						$('.vip_report_todetail').on('click',function(){
+							updateReportStatus(1,r.tip.startdate,r.tip.enddate,r.tip.pushcount);
+						});
+						$('.weui-dialog img.vip_report_tip_close').click(function(){
+							$('.vip_report_tip').fadeOut();
+							updateReportStatus(0);
+						});
+					}
+				});
+				$(".vip_report").click(function(){
+					window.location.href = "/vipreport/page/subreport.html";
+				});
 			}
 		}
 		//
@@ -709,7 +736,7 @@
 		.listcontent{
 			padding:0px 10px;
 			background: #fff;
-			margin-top: .20rem;
+			margin-top: 60px;
 		}
 		.adv-wxpush-center {
 		    width: 100%;
@@ -742,10 +769,6 @@
 		.blue{
 			color:#0987ff;
 		}
-		.resnumb .two{
-			max-height: 45px;
-		    overflow: hidden;
-		}
 		#gotosetpage{
 			width: 54px;
 			position: fixed;
@@ -826,15 +849,45 @@
 			width: 100%;
 			z-index: 999;
 		}
-		.listcontent{
-			margin-top: 1rem;
-		}
 		.province_city p:last-child{
 			margin-bottom:1rem;
 		}
 		.province p:last-child{
 			margin-bottom:1rem;
 		}
+		.tab_right>div{
+			display: inline-block;
+		}
+		.vip_report{
+			color: #686868;
+      padding-right: .05rem;
+      vertical-align: top;
+      position: relative;
+      top: 2px;
+		}
+		.vip_report>span{
+			position: relative;
+			padding-right: 3px;
+		}
+		.vip_report>span>img{
+			width: 22px;
+      position: relative;
+      top: -1px;
+		}
+		.vip_report>span>a{
+      display: none;
+			position: absolute;
+      top: -4.5px;
+      right: 0px;
+      background-color: #FE737A;
+      width: 8px;
+      height: 8px;
+      border-radius: 100%;
+      z-index: 1;
+		}
+    .tab_right>.vip_set{
+      vertical-align: middle;
+    }
 	</style>
 </head>
 <body>
@@ -864,6 +917,9 @@
 				</div>
 			</div>
 			<div class="tab_right">
+				<div class="vip_report" style="display: none;">
+					<span><a></a><img src="{{Msg "seo" "cdn"}}/vipsubscribe/image/vipreport/report.png"></span><font>报告</font>
+				</div>
                 <div class="normal_set" style="display: none;" id="normal_set">
                   	<div class="normal_set_box">
                         <i class="icon iconfont">&#xe633;</i>
@@ -873,7 +929,7 @@
               	<div class="vip_set" style="display: none;">
               		<a onclick="tosetpage()" class="vip_set_box"  style="text-decoration: none;">
               			<span class="free7days_pic"></span>
-              			<span style="text-decoration: none;">VIP订阅设置</span>
+              			<span style="text-decoration: none;">VIP设置</span>
               		</a>
               	</div>
 	         </div>
@@ -955,6 +1011,19 @@
       	</div>
       </div>
   	</div>
+	<div class="vip_report_tip">
+		<div class="weui-mask weui-animate-fade-in"></div>
+		<div class="weui-dialog weui-animate-fade-in">
+			<div class="my-dialog__hd">
+				<img src="{{Msg "seo" "cdn"}}/vipsubscribe/image/vipreport/dialog-image.png" alt="">
+				<div class="jy_title">剑鱼标讯</div>
+				<h2 class="weekly">每<span></span>订阅报告来啦</h2>
+				<div class="term"></div>
+				<a href="javascript:void(0)" class="vip_report_todetail">点击查看</a>
+				<img src="{{Msg "seo" "cdn"}}/vipsubscribe/image/vipreport/close.svg" class="vip_report_tip_close">
+			</div>
+		</div>
+	</div>
   	<script src="{{Msg "seo" "cdn"}}/vipsubscribe/js/weui.min.js?v={{Msg "seo" "version"}}"></script>
   	<script src="{{Msg "seo" "cdn"}}/vipsubscribe/js/mapArea.js?v={{Msg "seo" "version"}}"></script>
   	<script type="text/javascript" charset="UTF-8">
@@ -1285,8 +1354,14 @@
 				localStorage.setItem("nv_vip_"+userId,"T");
             	$('.nv_renew_toast').hide()
             })
-            
         })
+		function updateReportStatus(type,start,end,pushcount){
+			$.post("/subscribepay/report/tipover",null,function(r){
+				if(type==1){
+					window.location.href = "/vipreport/page/reportdetail.html?start="+start+"&end="+end+"&pushcount="+pushcount;
+				}
+			});
+		}
     </script>
     <div id="advertscript" class="hidden adv-wxpush-center">
     	{{$s:=(Ad "jy-wxpush-middle" -1)}}

+ 5 - 5
src/web/templates/weixin/my.html

@@ -57,14 +57,14 @@
             </div>
         </div>
         <div class="menu">
-            <a href="#" class="menu_list vip">
+            <a class="menu_list vip">
                 <div class="menu_list_left">
                     <img src="/images/wx/persional/my_vip.png" alt="">
                     <span>VIP订阅</span>
                 </div>
                 <img class="arrow_right" src="/images/wx/persional/my_arrow_right.png" alt="">
             </a>
-            <a href="#" class="menu_list toSieve">
+            <a class="menu_list toSieve">
                 <div class="menu_list_left">
                     <img src="/images/wx/persional/my_data_export.png" alt="">
                     <span>数据导出</span>
@@ -73,21 +73,21 @@
             </a>
         </div>
         <div class="menu">
-            <a href="#" class="menu_list useHelp">
+            <a class="menu_list useHelp">
                 <div class="menu_list_left">
                     <img src="/images/wx/persional/my_list_4.png" alt="">
                     <span>使用帮助</span>
                 </div>
                 <img class="arrow_right" src="/images/wx/persional/my_arrow_right.png" alt="">
             </a>
-            <a href="#" class="menu_list aboutJy">
+            <a class="menu_list aboutJy">
                 <div class="menu_list_left">
                     <img src="/images/wx/persional/my_list_5.png" alt="">
                     <span>关于剑鱼标讯</span>
                 </div>
                 <img class="arrow_right" src="/images/wx/persional/my_arrow_right.png" alt="">
             </a>
-            <a href="#" class="menu_list feedback">
+            <a class="menu_list feedback">
                 <div class="menu_list_left">
                     <img src="/images/wx/persional/my_list_6.png" alt="">
                     <span>意见反馈</span>

+ 3 - 3
src/web/templates/weixin/search/mainSearch.html

@@ -54,9 +54,9 @@
         $('.weui-mask').hide();
 		if(getWxVersion()!=null){
 			window.ontouchmove=function(e){
-		        e.preventDefault && e.preventDefault();
-		        e.returnValue=true;
-		        e.stopPropagation && e.stopPropagation();
+		        //e.preventDefault && e.preventDefault();
+		        //e.returnValue=true;
+		        //e.stopPropagation && e.stopPropagation();
 		        return true;
 		     }
 		}