瀏覽代碼

Merge branch 'dev4.6.1.2' of http://192.168.3.207:8080/qmx/jy into dev4.6.1.2

zhangxinlei1996 3 年之前
父節點
當前提交
0c3a233a1f
共有 71 個文件被更改,包括 1997 次插入194 次删除
  1. 3 1
      src/jfw/front/frontRouter.go
  2. 9 5
      src/jfw/front/pchelper.go
  3. 2 3
      src/jfw/front/swordfish.go
  4. 1 1
      src/jfw/modules/app/src/app/front/bigMember.go
  5. 1 1
      src/jfw/modules/app/src/web/templates/weixin/follow/list.html
  6. 1 1
      src/jfw/modules/app/src/web/templates/weixin/historypush.html
  7. 7 1
      src/jfw/modules/bigmember/src/config.json
  8. 5 0
      src/jfw/modules/bigmember/src/config/config.go
  9. 351 102
      src/jfw/modules/bigmember/src/entity/followEnterprise.go
  10. 93 14
      src/jfw/modules/bigmember/src/entity/followProject.go
  11. 1 0
      src/jfw/modules/bigmember/src/service/analysis/analysis.go
  12. 3 3
      src/jfw/modules/bigmember/src/service/analysis/esquery.go
  13. 23 0
      src/jfw/modules/bigmember/src/service/analysis/forecastproject.go
  14. 6 6
      src/jfw/modules/bigmember/src/service/analysis/forecastwinner.go
  15. 107 15
      src/jfw/modules/bigmember/src/service/analysis/potential.go
  16. 81 0
      src/jfw/modules/bigmember/src/service/analysis/util.go
  17. 32 4
      src/jfw/modules/bigmember/src/service/follow/enterprise.go
  18. 19 1
      src/jfw/modules/bigmember/src/service/follow/project.go
  19. 6 3
      src/jfw/modules/bigmember/src/service/use/use.go
  20. 14 10
      src/jfw/modules/common/src/qfw/util/jy/bigVipPower.go
  21. 2 1
      src/jfw/modules/common/src/qfw/util/jy/subscribepush.go
  22. 1 0
      src/jfw/modules/followent/src/followent/myfwent.go
  23. 200 0
      src/jfw/modules/publicapply/src/customer/entity/entiy.go
  24. 11 0
      src/jfw/modules/publicapply/src/customer/init.go
  25. 13 0
      src/jfw/modules/publicapply/src/customer/service/action.go
  26. 110 0
      src/jfw/modules/publicapply/src/customer/service/service.go
  27. 3 0
      src/jfw/modules/publicapply/src/main.go
  28. 97 0
      src/jfw/modules/publicapply/src/project/project.go
  29. 4 0
      src/jfw/modules/publicapply/src/subscribePush/service/pushList.go
  30. 142 0
      src/jfw/modules/publicapply/src/userbase/bigmembermenu.json
  31. 195 0
      src/jfw/modules/publicapply/src/userbase/commonfunctions.json
  32. 175 0
      src/jfw/modules/publicapply/src/userbase/entity/entity.go
  33. 43 0
      src/jfw/modules/publicapply/src/userbase/entity/menu.go
  34. 13 0
      src/jfw/modules/publicapply/src/userbase/init.go
  35. 47 0
      src/jfw/modules/publicapply/src/userbase/initjson/initjson.go
  36. 13 0
      src/jfw/modules/publicapply/src/userbase/service/action.go
  37. 78 0
      src/jfw/modules/publicapply/src/userbase/service/service.go
  38. 1 0
      src/jfw/modules/subscribepay/src/config/config.go
  39. 2 0
      src/jfw/modules/subscribepay/src/entity/member.go
  40. 2 1
      src/jfw/modules/subscribepay/src/member.json
  41. 49 5
      src/jfw/modules/subscribepay/src/report/report.go
  42. 2 0
      src/jfw/modules/weixin/src/wx/wx.go
  43. 二進制
      src/web/staticres/big-member/image/customer/customer-wx.png
  44. 二進制
      src/web/staticres/commonFunctions/pc_ai_search.png
  45. 二進制
      src/web/staticres/commonFunctions/pc_analysis_search.png
  46. 二進制
      src/web/staticres/commonFunctions/pc_bidfile_landpage.png
  47. 二進制
      src/web/staticres/commonFunctions/pc_collection.png
  48. 二進制
      src/web/staticres/commonFunctions/pc_dataExport_index.png
  49. 二進制
      src/web/staticres/commonFunctions/pc_dataPack_history.png
  50. 二進制
      src/web/staticres/commonFunctions/pc_dataPack_me.png
  51. 二進制
      src/web/staticres/commonFunctions/pc_docs_collections.png
  52. 二進制
      src/web/staticres/commonFunctions/pc_ent_follow.png
  53. 二進制
      src/web/staticres/commonFunctions/pc_entsearch.png
  54. 二進制
      src/web/staticres/commonFunctions/pc_follow_project.png
  55. 二進制
      src/web/staticres/commonFunctions/pc_forecast_list.png
  56. 二進制
      src/web/staticres/commonFunctions/pc_integral.png
  57. 二進制
      src/web/staticres/commonFunctions/pc_mycoupon.png
  58. 二進制
      src/web/staticres/commonFunctions/pc_mydocs.png
  59. 二進制
      src/web/staticres/commonFunctions/pc_myorder.png
  60. 二進制
      src/web/staticres/commonFunctions/pc_potential_c.png
  61. 二進制
      src/web/staticres/commonFunctions/pc_potential_r.png
  62. 二進制
      src/web/staticres/commonFunctions/pc_search.png
  63. 二進制
      src/web/staticres/commonFunctions/pc_subreport_month.png
  64. 二進制
      src/web/staticres/commonFunctions/pc_subreport_week.png
  65. 二進制
      src/web/staticres/commonFunctions/pc_subscribe_info.png
  66. 二進制
      src/web/staticres/commonFunctions/pc_subscribe_manage.png
  67. 1 1
      src/web/staticres/css/follow.css
  68. 9 1
      src/web/templates/common/pchead.html
  69. 17 12
      src/web/templates/pc/biddetail_rec.html
  70. 1 1
      src/web/templates/weixin/follow/list.html
  71. 1 1
      src/web/templates/weixin/historypush.html

+ 3 - 1
src/jfw/front/frontRouter.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"jfw/config"
 	"jfw/public"
+	"log"
 	"qfw/util/jy"
 	"regexp"
 	"strings"
@@ -156,7 +157,7 @@ func (this *CommonRouter) BigpcPage(htmlPage string) error {
 	return this.doPcBigPage(htmlPage)
 }
 
-var bigVipFreePageReg = regexp.MustCompile(`set_*|free_*|unit_portrayal|analysis_(search|result)`)
+var bigVipFreePageReg = regexp.MustCompile(`set_.*|free|unit_portrayal|analysis_(search|result)|pro_follow_detail`)
 
 func (this *CommonRouter) doPcBigPage(pageSign string) error {
 	userid, _ := this.GetSession("userId").(string)
@@ -169,6 +170,7 @@ func (this *CommonRouter) doPcBigPage(pageSign string) error {
 		if array := strings.Split(pageSign, "/"); len(array) > 0 {
 			pageSign = array[0]
 		}
+		log.Println(bigVipFreePageReg.MatchString(pageSign), pageSign)
 		if !bigVipFreePageReg.MatchString(pageSign) {
 			bigBaseMsg := jy.GetBigVipUserBaseMsg(userid, public.Mysql, public.MQFW)
 			if bigBaseMsg.Status <= 0 && bigBaseMsg.Vip_BuySet.Upgrade != 1 {

+ 9 - 5
src/jfw/front/pchelper.go

@@ -184,15 +184,19 @@ func (l *PcHelper) Login() error {
 			if phone != "" && mac == deMac {
 				query := map[string]interface{}{
 					"i_appid": 2,
-					"s_phone": phone,
 				}
-				user, ok := mongodb.FindOneByField("user", query, `{"s_nickname":1}`)
+				if len([]rune(phone)) == 11 {
+					query["s_phone"] = phone
+				} else {
+					query["s_m_openid"] = phone
+				}
+				user, ok := mongodb.FindOneByField("user", query, `{"s_nickname":1,"s_phone":1}`)
 				if ok && user != nil && len(*user) > 0 {
 					reOpenId = phone
 					if (*user)["s_nickname"] != nil {
 						reNickname = (*user)["s_nickname"].(string)
-					} else {
-						reNickname = phone
+					} else if (*user)["s_phone"] != nil {
+						reNickname = (*user)["s_phone"].(string)
 					}
 					reToken = getUToken(mac, phone)
 					return 1
@@ -282,7 +286,7 @@ func (l *PcHelper) ToAct(token string) error {
 		} else {
 			if b {
 				if phone != "" && deMac != "" {
-					if len(phone) == 11 {
+					if len([]rune(phone)) == 11 {
 						//PcHelperLoginInfo(phone, l.Session())
 						CreateSession(map[string]interface{}{
 							"i_appid": 2,

+ 2 - 3
src/jfw/front/swordfish.go

@@ -934,9 +934,8 @@ func pcVRT(sid, industry string) (po, bo, wo []map[string]interface{}, objdata m
 				buyerOther = bidDataConvert(sid, commonQuery(queryStr))
 			}
 			//同一中标人最近中标的其他信息
-			subtype, _ := obj["subtype"].(string) //信息类型
-			winner, _ := obj["winner"].(string)   //中标人
-			if winner != "" && subtype == "中标" {
+			winner, _ := obj["winner"].(string) //中标人
+			if winner != "" {
 				queryStr = `{"TERM_s_winner":"` + winner + `"}`
 				winnerOther = bidDataConvert(sid, commonQuery(queryStr))
 			}

+ 1 - 1
src/jfw/modules/app/src/app/front/bigMember.go

@@ -14,7 +14,7 @@ type NewBigMemberAction struct {
 	powerClear     xweb.Mapper `xweb:"/jyapp/bigMember/powerClear"` //大会员清除redis 服务id缓存
 }
 
-var freePageReg = regexp.MustCompile(`full|landingPage|buy_commit|contrast|orderdetail_*|write_infor|init|set_*|ontrial_commit|bid_*|free_*|ent_portrait|bigvip_subreport_*|report_detail_*|analysis_(search|filter)`)
+var freePageReg = regexp.MustCompile(`full|landingPage|pro_follow_detail|buy_commit|push_setting_detail|land_setting|push_settings|contrast|orderdetail_.*|write_infor|init|set_.*|ontrial_commit|bid_.*|free_.*|ent_portrait|bigvip_subreport_.*|report_detail_.*|analysis_(search|filter)`)
 
 func init() {
 	jy.InitBigVipService(public.Mysql)

+ 1 - 1
src/jfw/modules/app/src/web/templates/weixin/follow/list.html

@@ -351,7 +351,7 @@ $(document).on('click','.pur_btn',function(){
 		</div>
 		<ul>
 		</ul>
-		<div class="divbtn"{{if .T.datas}}{{if eq (len .T.datas) 10}} disabled="disabled"{{end}}{{end}}><img class="jybtnimg" src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/jyaddfw.png?v={{Msg "seo" "version"}}"/></div>
+<!--		<div class="divbtn"{{if .T.datas}}{{if eq (len .T.datas) 10}} disabled="disabled"{{end}}{{end}}><img class="jybtnimg" src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/jyaddfw.png?v={{Msg "seo" "version"}}"/></div>-->
 		<div class="limit"></div>
 		<div class="tip">
 			<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/jyprompt.png?v={{Msg "seo" "version"}}">剑鱼标讯提示:<front>可关注{{.T.followLimit}}个项目</front>

+ 1 - 1
src/jfw/modules/app/src/web/templates/weixin/historypush.html

@@ -735,7 +735,7 @@
         }
         if (r.isExpire < 0 && r.vipStatus == -1) {
           if (localStorage.getItem("nv_vip_" + userId) == null) {
-            $(".nv_renew_toast").show();
+            // $(".nv_renew_toast").show();
           }
         }
         thisClass.LoadDatas(r);

+ 7 - 1
src/jfw/modules/bigmember/src/config.json

@@ -50,5 +50,11 @@
 	"warnMbTitle":"中标预测失败提醒",
 	"timeSpan":2,
 	"regWinner":".+[司院厂所心处普行]$",
-    "oldSubscribeMoveTip": 1632294000
+    "oldSubscribeMoveTip": 1632294000,
+    "customers":[
+    	{
+			"name":"赵秀臻",
+			"wxer":"/big-member/image/customer/customer-wx.png"
+		}
+    ]
 }

+ 5 - 0
src/jfw/modules/bigmember/src/config/config.go

@@ -31,6 +31,11 @@ type config struct {
 	TimeSpan            int
 	RegWinner           string
 	OldSubscribeMoveTip int64
+	Customers           []customerInfo
+}
+type customerInfo struct {
+	Name string `json:"name"`
+	Wxer string `json:"wxer"`
 }
 type followConfig struct {
 	Normal int

+ 351 - 102
src/jfw/modules/bigmember/src/entity/followEnterprise.go

@@ -1,14 +1,15 @@
 package entity
 
 import (
+	"config"
 	"db"
 	"errors"
 	"fmt"
-	"log"
 	"mongodb"
 	qutil "qfw/util"
 	"qfw/util/elastic"
 	"qfw/util/jy"
+	"qfw/util/redis"
 	"sort"
 	"strings"
 	"time"
@@ -16,6 +17,7 @@ import (
 )
 
 type EntFollow struct {
+	HasPower  bool
 	UserId    string //用户id
 	MaxNum    int    //最大关注数量
 	SaveTable string //关注企业数量
@@ -32,13 +34,11 @@ func CreateEntFollowManager(userid string, pageFlag ...string) (*EntFollow, erro
 	if len(pageFlag) > 0 {
 		defaultPageFlag = pageFlag[0]
 	}
-	isBuy := bigMsg.CheckBigVipBackPower(defaultPageFlag)
-	if !isBuy {
-		return nil, errors.New("非法请求")
+	if isBuy := bigMsg.CheckBigVipBackPower(defaultPageFlag); isBuy {
+		uid := qutil.If(bigMsg.Pid == "", userid, bigMsg.Pid).(string) //若为子账号则存储为主账号userid
+		return &EntFollow{true, uid, bigMsg.EntNum, "follow_entinfo_bigvip"}, nil
 	}
-
-	uid := qutil.If(bigMsg.Pid == "", userid, bigMsg.Pid).(string) //若为子账号则存储为主账号userid
-	return &EntFollow{uid, bigMsg.EntNum, "follow_entinfo_bigvip"}, nil
+	return &EntFollow{false, userid, config.Config.FollowProject.Normal, "jylab_followent"}, nil
 }
 
 //关注企业联想
@@ -58,7 +58,7 @@ func (this *EntFollow) GetAssociationEnt(entName string) ([]map[string]interface
 		})
 	}
 	//查询是否关注
-	followed, _ := db.Mgo.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, nil, `{"s_entname":1,"s_entId"}`, false, -1, -1)
+	followed, _ := db.Mgo.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, nil, `{"s_entname":1,"s_entId":1}`, false, -1, -1)
 	if followed != nil && len(*followed) > 0 { //有关注的项目
 		for _, follow := range *followed {
 			s_entId := qutil.ObjToString(follow["s_entId"])
@@ -79,74 +79,173 @@ func (this *EntFollow) GetAssociationEnt(entName string) ([]map[string]interface
 	return accMap, nil
 }
 
-//详情页查询是否关注企业
+//EntFollowedShow 详情页查询是否关注企业
+//followed 是否已关注
+//showFollow 是否展示关注(检索库存在相关企业信息时展示)
 func (this *EntFollow) EntFollowedShow(entId string) (followed, showFollow bool, err error) {
 	if entId == "" {
 		err = errors.New("未查询到企业")
 		return
 	}
-	query := map[string]interface{}{"s_entId": entId, "s_userid": this.UserId}
-	fRes, _ := db.Mgo.FindOneByField(this.SaveTable, query, `{"i_apppushunread":1}`)
-	followed = false
-	if fRes != nil && len(*fRes) > 0 {
-		followed = true
-		//已关注,并且有未读标示
-		if qutil.IntAll((*fRes)["i_apppushunread"]) > 0 {
-			go db.Mgo.Update(this.SaveTable, query, map[string]interface{}{
-				"$set": map[string]interface{}{
-					"i_apppushunread": 0,
-				},
-			}, false, false)
-		}
-	}
-	if followed {
-		//查询是否可以关注
-		showFollow = true
-		return
-	}
-	//展示是否关注(部分企业不在企业库中 不展示关注按钮)
-	r := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query": {"term": {"_id": "%s"}},"_source": ["name"],"size": %d}`, entId, 1))
-	if r != nil && len(*r) > 0 {
+	if this.HasPower { //大会员付费用户
+		query := map[string]interface{}{"s_entId": entId, "s_userid": this.UserId}
+		fRes, _ := db.Mgo.FindOneByField(this.SaveTable, query, `{"i_apppushunread":1}`)
+		followed = false
+		if fRes != nil && len(*fRes) > 0 {
+			followed = true
+			//已关注,并且有未读标示
+			if qutil.IntAll((*fRes)["i_apppushunread"]) > 0 {
+				go db.Mgo.Update(this.SaveTable, query, map[string]interface{}{
+					"$set": map[string]interface{}{
+						"i_apppushunread": 0,
+					},
+				}, false, false)
+			}
+		}
+		if followed {
+			//查询是否可以关注
+			showFollow = true
+			return
+		}
+		//展示是否关注(部分企业不在企业库中 不展示关注按钮)
+		r := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query": {"term": {"_id": "%s"}},"_source": ["name"],"size": %d}`, entId, 1))
+		if r != nil && len(*r) > 0 {
+			showFollow = true
+		}
+	} else { //免费用户
+		//获取关注企业名字
+		entName := getEntNameById(entId)
+		if entName == "" {
+			return
+		}
+
 		showFollow = true
+		query := map[string]interface{}{"s_entname": entName, "s_userid": this.UserId}
+		fRes, _ := db.Mgo.FindOneByField(this.SaveTable, query, `{"i_apppushunread":1}`)
+		if fRes != nil && len(*fRes) > 0 {
+			followed = true
+			//已关注,并且有未读标示
+			if qutil.IntAll((*fRes)["i_apppushunread"]) > 0 {
+				go db.Mgo.Update(this.SaveTable, query, map[string]interface{}{
+					"$set": map[string]interface{}{
+						"i_apppushunread": 0,
+					},
+				}, false, false)
+			}
+		}
 	}
 	return
 }
 
-//我关注的企业列表
-func (this *EntFollow) GetEntFollowList(pNum, pSize int) (followData []map[string]interface{}, hasNext bool, count int, err error) {
-	count = db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId})
+//GetEntFollowList 我关注的企业列表
+// param A默认分组 B竞争对手 C合作伙伴 逗号分隔
+// db  0||nil 默认分组、1 竞争对手、2 合作伙伴、3 竞争对手和合作伙伴
+func (this *EntFollow) GetEntFollowList(pNum, pSize int, match, group string) (followData []map[string]interface{}, hasNext bool, count, total int, err error) {
+	var groupSearchArr []map[string]interface{}
+	if group != "" {
+		groupSearchArr = func() (searchArr []map[string]interface{}) {
+			if strings.Index(group, "A") > -1 {
+				searchArr = append(searchArr, []map[string]interface{}{map[string]interface{}{"i_group": map[string]interface{}{"$exists": 0}}, map[string]interface{}{"i_group": 0}}...)
+			}
+			if strings.Index(group, "B") > -1 && strings.Index(group, "C") > -1 {
+				searchArr = append(searchArr, []map[string]interface{}{map[string]interface{}{"i_group": 1},
+					map[string]interface{}{"i_group": 2}, map[string]interface{}{"i_group": 3}}...)
+			} else {
+				if strings.Index(group, "B") > -1 {
+					searchArr = append(searchArr, []map[string]interface{}{map[string]interface{}{"i_group": 1}, map[string]interface{}{"i_group": 3}}...)
+				} else if strings.Index(group, "C") > -1 {
+					searchArr = append(searchArr, []map[string]interface{}{map[string]interface{}{"i_group": 2}, map[string]interface{}{"i_group": 3}}...)
+				}
+			}
+			return
+		}()
+	}
+	query := map[string]interface{}{"s_userid": this.UserId}
+	//已关注数量查询
+	count = db.Mgo.Count(this.SaveTable, query)
 	if count == 0 {
 		return
 	}
-	if pNum*pSize > count {
-		err = errors.New("非法查询")
-		return
+	if match = strings.TrimSpace(match); match != "" {
+		query["s_entname"] = map[string]interface{}{"$regex": match}
 	}
-	hasNext = (pNum+1)*pSize < count
-	res, _ := db.Mgo.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, `{"l_lastpushtime":-1}`, `{"s_entname":1,"s_area":1,"s_city":1,"s_phone":1,"f_capital":1,"s_employeeno":1,"l_establishdate":1,"i_apppushunread":1,"s_entId":1}`, false, pNum*pSize, pSize)
-	if res == nil || len(*res) == 0 {
-		err = errors.New("查询异常")
-		return
+	//当前筛选条件数量
+	if len(groupSearchArr) > 0 {
+		query["$or"] = groupSearchArr
+		total = db.Mgo.Count(this.SaveTable, query)
+		if total == 0 {
+			return
+		}
+	} else {
+		total = count
 	}
-	//followData = *res
-	//加密entId
-	for _, item := range *res {
-		entId := qutil.ObjToString(item["s_entId"])
-		if entId == "" { //dev3.6.2 前关注企业未存入企业id
-			//查询企业entid
-			entId = this.updateFollowed(item)
+
+	hasNext = (pNum+1)*pSize < total
+
+	if this.HasPower { //购买企业情报的用户直接查询
+		res, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1}`, `{"_id":1,"s_entname":1,"s_area":1,"s_city":1,"s_phone":1,"f_capital":1,"s_employeeno":1,"l_establishdate":1,"i_apppushunread":1,"s_entId":1,"l_lastpushtime":1,"i_group":1}`, false, pNum*pSize, pSize)
+		if res == nil || len(*res) == 0 {
+			err = errors.New("查询异常")
+			return
+		}
+		//followData = *res
+		//加密entId
+		for _, item := range *res {
+			entId := qutil.ObjToString(item["s_entId"])
+			if entId == "" { //dev3.6.2 前关注企业未存入企业id
+				//查询企业entid
+				entId = this.updateFollowed(item)
+			}
+			followData = append(followData, map[string]interface{}{
+				"fid":             util.EncodeId(mongodb.BsonIdToSId(item["_id"])),
+				"s_entId":         util.EncodeId(entId),
+				"f_capital":       item["f_capital"],
+				"l_establishdate": item["l_establishdate"],
+				"s_area":          item["s_area"],
+				"s_city":          item["s_city"],
+				"s_employeeno":    item["s_employeeno"],
+				"s_entname":       item["s_entname"],
+				"s_phone":         item["s_phone"],
+				"i_apppushunread": item["i_apppushunread"],
+				"l_lastpushtime":  item["l_lastpushtime"],
+				"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
+			})
+		}
+	} else { //免费用户根据企业名称 二次查询企业id、成立时间等数据
+		res, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1}`, `{"_id":1,"s_entname":1,"i_apppushunread":1,"l_lastpushtime":1,"i_group":1}`, false, pNum*pSize, pSize)
+		if res == nil || len(*res) == 0 {
+			err = errors.New("查询异常")
+			return
+		}
+		//根据企业名字查询企业信息
+		var names []string
+		for _, data := range *res {
+			names = append(names, qutil.ObjToString(data["s_entname"]))
+		}
+		fullData := getEntMsgByNames(names)
+
+		for _, item := range *res {
+			entName, _ := item["s_entname"].(string)
+			rowMap := map[string]interface{}{
+				"fid":             util.EncodeId(mongodb.BsonIdToSId(item["_id"])),
+				"s_entname":       entName,
+				"i_apppushunread": item["i_apppushunread"],
+				"l_lastpushtime":  item["l_lastpushtime"],
+				"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
+			}
+			if supplement, ok := fullData[entName]; ok {
+				//企业id
+				if entId, _ := supplement["_id"].(string); entId != "" {
+					rowMap["s_entId"] = util.EncodeId(entId)
+				}
+				rowMap["l_establishdate"] = supplement["establish_date"] //成立时间
+				rowMap["f_capital"] = supplement["capital"]              //注册资本
+				rowMap["s_area"] = supplement["company_area"]            //企业省份
+				rowMap["s_city"] = supplement["company_city"]            //城市
+				rowMap["s_phone"] = supplement["company_phone"]          //企业电话
+			}
+			followData = append(followData, rowMap)
 		}
-		followData = append(followData, map[string]interface{}{
-			"s_entId":         util.EncodeId(entId), //此处id需要加密
-			"f_capital":       item["f_capital"],
-			"l_establishdate": item["l_establishdate"],
-			"s_area":          item["s_area"],
-			"s_city":          item["s_city"],
-			"s_employeeno":    item["s_employeeno"],
-			"s_entname":       item["s_entname"],
-			"s_phone":         item["s_phone"],
-			"i_apppushunread": item["i_apppushunread"],
-		})
 	}
 	return
 }
@@ -154,7 +253,6 @@ func (this *EntFollow) GetEntFollowList(pNum, pSize int) (followData []map[strin
 func (this *EntFollow) GetEntFollowAndChangeList(num int) (followData []map[string]interface{}, err error) {
 	res, _ := db.Mgo.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, `{"l_lastpushtime":-1}`, `{"s_entname":1,"i_apppushunread":1,"s_entId":1,"l_lastpushtime":1}`, false, 0, num)
 	if res == nil || len(*res) == 0 {
-		err = errors.New("查询异常")
 		return
 	}
 	//加密entId,查询变更条数
@@ -201,7 +299,6 @@ func (this *EntFollow) updateFollowed(follow map[string]interface{}) string {
 	if entName == "" {
 		return ""
 	}
-	log.Println(fmt.Sprintf(`{"query":{"bool":{"should":[{"term":{"company_name":"%s"}},{"term":{"hname":"%s"}}],"minimum_should_match":1}},"_source":["name","_id","capital","company_phone"],"size":1}`, entName, entName))
 	rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"should":[{"term":{"company_name":"%s"}},{"term":{"hname":"%s"}}],"minimum_should_match":1}},"_source":["name","_id","capital","company_phone"],"size":1}`, entName, entName))
 	if rData == nil || len(*rData) == 0 {
 		return ""
@@ -234,58 +331,186 @@ func (this *EntFollow) updateFollowed(follow map[string]interface{}) string {
 	return entId
 }
 
-//添加关注企业
-func (this *EntFollow) AddFollowEnt(entId string, getOldData ...bool) error {
-	if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entId": entId}) > 0 {
-		return errors.New("已关注此企业")
-	}
-	if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}) >= this.MaxNum {
-		return errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", this.MaxNum))
-	}
-	res, _ := db.Mgo_Ent.FindOneByField("qyxy_std", map[string]interface{}{"_id": entId}, `{"company_name":1,"company_area":1,"company_city":1,"establish_date":1,"capital":1,"employee_no":1,"company_phone":1}`)
-	if res == nil || len(*res) == 0 {
-		return errors.New("查找企业异常")
-	}
-	followData := map[string]interface{}{
-		"s_entId":        mongodb.BsonIdToSId((*res)["_id"]), //dev3.6.2 企业画像根据entId查询
-		"s_entname":      (*res)["company_name"],
-		"s_area":         qutil.If((*res)["company_area"] == nil, "", (*res)["company_area"]),
-		"s_city":         qutil.If((*res)["company_city"] == nil, "", (*res)["company_city"]),
-		"s_phone":        qutil.If((*res)["company_phone"] == nil, "", (*res)["company_phone"]),
-		"f_capital":      qutil.If((*res)["capital"] == nil, 0.0, (*res)["capital"]),
-		"s_employeeno":   qutil.If((*res)["employee_no"] == nil, 0, (*res)["employee_no"]),
-		"l_createdate":   time.Now().Unix(),
-		"s_userid":       this.UserId,
-		"l_lastpushtime": time.Now().Unix(),
-	}
-	if len(getOldData) > 0 && getOldData[0] {
-		followent, ok := db.Mgo.FindOne("jylab_followent", map[string]interface{}{"s_userid": this.UserId, "s_entname": (*res)["company_name"]})
-		if followent != nil && ok && len(*followent) > 0 {
-			followData["s_id"] = qutil.If((*followent)["s_id"] == nil, "", (*followent)["s_id"])
-			followData["l_lastpushtime"] = qutil.If((*followent)["s_id"] == nil, 0, (*followent)["l_lastpushtime"])
+//AddFollowEnt 添加关注企业
+
+func (this *EntFollow) AddFollowEnt(entId, group string, getOldData ...bool) error {
+	groupFlag := getGroup(group)
+	if this.HasPower {
+		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entId": entId}) > 0 {
+			return errors.New("已关注此企业")
+		}
+		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}) >= this.MaxNum {
+			return errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", this.MaxNum))
+		}
+		res, _ := db.Mgo_Ent.FindOneByField("qyxy_std", map[string]interface{}{"_id": entId}, `{"company_name":1,"company_area":1,"company_city":1,"establish_date":1,"capital":1,"employee_no":1,"company_phone":1}`)
+		if res == nil || len(*res) == 0 {
+			return errors.New("查找企业异常")
+		}
+		followData := map[string]interface{}{
+			"s_entId":        mongodb.BsonIdToSId((*res)["_id"]), //dev3.6.2 企业画像根据entId查询
+			"s_entname":      (*res)["company_name"],
+			"s_area":         qutil.If((*res)["company_area"] == nil, "", (*res)["company_area"]),
+			"s_city":         qutil.If((*res)["company_city"] == nil, "", (*res)["company_city"]),
+			"s_phone":        qutil.If((*res)["company_phone"] == nil, "", (*res)["company_phone"]),
+			"f_capital":      qutil.If((*res)["capital"] == nil, 0.0, (*res)["capital"]),
+			"s_employeeno":   qutil.If((*res)["employee_no"] == nil, 0, (*res)["employee_no"]),
+			"l_createdate":   time.Now().Unix(),
+			"s_userid":       this.UserId,
+			"l_lastpushtime": time.Now().Unix(),
+		}
+
+		if len(getOldData) > 0 && getOldData[0] {
+			followent, ok := db.Mgo.FindOne("jylab_followent", map[string]interface{}{"s_userid": this.UserId, "s_entname": (*res)["company_name"]})
+			if followent != nil && ok && len(*followent) > 0 {
+				followData["s_id"] = qutil.If((*followent)["s_id"] == nil, "", (*followent)["s_id"])
+				followData["l_lastpushtime"] = qutil.If((*followent)["s_id"] == nil, 0, (*followent)["l_lastpushtime"])
+			}
+		}
+
+		establishdate := qutil.ObjToString((*res)["establish_date"])
+		if establishdate != "" {
+			t, err := time.Parse(qutil.Date_Short_Layout, establishdate)
+			if err == nil {
+				followData["l_establishdate"] = t.Unix()
+			}
+		}
+
+		//设置分组
+		if groupFlag > -1 {
+			followData["i_group"] = groupFlag
+		}
+		followId := db.Mgo.Save(this.SaveTable, followData)
+		if followId == "" || len(followId) == 0 {
+			return errors.New("保存关注企业异常")
+		}
+	} else { //免费用户关注企业
+		entName := getEntNameById(entId)
+		if entName == "" {
+			return errors.New("企业信息异常")
+		}
+		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entname": entName}) > 0 {
+			return errors.New("已关注此企业")
+		}
+		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}) >= this.MaxNum {
+			return errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", this.MaxNum))
+		}
+		followData := map[string]interface{}{
+			"s_entname":       entName,
+			"s_userid":        this.UserId,
+			"l_createtime":    time.Now().Unix(),
+			"l_lastpushtime":  time.Now().Unix(),
+			"i_apppushunread": 0,
+		}
+		//设置分组
+		if groupFlag > -1 {
+			followData["i_group"] = groupFlag
+		}
+		followId := db.Mgo.Save(this.SaveTable, followData)
+		if followId == "" || len(followId) == 0 {
+			return errors.New("保存关注企业异常")
 		}
 	}
+	go func(userId string) {
+		//首页潜在竞争对手缓存
+		redis.Del("other", fmt.Sprintf("CRIndex_R_%s", userId))
+	}(this.UserId)
+	return nil
+}
 
-	establishdate := qutil.ObjToString((*res)["establish_date"])
-	if establishdate != "" {
-		t, err := time.Parse(qutil.Date_Short_Layout, establishdate)
-		if err == nil {
-			followData["l_establishdate"] = t.Unix()
+// getGroup 获取分组
+// param A默认分组 B竞争对手 C合作伙伴 逗号分隔
+// db  0||nil 默认分组、1 竞争对手、2 合作伙伴、3 竞争对手和合作伙伴
+func getGroup(groupStr string) (s int) {
+	for _, sign := range strings.Split(groupStr, ",") {
+		switch sign {
+		case "A": //默认分组
+			return -1
+		case "B": //竞争对手
+			if s == 0 {
+				s = 1
+			} else {
+				return 3
+			}
+		case "C": //合作伙伴
+			if s == 0 {
+				s = 2
+			} else {
+				return 3
+			}
 		}
 	}
+	if s == 0 {
+		return -1
+	}
+	return
+}
+
+//格式化分组字段
+func parseGroupStr(gFlag int) string {
+	switch gFlag {
+	case 1:
+		return "B"
+	case 2:
+		return "C"
+	case 3:
+		return "B,C"
+	default:
+		return "A"
+	}
+}
 
-	followId := db.Mgo.Save(this.SaveTable, followData)
-	if followId == "" || len(followId) == 0 {
-		return errors.New("保存关注企业异常")
+//ChangeFollowGroup 更换关注企业分组
+func (this *EntFollow) ChangeFollowGroup(fid, group string) error {
+	groupValue := getGroup(group)
+	if groupValue == -1 {
+		groupValue = 0
+	}
+	if !db.Mgo.UpdateById(this.SaveTable, fid, map[string]interface{}{"$set": map[string]interface{}{"i_group": groupValue}}) {
+		return fmt.Errorf("设置分组失败")
 	}
 	return nil
 }
 
 //删除关注企业
-func (this *EntFollow) DelFollowEnt(entId string) error {
-	if db.Mgo.Delete(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entId": entId}) < 0 {
-		return errors.New("取关企业失败")
+func (this *EntFollow) DelFollowEnt(entId, fid string) error {
+	if entId == "" && fid == "" {
+		return fmt.Errorf("筛选条件异常")
 	}
+	query := map[string]interface{}{
+		"s_userid": this.UserId,
+	}
+	if this.HasPower {
+		if entId != "" {
+			query["s_entId"] = entId
+		}
+		if fid != "" {
+			query["_id"] = mongodb.StringTOBsonId(fid)
+		}
+		if db.Mgo.Delete(this.SaveTable, query) < 0 {
+			return errors.New("取关企业失败")
+		}
+	} else {
+		if fid != "" {
+			query["_id"] = mongodb.StringTOBsonId(fid)
+		} else if entId != "" {
+			if entName := getEntNameById(entId); entName != "" {
+				query["s_entname"] = entName
+			} else {
+				return fmt.Errorf("未获取到企业信息")
+			}
+		}
+		data, ok := db.Mgo.FindOne("jylab_followent", query)
+		if ok && data != nil && len(*data) > 0 && db.Mgo.Del("jylab_followent", map[string]interface{}{"_id": (*data)["_id"]}) {
+			(*data)["s_followid"] = mongodb.BsonIdToSId((*data)["_id"])
+			db.Mgo.Save("jylab_followent_back", data)
+		} else {
+			return fmt.Errorf("操作失败")
+		}
+	}
+	go func(userId string) {
+		//首页潜在竞争对手缓存
+		redis.Del("other", fmt.Sprintf("CRIndex_R_%s", userId))
+	}(this.UserId)
 	return nil
 }
 
@@ -374,3 +599,27 @@ func InitializeSort(data []map[string]interface{}) []map[string][]EntChangeSort
 	}
 	return result
 }
+
+func getEntNameById(entId string) (entName string) {
+	r := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query": {"term": {"_id": "%s"}},"_source": ["name"],"size": %d}`, entId, 1))
+	if r == nil || len(*r) == 0 {
+		return
+	}
+	entName, _ = (*r)[0]["name"].(string)
+	return
+}
+
+func getEntMsgByNames(names []string) (detail map[string]map[string]interface{}) {
+	detail = make(map[string]map[string]interface{})
+	names_str := `"` + strings.Join(names, `","`) + `"`
+	rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"must":[{"terms":{"company_name":[%s]}}]}},"_source":["company_name","_id","company_area","company_city","company_phone","capital","establish_date"],"size":%d}`, names_str, len(names)))
+	if rData == nil || len(*rData) == 0 {
+		return
+	}
+	for _, data := range *rData {
+		if name, ok := data["company_name"].(string); ok && name != "" {
+			detail[name] = data
+		}
+	}
+	return
+}

+ 93 - 14
src/jfw/modules/bigmember/src/entity/followProject.go

@@ -14,6 +14,7 @@ import (
 	"qfw/util/redis"
 	"qfw/util/rpc"
 	"strings"
+	"sync"
 	"time"
 	"util"
 )
@@ -29,7 +30,6 @@ func CreateProjectFollowManager(userid string, mustBuy ...bool) (*ProjectFollow,
 	if len(mustBuy) > 0 && !isBuy {
 		return nil, errors.New("非法请求")
 	}
-
 	if isBuy { //收费版
 		uid := qutil.If(bigMsg.Pid == "", userid, bigMsg.Pid).(string) //若为子账号则存储为主账号userid
 		return &ProjectFollow{true, uid, bigMsg.ProNum, "follow_project_bigvip"}, nil
@@ -218,7 +218,7 @@ func (this *ProjectFollow) GetDetailByFid(fid string) (returnData map[string]int
 //大会员查询项目信息
 func (this *ProjectFollow) GetProjectDetailBySid(sid string) (res map[string]interface{}, err error) {
 	redisKey := fmt.Sprintf("project_%s", sid)
-	log.Println("redisKey:", redisKey)
+	// log.Println("redisKey:", redisKey)
 	if reidsCatche, redisErr := redis.GetBytes("other", redisKey); redisErr == nil && reidsCatche != nil {
 		err = json.Unmarshal(*reidsCatche, &res)
 		if err == nil {
@@ -270,7 +270,10 @@ func (this *ProjectFollow) SetFollowRead(sid, fid, flag string) bool {
 
 //获取列表页
 func (this *ProjectFollow) GetFollowList(pNum, pSize int) (followData []map[string]interface{}, hasNext bool, count int, err error) {
-	count = db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId})
+	query := map[string]interface{}{
+		"s_userid": this.UserId,
+	}
+	count = db.Mgo.Count(this.SaveTable, query)
 	if count == 0 {
 		return
 	}
@@ -279,7 +282,7 @@ func (this *ProjectFollow) GetFollowList(pNum, pSize int) (followData []map[stri
 		return
 	}
 	hasNext = (pNum+1)*pSize < count
-	followList, _ := db.Mgo.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"l_lastpushtime":1,"s_id":1,"i_remind":1,"_id":1,"l_createtime":1,"i_apppushunread":1}`, false, pNum*pSize, pSize)
+	followList, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"l_lastpushtime":1,"s_id":1,"i_remind":1,"_id":1,"l_createtime":1,"i_apppushunread":1}`, false, pNum*pSize, pSize)
 	if followList == nil || len(*followList) == 0 {
 		err = errors.New("查询异常")
 		return
@@ -290,15 +293,43 @@ func (this *ProjectFollow) GetFollowList(pNum, pSize int) (followData []map[stri
 		sid := qutil.ObjToString(followOne["s_id"])
 		if followOne["l_lastpushtime"] != nil && followOne["l_lastpushtime"] != "" {
 			followOne["l_createtime"] = followOne["l_lastpushtime"]
+		} else if followOne["l_lastpushtime"] == nil {
+			followOne["l_lastpushtime"] = followOne["l_createtime"]
 		}
 		sidArr = append(sidArr, sid)
 		followSetting[sid] = followOne
 	}
-	projectInfos, err := getProjectsBySid(sidArr)
-	if err != nil {
-		err = errors.New("项目信息查询异常")
-		return nil, false, 0, err
-	}
+	projectInfos := []map[string]interface{}{}
+
+	pool := make(chan bool, 10)
+	wait := &sync.WaitGroup{}
+	var lock sync.Mutex
+	for _, v := range SplitArray(sidArr, 50) {
+		pool <- true
+		wait.Add(1)
+		go func(arr []string) error {
+			defer func() {
+				wait.Done()
+				<-pool
+			}()
+			//es查询
+			projectInfos_, err := getProjectsBySid(arr)
+			lock.Lock()
+			projectInfos = append(projectInfos, projectInfos_...)
+			lock.Unlock()
+			if err != nil {
+				err = errors.New("项目信息查询异常")
+				return err
+			}
+			return nil
+		}(v)
+	}
+	wait.Wait()
+	// projectInfos, err := getProjectsBySid(sidArr)
+	// if err != nil {
+	// 	err = errors.New("项目信息查询异常")
+	// 	return nil, false, 0, err
+	// }
 	for _, projectinfo := range projectInfos { //补充设置信息
 		for _, k := range qutil.ObjArrToStringArr(projectinfo["ids"].([]interface{})) {
 			if info, ok := followSetting[k]; ok {
@@ -307,6 +338,7 @@ func (this *ProjectFollow) GetFollowList(pNum, pSize int) (followData []map[stri
 				info["budget"] = qutil.Float64All(projectinfo["budget"])
 				info["title"] = projectinfo["projectname"]
 				info["status"] = projectinfo["bidstatus"]
+				info["projectcode"] = projectinfo["projectcode"]
 				break
 			}
 		}
@@ -317,22 +349,25 @@ func (this *ProjectFollow) GetFollowList(pNum, pSize int) (followData []map[stri
 		thisRow["fid"] = util.EncodeId(fid)
 		thisRow["sid"] = util.EncodeId(sid)
 		if thisRow["title"] == nil {
-			//删除异常数据
-			go this.CancelFollow(sid, fid)
+			log.Println("异常数据:", sid, fid)
+			//大会员有项目进度监控权限删除异常项目(包括:非会员时 手动添加的没有招标信息的项目) 否则不显示不处理
+			if this.Buy {
+				//删除异常数据
+				go this.CancelFollow(sid, fid)
+			}
 			continue
 		}
 		delete(thisRow, "_id")
 		delete(thisRow, "s_id")
 		followData = append(followData, thisRow)
 	}
-
 	return
 }
 
 //根据多个信息id查询对应的项目信息
 func getProjectsBySid(sids []string) ([]map[string]interface{}, error) {
 	sidStr := strings.Join(sids, `","`)
-	list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"terms": {"list.infoid": ["`+sidStr+`"]}}]}},"_source":["projectname","_id","area","buyerclass","budget","ids","bidstatus"],"from": 0,"size": `+fmt.Sprint(len(sids))+`}`)
+	list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"terms": {"list.infoid": ["`+sidStr+`"]}}]}},"_source":["projectname","_id","area","buyerclass","budget","ids","bidstatus","projectcode"],"from": 0,"size": `+fmt.Sprint(len(sids))+`}`)
 	if len(*list) == 0 {
 		return nil, errors.New("获取项目信息查询出错")
 	}
@@ -353,7 +388,7 @@ func (this *ProjectFollow) CancelFollow(sid, fid string) error {
 	if fid != "" {
 		query["_id"] = StringTOBsonId(fid)
 	}
-	log.Println(query)
+	// log.Println(query)
 	data, _ := db.Mgo.FindOne(this.SaveTable, query)
 	if data == nil || len(*data) == 0 {
 		return errors.New("未找到相应数据")
@@ -441,3 +476,47 @@ func delRelRedis(userid interface{}, relationinfo interface{}) {
 		redis.Del("push", "push_"+uid+"_"+sid)
 	}
 }
+
+//获取已关注项目的地区
+//项目提醒开关
+func (this *ProjectFollow) Area(list []map[string]interface{}) []string {
+	areaM := map[string]int{}
+	area := []string{}
+	for _, v := range list {
+		areaM[qutil.ObjToString(v["area"])]++
+	}
+	for k, _ := range areaM {
+		area = append(area, k)
+	}
+	return area
+}
+
+//分割数组
+func SplitArray(arr []string, num int64) [][]string {
+	max := int64(len(arr))
+	//判断数组大小是否小于等于指定分割大小的值,是则把原数组放入二维数组返回
+	if max <= num {
+		return [][]string{arr}
+	}
+	//获取应该数组分割为多少份
+	var quantity int64
+	if max%num == 0 {
+		quantity = max / num
+	} else {
+		quantity = (max / num) + 1
+	}
+	//声明分割好的二维数组
+	var segments = make([][]string, 0)
+	//声明分割数组的截止下标
+	var start, end, i int64
+	for i = 1; i <= quantity; i++ {
+		end = i * num
+		if i != quantity {
+			segments = append(segments, arr[start:end])
+		} else {
+			segments = append(segments, arr[start:])
+		}
+		start = i * num
+	}
+	return segments
+}

+ 1 - 0
src/jfw/modules/bigmember/src/service/analysis/analysis.go

@@ -33,6 +33,7 @@ type Analysis struct {
 	fWOvertime   xweb.Mapper `xweb:"/forecast/forWOvertime"` //中标预测超时处理
 	bdInfoStatus xweb.Mapper `xweb:"/forecast/bdInfoStatus"` //中标预测-项目是否已完成招标
 	freeDecInfo  xweb.Mapper `xweb:"/decision/freeDecInfo"`  //投标决策分析-免费用户
+	potIndex     xweb.Mapper `xweb:"/potential/index"`       //潜在客户customers or 潜在竞争对手rivals 首页接口
 }
 
 const (

+ 3 - 3
src/jfw/modules/bigmember/src/service/analysis/esquery.go

@@ -469,18 +469,18 @@ func PCQuery(area map[string]interface{}, industry []string, buyerclass []string
 			must_not := []string{}
 			//关键词
 			for _, v := range kv.Keyword {
-				shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+v+"\""))
+				shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+strings.ReplaceAll(v, "\n", "")+"\""))
 			}
 			//附加词
 			if len(kv.Appended) > 0 {
 				for _, vv := range kv.Appended {
-					shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
+					shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+strings.ReplaceAll(vv, "\n", "")+"\""))
 				}
 			}
 			if len(kv.Exclude) > 0 {
 				//排除词
 				for _, vv := range kv.Exclude {
-					must_not = append(must_not, fmt.Sprintf(multi_match, "\""+vv+"\""))
+					must_not = append(must_not, fmt.Sprintf(multi_match, "\""+strings.ReplaceAll(vv, "\n", "")+"\""))
 				}
 			}
 			//添加

+ 23 - 0
src/jfw/modules/bigmember/src/service/analysis/forecastproject.go

@@ -175,9 +175,32 @@ func getNewProjects(userId string, cpage int) ([]map[string]interface{}, int) {
 			createtime := ov["createtime"]
 			ov["createtime"] = qutil.FormatDateWithObj(&createtime, qutil.Date_Short_Layout)
 			ov["id"] = util.EncodeId(ov["id"].(string))
+			ov["results"] = keysfilter(qutil.ObjArrToMapArr(ov["results"].([]interface{})))
 			delete(ov, "_id")
 		}
 		return *data, count
 	}
 	return nil, 0
 }
+
+//过滤 去重 处理特殊符号
+func keysfilter(result []map[string]interface{}) (res []map[string]interface{}) {
+	if len(result) > 0 {
+		var keysMap = map[string]bool{}
+	L:
+		for _, rv := range result {
+			keys := qutil.ObjArrToStringArr(rv["keys"].([]interface{}))
+			var _keys = []string{}
+			for _, kv := range keys {
+				if kv == "" || keysMap[strings.ReplaceAll(kv, "+", "、")] {
+					continue L
+				}
+				keysMap[strings.ReplaceAll(kv, "+", "、")] = true
+				_keys = append(_keys, strings.ReplaceAll(kv, "+", "、"))
+			}
+			rv["keys"] = strings.Split(strings.Join(_keys, "、"), " ")
+			res = append(res, rv)
+		}
+	}
+	return res
+}

+ 6 - 6
src/jfw/modules/bigmember/src/service/analysis/forecastwinner.go

@@ -87,12 +87,12 @@ func (this *Analysis) FWData() {
 	if this.Method() == METHOD {
 		// log.Println(this.Request)
 		userId, _ := this.GetSession("userId").(string)
-		//有正在预测的数据或已预测未查看的数据
-		OverRegLock.Lock()
-		defer func() {
-			OverRegLock.Unlock()
-			// <-ForecastChan
-		}()
+		// //有正在预测的数据或已预测未查看的数据
+		// OverRegLock.Lock()
+		// defer func() {
+		// 	OverRegLock.Unlock()
+		// 	// <-ForecastChan
+		// }()
 		success, id := isExistsFIng(userId)
 		status := 0
 		if success {

+ 107 - 15
src/jfw/modules/bigmember/src/service/analysis/potential.go

@@ -6,6 +6,7 @@ import (
 	"db"
 	"encoding/json"
 	"entity"
+	"fmt"
 	"log"
 	qutil "qfw/util"
 	"qfw/util/jy"
@@ -19,15 +20,60 @@ import (
 	"go.mongodb.org/mongo-driver/bson"
 )
 
-type SelectC struct {
-	Area           map[string]interface{} //区域
-	BuyerClass     []string               //客户类型(采购单位行业)
-	Industry       []string               //行业分类(信息行业)
-	Business_scope []ViewKeyWord          //业务范围(关键词 附加词 排除词)
-	Sort_no        int                    //排序规则
-	PCOR           string                 //客户还是竞争对手 C:客户;R:对手
-	ServiceId      int                    //大会员服务id
-	Searchbool     int                    //是否是查询
+//大会员首页
+func (this *Analysis) PotIndex() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qutil.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		//接受前端参数
+		ptst := new(SelectC)
+		if string(this.Body()) != "" {
+			//接收参数
+			json.Unmarshal(this.Body(), &ptst)
+		}
+		ptst.UserId = userId
+		if !ptst.UserStatusChecked() {
+			return Result{Data: nil, Error_msg: Error_msg_1004}
+		}
+		if ptst.PCOR != "" && ptst.IsIndex {
+			list := []*PTComs{}
+			ok, _ := redis.Exists("other", "CRIndex_"+ptst.PCOR+"_"+ptst.UserId)
+			baseKeys := ptst.Base64Keys()
+			_res := redis.Get("other", baseKeys)
+			if ok && _res != nil {
+				b, e := json.Marshal(_res)
+				if e != nil {
+					log.Println(e.Error())
+				}
+				json.Unmarshal(b, &list)
+			} else {
+				//客户
+				if ptst.PCOR == "C" {
+					potComQ := PCQuery(ptst.Area, ptst.Industry, ptst.BuyerClass, ptst.Business_scope, ptst.Sort_no, ptst.PCOR)
+					list = getPCostomers(ptst.UserId, ptst.EntName, potComQ, ptst.PCOR)
+
+				} else if ptst.PCOR == "R" {
+					potRivQ := PCQuery(ptst.Area, ptst.Industry, ptst.BuyerClass, ptst.Business_scope, ptst.Sort_no, ptst.PCOR)
+					list = getPRivals(ptst.UserId, potRivQ, ptst.PCOR)
+				}
+			}
+			if len(list) > 20 {
+				list = list[:20]
+			}
+			if len(list) > 0 {
+				redis.Put("other", baseKeys, list, 8*60*60)
+				redis.Put("other", "CRIndex_"+ptst.PCOR+"_"+ptst.UserId, "CR", 8*60*60)
+			}
+			return Result{Data: map[string]interface{}{
+				"list": list,
+			}}
+		}
+		return Result{Data: nil}
+	}()
+	this.ServeJson(r)
 }
 
 //移除我的潜在对手
@@ -52,6 +98,10 @@ func (this *Analysis) RMyRivals() {
 				regMap.Data = map[string]interface{}{
 					"success": ok,
 				}
+				go func(userId string) {
+					//首页潜在竞争对手缓存
+					redis.Del("other", fmt.Sprintf("CRIndex_R_%s", userId))
+				}(main_userId)
 			}
 		} else {
 			regMap.Error_code = Error_code_1002
@@ -338,7 +388,7 @@ func getMyFollowEnts(userId string) map[string]interface{} {
 //潜在客户
 func getPCostomers(userId, entName string, potComQ, pcor string) []*PTComs {
 	var regMap = []*PTComs{}
-	//获取我的客户信息
+	//获取用户默认企业的客户信息+手动关注的企业信息+不是我的客户信息 此三项都不展示在我的客户列表
 	MyCustomers := getMyCostomers(userId, entName)
 	// log.Println("MyCustomers:", MyCustomers)
 	aggs, _ := GetAggs(P_INDEX, P_TYPE, potComQ)
@@ -357,13 +407,12 @@ func getPCostomers(userId, entName string, potComQ, pcor string) []*PTComs {
 	return regMap
 }
 
-//获取当前我的客户信息
-func getMyCostomers(userId, entName string) (MyCS map[string]interface{}) {
+//获取当前我的客户信息(大会员初始化的企业名称+关注的客户名称)
+func getMyCostomers(userId, entName string) map[string]interface{} {
+	MyCS := map[string]interface{}{}
 	r_MyCS := redis.Get("other", "mycostomer_"+userId)
 	if r_MyCS == nil {
-		MyCS = map[string]interface{}{}
 		query_str := getQueryByEntName(entName)
-		// log.Println("query:", query_str)
 		aggs, _ := GetAggs(P_INDEX, P_TYPE, query_str)
 		if aggs != nil {
 			if aggs_g, ok := aggs.Children("group_buyer"); ok {
@@ -384,10 +433,53 @@ func getMyCostomers(userId, entName string) (MyCS map[string]interface{}) {
 				}
 			}
 		}
-		redis.Put("other", "mycostomer_"+userId, MyCS, P_redis_time)
+		if MyCS != nil {
+			redis.Put("other", "mycostomer_"+userId, MyCS, P_redis_time)
+		}
 	} else {
 		MyCS = r_MyCS.(map[string]interface{})
 	}
+	//我关注的客户
+	r_ATTCS := redis.GetStr("other", "customer_list_"+userId)
+	if r_ATTCS == "" {
+		clist, ok := db.Mgo.Find("follow_customer", map[string]interface{}{
+			"userId": userId,
+		}, nil, `{"name":1}`, false, -1, -1)
+		if ok && clist != nil && len(*clist) > 0 {
+			names := []string{}
+			for _, v := range *clist {
+				names = append(names, v["name"].(string))
+			}
+			r_ATTCS = strings.Join(names, ",")
+			redis.Put("other", "customer_list_"+userId, r_ATTCS, 2*60*60)
+		}
+	}
+	for _, v := range strings.Split(r_ATTCS, ",") {
+		if v != "" {
+			MyCS[v] = true
+		}
+	}
+	//不是我的客户
+	r_EXCCS := redis.GetStr("other", "customer_exclude_"+userId)
+	if r_EXCCS == "" {
+		clist, ok := db.Mgo.Find("exclude_customer", map[string]interface{}{
+			"userId": userId,
+		}, nil, `{"name":1}`, false, -1, -1)
+		if ok && clist != nil && len(*clist) > 0 {
+			names := []string{}
+			for _, v := range *clist {
+				names = append(names, v["name"].(string))
+			}
+			r_EXCCS = strings.Join(names, ",")
+			redis.Put("other", "customer_exclude_"+userId, r_EXCCS, 2*60*60)
+		}
+	}
+	for _, v := range strings.Split(r_EXCCS, ",") {
+		if v != "" {
+			MyCS[v] = true
+		}
+	}
+	// log.Println(userId, "---", MyCS)
 	return MyCS
 }
 

+ 81 - 0
src/jfw/modules/bigmember/src/service/analysis/util.go

@@ -4,12 +4,16 @@ import (
 	"bytes"
 	"crypto/hmac"
 	"crypto/sha1"
+	"db"
 	"encoding/base64"
+	"encoding/json"
 	"hash"
 	"io"
 	"net/url"
+	"qfw/util/jy"
 	"sort"
 	"strings"
+	"util"
 )
 
 type SignStr struct {
@@ -19,6 +23,83 @@ type SignStr struct {
 
 var secret = "20202020"
 
+type SelectC struct {
+	Area           map[string]interface{} //区域
+	BuyerClass     []string               //客户类型(采购单位行业)
+	Industry       []string               //行业分类(信息行业)
+	Business_scope []ViewKeyWord          //业务范围(关键词 附加词 排除词)
+	Sort_no        int                    //排序规则
+	PCOR           string                 //客户还是竞争对手 C:客户;R:对手
+	ServiceId      int                    //大会员服务id
+	Searchbool     int                    //是否是查询
+	IsIndex        bool                   //是否首页查询
+	EntName        string                 //我的企业
+	UserId         string
+}
+
+//查看权限
+func (this *SelectC) UserStatusChecked() bool {
+	serviceId := 7
+	if this.PCOR == "R" {
+		serviceId = 8
+	}
+	userPower := jy.GetBigVipUserBaseMsg(this.UserId, db.Mysql, db.Mgo)
+	return userPower.Status > 0 && userPower.PowerMap[serviceId]
+}
+
+//查看数据
+func (this *SelectC) Base64Keys() (baseKey string) {
+	this.UserId, _, _ = util.MainUserId(this.UserId, "", 0)
+	this.Area, this.BuyerClass, this.Business_scope = GetUserInfo(this.UserId)
+	area, _ := json.Marshal(this.Area)
+	//查库获得大会员用户的行业信息
+	industry := []byte{}
+	entInfo, ok := db.Mgo.FindOneByField("member", `{"userid":"`+this.UserId+`"}`, `{"entname":1,"industry":1}`)
+	if ok && entInfo != nil {
+		if (*entInfo)["entname"] != nil {
+			this.EntName = (*entInfo)["entname"].(string)
+		}
+		if (*entInfo)["industry"] != nil {
+			industry, _ = json.Marshal((*entInfo)["industry"])
+		}
+	}
+	var keywordsaggregate = ""
+	for _, v := range this.Business_scope {
+		keywordsaggregate = keywordsaggregate + strings.Join(v.Keyword, "") + strings.Join(v.Appended, "") + strings.Join(v.Exclude, "")
+	}
+	baseKey = GetBase64KeyForPotential(this.UserId, string(area), strings.Join(this.BuyerClass, ""), keywordsaggregate, this.EntName, string(industry)) + "_" + this.PCOR
+	return
+}
+
+//
+func GetBase64KeyForPotential(userId, area, buyerClass, business_scope, entName, industry string) (signedStr string) {
+	var param = [][]string{
+		[]string{"userId", userId},
+		[]string{"area", area},
+		[]string{"buyerClass", buyerClass},
+		[]string{"business_scope", business_scope},
+		[]string{"entName", entName},
+		[]string{"industry", industry},
+	}
+	sgt := &SignStr{[]string{}, []string{}}
+	for _, v := range param {
+		sgt.Key = append(sgt.Key, v[0])
+		sgt.Val = append(sgt.Val, v[1])
+	}
+	sgt.Sort()
+	reqStr := sgt.ToString()
+	str := percentEncode(reqStr)
+	// log.Println("str", str)
+	h := hmac.New(func() hash.Hash {
+		return sha1.New()
+	}, []byte(secret))
+	io.WriteString(h, str)
+	signedStr = url.QueryEscape(base64.StdEncoding.EncodeToString(h.Sum(nil)))
+	// log.Println(signedStr)
+	return
+}
+
+//
 func GetBase64Key(userId, pname, sid string) (signedStr string) {
 	var param = [][]string{
 		[]string{"userId", userId},

+ 32 - 4
src/jfw/modules/bigmember/src/service/follow/enterprise.go

@@ -4,6 +4,7 @@ import (
 	. "api"
 	"entity"
 	"errors"
+	"fmt"
 	"log"
 	qutil "qfw/util"
 	"util"
@@ -21,6 +22,7 @@ type FollowEnt struct {
 	delFollow          xweb.Mapper `xweb:"/follow/ent/delFollow"`          //取消关注标企业
 	entChangeList      xweb.Mapper `xweb:"/follow/ent/entChangeList"`      //企业变更记录
 	pcSimpleFollowList xweb.Mapper `xweb:"/follow/ent/pcSimpleFollowList"` //pc关注企业列表(带变更)
+	changeGroup        xweb.Mapper `xweb:"/follow/ent/changeGroup"`        //关注企业分组改变
 }
 
 //中标企业联想
@@ -84,12 +86,13 @@ func (this *FollowEnt) List() {
 		if pSize == 0 || pSize > 100 {          //默认一页50条数据
 			pSize = 50
 		}
-		entList, hasNext, count, err := followEntManager.GetEntFollowList(pNum, pSize)
+		entList, hasNext, count, total, err := followEntManager.GetEntFollowList(pNum, pSize, this.GetString("match"), this.GetString("group"))
 		if err != nil {
 			return nil, err
 		}
 		return map[string]interface{}{
-			"total":     count,
+			"count":     count,                   //已关注数量
+			"total":     total,                   //筛选总数
 			"hasNext":   hasNext,                 //是否有下一页
 			"list":      entList,                 //我关注的企业信息
 			"followMax": followEntManager.MaxNum, //最多关注企业数量
@@ -136,7 +139,7 @@ func (this *FollowEnt) AddFollow() {
 		if err != nil {
 			return nil, err
 		}
-		err = followEntManager.AddFollowEnt(util.DecodeId(entId))
+		err = followEntManager.AddFollowEnt(util.DecodeId(entId), this.GetString("group"))
 		if err != nil {
 			return nil, err
 		}
@@ -157,7 +160,7 @@ func (this *FollowEnt) DelFollow() {
 		if err != nil {
 			return nil, err
 		}
-		err = followEntManager.DelFollowEnt(util.DecodeId(entId))
+		err = followEntManager.DelFollowEnt(util.DecodeId(entId), util.DecodeId(this.GetString("fid")))
 		if err != nil {
 			return nil, err
 		}
@@ -177,6 +180,9 @@ func (this *FollowEnt) EntChangeList() {
 		if err != nil {
 			return nil, err
 		}
+		if !cepm.HasPower {
+			return nil, fmt.Errorf("暂无权限")
+		}
 		entInfo, err := cepm.GetEntChangeList(util.DecodeId(this.GetString("entId")))
 		if err != nil {
 			return nil, err
@@ -188,3 +194,25 @@ func (this *FollowEnt) EntChangeList() {
 	}
 	this.ServeJson(NewResult(rData, errMsg))
 }
+
+//ChangeGroup 更换关注企业分组
+func (this *FollowEnt) ChangeGroup() {
+	userId := qutil.ObjToString(this.GetSession("userId"))
+	rData, errMsg := func() (interface{}, error) {
+		cepm, err := entity.CreateEntFollowManager(userId)
+		if err != nil {
+			return nil, err
+		}
+		group := this.GetString("group")
+		followId := util.DecodeId(this.GetString("fid"))
+		err = cepm.ChangeFollowGroup(followId, group)
+		if err != nil {
+			return nil, err
+		}
+		return "success", nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s 关注企业-更换分组出错:%s\n", userId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}

+ 19 - 1
src/jfw/modules/bigmember/src/service/follow/project.go

@@ -24,6 +24,7 @@ type FollowProject struct {
 	addTime       xweb.Mapper `xweb:"/follow/project/addTime"`     //项目关注-添加提醒时间&开标时间
 	remindSwitch  xweb.Mapper `xweb:"/follow/project/remind"`      //项目关注-项目提醒开关
 	remove30Day   xweb.Mapper `xweb:"/follow/project/remove30Day"` //批量删除30天未更新的项目
+	screenArea    xweb.Mapper `xweb:"/follow/project/screenArea"`  //关注项目筛选地区
 }
 
 //项目关注
@@ -136,7 +137,7 @@ func (this *FollowProject) FollowList() {
 func (this *FollowProject) FollowDetail() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
-		projectManager, err := entity.CreateProjectFollowManager(userId, true)
+		projectManager, err := entity.CreateProjectFollowManager(userId)
 		if err != nil {
 			return nil, err
 		}
@@ -323,3 +324,20 @@ func (this *FollowProject) RemindSwitch() {
 	}
 	this.ServeJson(NewResult(rData, errMsg))
 }
+
+//获取已关注的项目地区
+func (this *FollowProject) ScreenArea() {
+	userId := qutil.ObjToString(this.GetSession("userId"))
+	rData, errMsg := func() (interface{}, error) {
+		projectManager, err := entity.CreateProjectFollowManager(userId)
+		if err != nil {
+			return nil, err
+		}
+		pList, _, _, err := projectManager.GetFollowList(0, 500)
+		return projectManager.Area(pList), nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s 项目关注列表获取已关注项目地区出错:%s\n", userId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}

+ 6 - 3
src/jfw/modules/bigmember/src/service/use/use.go

@@ -135,11 +135,11 @@ func (u *Use) Add() {
 				followEntManager, err := entity.CreateEntFollowManager(userid)
 				if err != nil {
 					log.Println("add err:", userid, err)
-				} else {
+				} else if followEntManager.HasPower {
 					for k, v := range ids {
 						BigMsg := jy.GetBigVipUserBaseMsg(userid, db.Mysql, db.Mgo)
 						if BigMsg.Status != 4 {
-							err = followEntManager.AddFollowEnt(v, true)
+							err = followEntManager.AddFollowEnt(v, "", true)
 							if err != nil {
 								log.Println("add err:", userid, err)
 							}
@@ -488,7 +488,7 @@ func (u *Use) Equity() {
 			if s_phone != "" && len(s_phone) == 11 {
 				s_phone = s_phone[:3] + "****" + s_phone[7:]
 			}
-			name := qu.If((*person)["s_nickname"] == nil, s_phone, (*person)["s_nickname"])
+			name := (*person)["s_nickname"] //qu.If((*person)["s_nickname"] == nil, s_phone, (*person)["s_nickname"])
 			i_member_status := qu.IntAllDef((*person)["i_member_status"], 0)
 			i_member_endtime := qu.IntAllDef((*person)["i_member_endtime"], 0)
 			companyname, industry := "", map[string]interface{}{}
@@ -520,6 +520,7 @@ func (u *Use) Equity() {
 			return Result{Data: M{
 				"headimage":      headimage,
 				"name":           name,
+				"phone":          s_phone,
 				"member_status":  i_member_status,
 				"member_endtime": i_member_endtime,
 				"entname":        companyname,
@@ -532,6 +533,7 @@ func (u *Use) Equity() {
 				"isbidfilePower": overdue,
 				"combo":          Combo(userid, i_member_status),
 				"bidTotalCount":  bidTotalCount,
+				"customers":      config.Config.Customers,
 			}}
 		}
 		return Result{}
@@ -942,6 +944,7 @@ func addOldent(userid, entname string) {
 	data["s_entname"] = entname
 	data["s_userid"] = userid
 	data["l_createtime"] = time.Now().Unix()
+	data["l_lastpushtime"] = time.Now().Unix()
 	db.Mgo.Save("jylab_followent", data)
 }
 

+ 14 - 10
src/jfw/modules/common/src/qfw/util/jy/bigVipPower.go

@@ -13,15 +13,16 @@ import (
 
 //大会员状态redis缓存
 type BigVipBaseMsg struct {
-	Status   int          `json:"status"`    //大会员状态
-	Used     bool         `json:"used"`      //是否首次使用大会员
-	PowerMap map[int]bool `json:"p_map"`     //权限列表
-	ProNum   int          `json:"p_num"`     //可关注项目数量
-	EntNum   int          `json:"e_num"`     //可关注企业数量(取企业情报监控和企业中标动态中最大的值)
-	DailyNum int          `json:"d_num"`     //数据包导出数量
-	Pid      string       `json:"pid"`       //若为子账号此处为父节点userid
-	Uid      string       `json:"uid"`       //用户id
-	HasTrial bool         `json:"has_trial"` //是否试用过
+	Status    int          `json:"status"`    //大会员状态
+	Used      bool         `json:"used"`      //是否首次使用大会员
+	PowerMap  map[int]bool `json:"p_map"`     //权限列表
+	ProNum    int          `json:"p_num"`     //可关注项目数量
+	EntNum    int          `json:"e_num"`     //可关注企业数量(取企业情报监控和企业中标动态中最大的值)
+	DailyNum  int          `json:"d_num"`     //数据包导出数量
+	Pid       string       `json:"pid"`       //若为子账号此处为父节点userid
+	Uid       string       `json:"uid"`       //用户id
+	HasTrial  bool         `json:"has_trial"` //是否试用过
+	Customers int          `json:"customers"` //可关注客户数量
 
 	VipStatus  int    `json:"vip_status"` //超级订阅状态
 	Vip_BuySet BuySet `json:"vip_buyset"` //超级订阅套餐内容
@@ -129,7 +130,7 @@ func GetBigVipUserBaseMsg(userId string, mysql *mysql.Mysql, mg MongodbSim) *Big
 	//用户购买的服务
 	serviceList := mysql.Find(BigmemberUserPowerTable, map[string]interface{}{"s_userid": queryId, "i_status": 0}, "DISTINCT(s_serviceid),i_frequency", "", -1, -1)
 	if serviceList != nil && len(*serviceList) != 0 {
-		pCount, eCount, dailyNum := 0, 0, 0
+		pCount, eCount, dailyNum, customers := 0, 0, 0, 10
 		for _, item := range *serviceList {
 			serviceid := qutil.IntAll(item["s_serviceid"])
 			userPower.PowerMap[serviceid] = true
@@ -142,11 +143,14 @@ func GetBigVipUserBaseMsg(userId string, mysql *mysql.Mysql, mg MongodbSim) *Big
 				}
 			} else if serviceid == 17 || serviceid == 18 { //每日数据包
 				dailyNum = qutil.IntAll(item["i_frequency"])
+			} else if serviceid == 7 { //潜在客户 关注客户
+				customers = qutil.IntAll(item["i_frequency"])
 			}
 		}
 		userPower.EntNum = eCount
 		userPower.ProNum = pCount
 		userPower.DailyNum = dailyNum
+		userPower.Customers = customers
 	}
 
 	//存储缓存

+ 2 - 1
src/jfw/modules/common/src/qfw/util/jy/subscribepush.go

@@ -205,7 +205,7 @@ func (s *subscribePush) InfoFormat(p *PushCa, info *map[string]interface{}) *Sub
 }
 
 func (s *subscribePush) Datas(spqp *SubPushQueryParam) (hasNextPage bool, total int64, result []*SubPushList) {
-	log.Println(spqp.UserId, s.ModuleFlag, "subscribePush query param:", "SelectTime", spqp.SelectTime, "Area", spqp.Area, "City", spqp.City, "Subtype", spqp.Subtype, "Subscopeclass", spqp.Subscopeclass, "Buyerclass", spqp.Buyerclass, "Key", spqp.Key, "PageNum", spqp.PageNum)
+	// log.Println(spqp.UserId, s.ModuleFlag, "subscribePush query param:", "SelectTime", spqp.SelectTime, "Area", spqp.Area, "City", spqp.City, "Subtype", spqp.Subtype, "Subscopeclass", spqp.Subscopeclass, "Buyerclass", spqp.Buyerclass, "Key", spqp.Key, "PageNum", spqp.PageNum)
 	if spqp.UserId == "" {
 		return
 	}
@@ -271,6 +271,7 @@ func (s *subscribePush) Datas(spqp *SubPushQueryParam) (hasNextPage bool, total
 		if start < length {
 			result = subPush.Datas[start:end]
 		}
+		total = int64(length)
 	} else if spqp.IsEmpty() && (spqp.PageNum-1)*spqp.PageSize <= 250 { //全部,没有过滤条件 之前缓存5页*50条=250
 		allCache, err := s.GetAllCache(spqp.UserId)
 		if err != nil {

+ 1 - 0
src/jfw/modules/followent/src/followent/myfwent.go

@@ -44,6 +44,7 @@ func (m *Myfwent) Addfwent() error {
 		data["s_openid"] = openid
 		data["i_ispush"] = 1
 		data["l_createtime"] = time.Now().Unix()
+		data["l_lastpushtime"] = time.Now().Unix()
 		if followId = mongodb.Save("jylab_followent", data); len(followId) > 0 {
 			status = "y"
 		}

+ 200 - 0
src/jfw/modules/publicapply/src/customer/entity/entiy.go

@@ -0,0 +1,200 @@
+package entity
+
+import (
+	"db"
+	"fmt"
+	"jfw/modules/common/src/qfw/util/jy"
+	qu "qfw/util"
+	"qfw/util/elastic"
+	"qfw/util/redis"
+	"strings"
+	"time"
+)
+
+type CustomerOperation struct {
+	UserId   string `json:"userId"`
+	Name     string `json:"name"`
+	Province string `json:"province"`
+	City     string `json:"city"`
+	B        bool   `json:"b"` //true 取关;默认 false 关注。
+}
+
+func NewCustomerOperation() CustomerOperation {
+	return CustomerOperation{}
+}
+
+var (
+	fc              = "follow_customer"  //关注客户表
+	ec              = "exclude_customer" //不是我的客户表
+	redisName       = "other"
+	redisListKey    = "customer_list_%s"
+	redisCountKey   = "customer_count_%s"
+	redisExcludeKey = "customer_exclude_%s"
+	redisCRIndex    = "CRIndex_C_%s" //首页潜在客户关注
+)
+
+type CustomerInfo struct {
+	Name       string `json:"name"`
+	Province   string `json:"province"`
+	Buyerclass string `json:"buyerclass"`
+	Followdate string `json:"followdate"`
+}
+
+//是否关注此企业客户
+func (this *CustomerOperation) CheckIsFollow() bool {
+	return db.Mgo.Count(fc, map[string]interface{}{
+		"userId": this.UserId,
+		"name":   this.Name,
+	}) > 0
+}
+
+//不是我的客户
+func (this *CustomerOperation) Exclude() (B bool) {
+	timeNow := time.Now()
+	updateMap := map[string]interface{}{
+		"$set": map[string]interface{}{
+			"date":     timeNow.Unix(),
+			"userId":   this.UserId,
+			"name":     this.Name,
+			"province": this.Province,
+			"city":     this.City,
+		},
+	}
+	B = db.Mgo.Update(ec, map[string]interface{}{
+		"userId": this.UserId,
+		"name":   this.Name,
+	}, updateMap, true, false)
+	if B {
+		redis.Del(redisName, fmt.Sprintf(redisCRIndex, this.UserId))
+		redis.Del(redisName, fmt.Sprintf(redisExcludeKey, this.UserId))
+	}
+	return B
+}
+
+//列表
+func (this *CustomerOperation) CList(pageSize, pageNo int, keyword string) ([]*CustomerInfo, int, int) {
+	var cinfoarr = []*CustomerInfo{}
+	startPage := pageSize * (pageNo - 1)
+	entnames := []string{}
+	count, total := 0, 0
+	query := map[string]interface{}{
+		"userId": this.UserId,
+	}
+	total = redis.GetInt(redisName, fmt.Sprintf(redisCountKey, this.UserId))
+	if total < 1 {
+		total = db.Mgo.Count(fc, query)
+		redis.Put(redisName, fmt.Sprintf(redisCountKey, this.UserId), total, 2*60*60)
+	}
+	if keyword != "" {
+		query["name"] = map[string]interface{}{
+			"$regex": keyword,
+		}
+	}
+	count = db.Mgo.Count(fc, query)
+	clist, ok := db.Mgo.Find(fc, query, `{"date":-1}`, `{"name":1,"date":1}`, false, startPage, pageSize)
+	if ok && clist != nil && len(*clist) > 0 {
+		for _, v := range *clist {
+			entnames = append(entnames, v["name"].(string))
+			date := v["date"]
+			cinfoarr = append(cinfoarr, &CustomerInfo{
+				Name:       v["name"].(string),
+				Followdate: qu.FormatDateWithObj(&date, "2006/01/02"),
+			})
+		}
+	}
+	entinfolist := GetEntCusInfo(entnames)
+	if len(entinfolist) > 0 {
+	L:
+		for _, v := range entinfolist {
+			for _, ev := range cinfoarr {
+				if (*ev).Name == qu.ObjToString(v["buyer_name"]) {
+					(*ev).Province = qu.ObjToString(v["province"])
+					(*ev).Buyerclass = qu.ObjToString(v["buyerclass"])
+					continue L
+				}
+			}
+		}
+	}
+	return cinfoarr, count, total
+}
+
+//
+var pcquery = `{"query": {"bool": {"must": [{"terms": {"%s": [%s]}}],"must_not": [],"should": []}},"sort": []}`
+
+//获取企业-客户信息
+func GetEntCusInfo(entnames []string) []map[string]interface{} {
+	query := fmt.Sprintf(pcquery, "buyer_name", `"`+strings.Join(entnames, `","`)+`"`)
+	list := *elastic.Get("buyer", "buyer", query)
+	return list
+}
+
+//权限查询
+func (this *CustomerOperation) CheckPower() string {
+	msg := ""
+	if this.UserId == "" {
+		msg = "登录异常"
+	} else {
+		//查询是否是大会员
+		if userPower := jy.GetBigVipUserBaseMsg(this.UserId, db.Mysql, db.Mgo); userPower.Status > 0 {
+			count := redis.GetInt(redisName, fmt.Sprintf(redisCountKey, this.UserId))
+			if count < 1 {
+				query := map[string]interface{}{
+					"userId": this.UserId,
+				}
+				count = db.Mgo.Count(fc, query)
+			}
+			if count >= userPower.Customers {
+				msg = fmt.Sprintf("对不起,您最多可关注%d个客户", userPower.Customers)
+			}
+		} else {
+			msg = "暂无关注客户权限"
+		}
+	}
+	return msg
+}
+
+//
+func (this *CustomerOperation) Coperation() (B bool) {
+	queryMap := map[string]interface{}{
+		"userId": this.UserId,
+		"name":   this.Name,
+	}
+	//取关
+	if this.B {
+		B = db.Mgo.Del(fc, queryMap)
+	} else {
+		timeNow := time.Now()
+		updateMap := map[string]interface{}{
+			"$set": map[string]interface{}{
+				"date":     timeNow.Unix(),
+				"userId":   this.UserId,
+				"name":     this.Name,
+				"province": this.Province,
+				"city":     this.City,
+			},
+		}
+		B = db.Mgo.Update(fc, queryMap, updateMap, true, false)
+	}
+	redis.Del(redisName, fmt.Sprintf(redisCountKey, this.UserId))
+	if B {
+		go func(userId string) {
+			//首页潜在客户缓存
+			redis.Del(redisName, fmt.Sprintf(redisCRIndex, this.UserId))
+			//更新redis 客户数据
+			clist, ok := db.Mgo.Find(fc, map[string]interface{}{
+				"userId": userId,
+			}, nil, `{"name":1}`, false, -1, -1)
+			// fmt.Println(clist)
+			if ok && clist != nil && len(*clist) > 0 {
+				names := []string{}
+				for _, v := range *clist {
+					names = append(names, v["name"].(string))
+				}
+				if len(names) > 0 {
+					redis.Put(redisName, fmt.Sprintf(redisListKey, userId), strings.Join(names, ","), 2*60*60)
+				}
+			}
+		}(this.UserId)
+	}
+	return B
+}

+ 11 - 0
src/jfw/modules/publicapply/src/customer/init.go

@@ -0,0 +1,11 @@
+package customer
+
+import (
+	"customer/service"
+
+	"github.com/go-xweb/xweb"
+)
+
+func init() {
+	xweb.AddAction(&service.ServiceStruct{})
+}

+ 13 - 0
src/jfw/modules/publicapply/src/customer/service/action.go

@@ -0,0 +1,13 @@
+package service
+
+import (
+	"github.com/go-xweb/xweb"
+)
+
+type ServiceStruct struct {
+	*xweb.Action
+	cstList xweb.Mapper `xweb:"/customer/list"`      //客户列表
+	cstAtt  xweb.Mapper `xweb:"/customer/attention"` //操作客户信息动作(关注or取关)
+	exclude xweb.Mapper `xweb:"/customer/exclude"`   //排除我的客户
+	check   xweb.Mapper `xweb:"/customer/check"`     //是否关注此企业
+}

+ 110 - 0
src/jfw/modules/publicapply/src/customer/service/service.go

@@ -0,0 +1,110 @@
+package service
+
+import (
+	. "api"
+	"customer/entity"
+	"encoding/json"
+	qu "qfw/util"
+)
+
+//是否关注此企业客户
+func (this *ServiceStruct) Check() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		if string(this.Body()) == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		cotion := entity.NewCustomerOperation()
+		//接收参数
+		json.Unmarshal(this.Body(), &cotion)
+		if cotion.Name == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		cotion.UserId = userId
+		return Result{Data: cotion.CheckIsFollow()}
+	}()
+	this.ServeJson(r)
+}
+
+//不是我的客户
+func (this *ServiceStruct) Exclude() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		if string(this.Body()) == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		cotion := entity.NewCustomerOperation()
+		//接收参数
+		json.Unmarshal(this.Body(), &cotion)
+		if cotion.Name == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		cotion.UserId = userId
+		return Result{Data: cotion.Exclude()}
+	}()
+	this.ServeJson(r)
+}
+
+//关注客户列表
+func (this *ServiceStruct) CstList() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		cotion := entity.NewCustomerOperation()
+		cotion.UserId = userId
+		pageSize, _ := this.GetInteger("pagesize")
+		pageNo, _ := this.GetInteger("pageno")
+		keyword := this.GetString("keyword")
+		if pageSize <= 0 {
+			pageSize = 20
+		}
+		if pageNo <= 0 {
+			pageNo = 1
+		}
+		res, count, total := cotion.CList(pageSize, pageNo, keyword)
+		return Result{Data: map[string]interface{}{
+			"list":  res,
+			"count": count,
+			"total": total,
+		}}
+	}()
+	this.ServeJson(r)
+}
+
+//关注or取关客户
+func (this *ServiceStruct) CstAtt() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		if string(this.Body()) == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		cotion := entity.NewCustomerOperation()
+		//接收参数
+		json.Unmarshal(this.Body(), &cotion)
+		if !cotion.B && cotion.Name == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		cotion.UserId = userId
+		msg := cotion.CheckPower()
+		if !cotion.B && msg != "" {
+			return Result{Data: false, Error_msg: msg}
+		}
+		return Result{Data: cotion.Coperation()}
+	}()
+	this.ServeJson(r)
+}

+ 3 - 0
src/jfw/modules/publicapply/src/main.go

@@ -6,6 +6,7 @@ import (
 	_ "applocation"
 	_ "bidcollection"
 	. "config"
+	_ "customer"
 	_ "dataexport"
 	_ "db"
 	_ "drainage"
@@ -14,7 +15,9 @@ import (
 	_ "free"
 	_ "me"
 	"net/http"
+	_ "project"
 	_ "subscribePush"
+	_ "userbase"
 
 	"github.com/go-xweb/xweb"
 )

+ 97 - 0
src/jfw/modules/publicapply/src/project/project.go

@@ -0,0 +1,97 @@
+package project
+
+import (
+	. "api"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"log"
+	qutil "qfw/util"
+	"qfw/util/elastic"
+	"qfw/util/redis"
+	"util"
+
+	"github.com/go-xweb/xweb"
+)
+
+type ProInfo struct {
+	*xweb.Action
+
+	history xweb.Mapper `xweb:"/project/history"`
+}
+
+func init() {
+	xweb.AddAction(&ProInfo{})
+}
+
+//
+func (this *ProInfo) History() {
+	res, err := func() (res map[string]interface{}, err error) {
+		sid := util.DecodeId(this.GetString("sid")) //获取信息id
+		//大会员查询项目信息
+		redisKey := fmt.Sprintf("project_%s", sid)
+		log.Println("redisKey:", redisKey)
+		if reidsCatche, redisErr := redis.GetBytes("other", redisKey); redisErr == nil && reidsCatche != nil {
+			errs := json.Unmarshal(*reidsCatche, &res)
+			resList, ok := res["list"].([]interface{})
+			EnCodeList := []map[string]interface{}{}
+			if len(resList) > 0 && ok {
+				for _, v := range qutil.ObjArrToMapArr(resList) {
+					EnCodeList = append(EnCodeList, map[string]interface{}{
+						"l_publishtime": v["l_publishtime"],
+						"s_title":       v["s_title"],
+						"s_toptype":     v["s_toptype"],
+						"s_subtype":     v["s_subtype"],
+						"budget":        v["budget"],
+						"bidamount":     v["bidamount"],
+						"s_id":          util.EncodeId(qutil.ObjToString(v["s_id"])),
+					})
+				}
+				res["list"] = EnCodeList
+			}
+			if errs == nil {
+				return
+			}
+			log.Printf("ProjectFollow GetProjectDetailBySid Unmarshal err %v\n", err)
+		}
+		list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"match": {"list.infoid": "`+sid+`"}}]}},"_source":["list","projectcode","projectname","bidopentime","area","city","agency","buyer","buyerperson","buyertel","bidstatus"],"from": 0,"size": 1}`)
+		if len(*list) == 0 {
+			return nil, errors.New("没有找到项目信息")
+		}
+		finalDate := (*list)[0]
+		thisList := []map[string]interface{}{}
+		tmpList, ok := finalDate["list"].([]interface{})
+		EnCodeList := []map[string]interface{}{}
+		if ok && len(tmpList) > 0 {
+			for _, v := range qutil.ObjArrToMapArr(tmpList) {
+				if len(thisList) >= 50 {
+					break
+				}
+				thisList = append(thisList, map[string]interface{}{
+					"l_publishtime": v["publishtime"],
+					"s_title":       v["title"],
+					"s_toptype":     v["toptype"],
+					"s_subtype":     v["subtype"],
+					"budget":        v["budget"],
+					"bidamount":     v["bidamount"],
+					"s_id":          qutil.ObjToString(v["infoid"]),
+				})
+				EnCodeList = append(EnCodeList, map[string]interface{}{
+					"l_publishtime": v["publishtime"],
+					"s_title":       v["title"],
+					"s_toptype":     v["toptype"],
+					"s_subtype":     v["subtype"],
+					"budget":        v["budget"],
+					"bidamount":     v["bidamount"],
+					"s_id":          util.EncodeId(qutil.ObjToString(v["infoid"])),
+				})
+			}
+		}
+		finalDate["list"] = thisList
+		//redis缓存一星期
+		redis.Put("other", redisKey, &finalDate, 60*60*24*7)
+		finalDate["list"] = EnCodeList
+		return finalDate, nil
+	}()
+	this.ServeJson(NewResult(map[string]interface{}{"projectInfo": res}, err)) //满足前端格式
+}

+ 4 - 0
src/jfw/modules/publicapply/src/subscribePush/service/pushList.go

@@ -219,6 +219,9 @@ func (sp *SubscribePush) HistoryPaging() {
 	hasNextPage, total, list := jy.NewSubscribePush(vipType).Datas(spqp)
 	//查询是否收藏
 	jy.NewSubscribePush().MakeCollection(userId, db.Mysql, list)
+	//是否有关键词
+	user, _ := jy.NewSubscribePush(vipType).UserInfo(db.Mgo, userId)
+	hasKeyFlag, _ := me.GetKeySet(vipType, user)
 	//仅表格第一页展示全部字段
 	if !(sp.GetString("format") == "table" && pageNum == 1 && PageSize <= 20) && len(list) > 0 {
 		for i := 0; i < len(list); i++ {
@@ -232,6 +235,7 @@ func (sp *SubscribePush) HistoryPaging() {
 		"hasNextPage": hasNextPage,
 		"total":       total,
 		"data":        list,
+		"haskey":      hasKeyFlag,
 	})
 }
 

+ 142 - 0
src/jfw/modules/publicapply/src/userbase/bigmembermenu.json

@@ -0,0 +1,142 @@
+[
+	{
+		"firstlevel":"我的订阅",
+		"secondarylevel":[
+			{
+				"name":"订阅信息",
+				"url":"/swordfish/page_big_pc/big_subscribe",
+				"isusable":true
+			},
+			{
+				"name":"订阅管理",
+				"url":"/swordfish/page_big_pc/set_subscribe/config",
+				"isusable":false
+			}
+		]
+	},
+	{
+		"firstlevel":"我的关注",
+		"secondarylevel":[
+			{
+				"name":"项目关注",
+				"url":"/swordfish/page_big_pc/free/project_progress",
+				"isusable":true
+			},
+			{
+				"name":"企业关注",
+				"url":"/swordfish/page_big_pc/free/ent_follow",
+				"isusable":true
+			},
+			{
+				"name":"客户关注",
+				"url":"/swordfish/page_big_pc/my_client",
+				"isusable":false
+			}
+		]
+	},
+	{
+		"firstlevel":"我的收藏",
+		"secondarylevel":[
+			{
+				"name":"文库收藏",
+				"url":"/swordfish/docs/user/collections",
+				"isusable":true
+			},
+			{
+				"name":"标讯收藏",
+				"url":"/swordfish/frontPage/collection/sess/index",
+				"isusable":true
+			}
+		]
+	},
+	{
+		"firstlevel":"会员服务",
+		"secondarylevel":[
+			{
+				"name":"企业情报监控",
+				"url":"/swordfish/page_big_pc/free/ent_follow",
+				"isusable":true
+			},
+			{
+				"name":"中标企业预测",
+				"url":"/swordfish/page_big_pc/ai_search",
+				"isusable":false
+			},
+			{
+				"name":"投标决策分析",
+				"url":"/swordfish/page_big_pc/analysis_search",
+				"isusable":false
+			},
+			{
+				"name":"潜在项目预测",
+				"url":"/swordfish/page_big_pc/forecast_list",
+				"isusable":false
+			},
+			{
+				"name":"潜在客户挖掘",
+				"url":"/swordfish/page_big_pc/potential_cor_list/c",
+				"isusable":false
+			},
+			{
+				"name":"潜在竞争对手/合作伙伴挖掘",
+				"url":"/swordfish/page_big_pc/potential_rival_list/r",
+				"isusable":false
+			},
+			{
+				"name":"周报",
+				"url":"/swordfish/page_big_pc/bigvip_subreport_week",
+				"isusable":false
+			},
+			{
+				"name":"月报",
+				"url":"/swordfish/page_big_pc/bigvip_subreport_month",
+				"isusable":false
+			},
+			{
+				"name":"招标文件解读",
+				"url":"/bid/pc/page/bidfile_landpage",
+				"isusable":true
+			}
+		]
+	},
+	{
+		"firstlevel":"我的资产",
+		"secondarylevel":[
+			{
+				"name":"数据导出记录",
+				"url":"/front/dataPack/index?type=history",
+				"isusable":true
+			},
+			{
+				"name":"数据流量包",
+				"url":"/front/dataPack/index",
+				"isusable":true
+			},
+			{
+				"name":"剑鱼币",
+				"url":"/swordfish/integral/index",
+				"isusable":true
+			},
+			{
+				"name":"优惠券",
+				"url":"/swordfish/coupon/",
+				"isusable":true
+			},
+			{
+				"name":"我的文库",
+				"url":"/swordfish/docs/user/docs",
+				"isusable":true
+			}
+		]
+	},
+	{
+		"firstlevel":"交易管理",
+		"secondarylevel":[
+			{
+				"name":"我的订单",
+				"url":"/front/swordfish/toMyOrder",
+				"isusable":true
+			}
+		]
+	}
+]

+ 195 - 0
src/jfw/modules/publicapply/src/userbase/commonfunctions.json

@@ -0,0 +1,195 @@
+{
+	"cfcollotion":"commonfunctions",
+	"total":8,
+	"commonFunctions":[
+		{
+			"name":"招标搜索",
+			"charge":false,
+			"isbase":true,
+			"pc":{
+				"url":"/jylab/supsearch/index.html?publishtime=thisyear",
+				"img":"/commonFunctions/pc_search.png"
+			}
+		},
+		{
+			"name":"标讯收藏",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/frontPage/collection/sess/index",
+				"img":"/commonFunctions/pc_collection.png"
+			}
+		},
+		{
+			"name":"项目关注",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/page_big_pc/free/project_progress",
+				"img":"/commonFunctions/pc_follow_project.png"
+			}
+		},
+		{
+			"name":"企业搜索",
+			"charge":false,
+			"isbase":true,
+			"pc":{
+				"url":"/jylab/entSearch/index.html",
+				"img":"/commonFunctions/pc_entsearch.png"
+			}
+		},
+		{
+			"name":"企业情报监控",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/page_big_pc/free/ent_follow",
+				"img":"/commonFunctions/pc_ent_follow.png"
+			}
+		},
+		{
+			"name":"订阅信息",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/page_big_pc/big_subscribe",
+				"img":"/commonFunctions/pc_subscribe_info.png"
+			}
+		},
+		{
+			"name":"订阅管理",
+			"charge":false,
+			"isbase":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/set_subscribe/config",
+				"img":"/commonFunctions/pc_subscribe_manage.png"
+			}
+		},
+		{
+			"name":"数据自助导出",
+			"charge":false,
+			"isbase":true,
+			"pc":{
+				"url":"/front/dataExport/toSieve",
+				"img":"/commonFunctions/pc_dataExport_index.png"
+			}
+		},
+		{
+			"name":"数据导出记录",
+			"charge":false,
+			"isbase":true,
+			"pc":{
+				"url":"/front/dataPack/index?type=history",
+				"img":"/commonFunctions/pc_dataPack_history.png"
+			}
+		},
+		{
+			"name":"数据流量包",
+			"charge":false,
+			"pc":{
+				"url":"/front/dataPack/index",
+				"img":"/commonFunctions/pc_dataPack_me.png"
+			}
+		},
+		{
+			"name":"潜在客户挖掘",
+			"charge":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/potential_cor_list/c",
+				"img":"/commonFunctions/pc_potential_c.png"
+			}
+		},
+		{
+			"name":"潜在竞争对手/合作伙伴挖掘",
+			"charge":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/potential_rival_list/r",
+				"img":"/commonFunctions/pc_potential_r.png"
+			}
+		},
+		{
+			"name":"中标企业预测",
+			"charge":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/ai_search",
+				"img":"/commonFunctions/pc_ai_search.png"
+			}
+		},
+		{
+			"name":"投标决策分析",
+			"charge":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/analysis_search",
+				"img":"/commonFunctions/pc_analysis_search.png"
+			}
+		},
+		{
+			"name":"潜在项目预测",
+			"charge":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/forecast_list",
+				"img":"/commonFunctions/pc_forecast_list.png"
+			}
+		},
+		{
+			"name":"周报",
+			"charge":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/bigvip_subreport_week",
+				"img":"/commonFunctions/pc_subreport_week.png"
+			}
+		},
+		{
+			"name":"月报",
+			"charge":true,
+			"pc":{
+				"url":"/swordfish/page_big_pc/bigvip_subreport_month",
+				"img":"/commonFunctions/pc_subreport_month.png"
+			}
+		},
+		{
+			"name":"招标文件解读",
+			"charge":false,
+			"pc":{
+				"url":"/bid/pc/page/bidfile_landpage",
+				"img":"/commonFunctions/pc_bidfile_landpage.png"
+			}
+		},
+		{
+			"name":"我的订单",
+			"charge":false,
+			"pc":{
+				"url":"/front/swordfish/toMyOrder",
+				"img":"/commonFunctions/pc_myorder.png"
+			}
+		},
+		{
+			"name":"剑鱼币",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/integral/index",
+				"img":"/commonFunctions/pc_integral.png"
+			}
+		},
+		{
+			"name":"文库收藏",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/docs/user/collections",
+				"img":"/commonFunctions/pc_docs_collections.png"
+			}
+		},
+		{
+			"name":"我的文库",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/docs/user/docs",
+				"img":"/commonFunctions/pc_mydocs.png"
+			}
+		},
+		{
+			"name":"优惠券",
+			"charge":false,
+			"pc":{
+				"url":"/swordfish/coupon/",
+				"img":"/commonFunctions/pc_mycoupon.png"
+			}
+		}
+	]
+}

+ 175 - 0
src/jfw/modules/publicapply/src/userbase/entity/entity.go

@@ -0,0 +1,175 @@
+package entity
+
+import (
+	"db"
+	"qfw/util"
+	"qfw/util/jy"
+	"strings"
+	"time"
+	"userbase/initjson"
+	. "userbase/initjson"
+)
+
+type UserInfo struct {
+	UserId   string //用户id
+	Platform string //平台 PC WX APP
+	Names    string //功能名称
+}
+
+type FuncNames struct {
+	Name string `json:"name"`
+	Url  string `json:"url"`
+	Img  string `json:"img"`
+}
+
+func NewUserInfo(userId, platform, names string) *UserInfo {
+	if platform == "" {
+		platform = "PC"
+	}
+	return &UserInfo{userId, platform, names}
+}
+
+//保存
+func (this *UserInfo) SaveNameByUserId() bool {
+	queryMap := map[string]interface{}{
+		"s_userId":   this.UserId,
+		"s_platform": this.Platform,
+	}
+	var namesarr = []string{}
+	if this.Names != "" {
+		for _, v := range strings.Split(this.Names, ",") {
+			if !ChargeMap[v] || IsPower(v, this.UserId) {
+				namesarr = append(namesarr, v)
+			}
+		}
+	}
+	updateMap := map[string]interface{}{
+		"$set": map[string]interface{}{
+			"l_createtime": time.Now().Unix(),
+			"s_userId":     this.UserId,
+			"s_names":      strings.Join(namesarr, ","),
+			"s_platform":   this.Platform,
+		},
+	}
+	return db.Mgo.Update(BaseFuncInfo.Cfcollotion, queryMap, updateMap, true, false)
+}
+
+//获取用户已选功能或基本功能
+func (this *UserInfo) GetNameByUserId() (fns []*FuncNames) {
+	queryMap := map[string]interface{}{
+		"s_userId":   this.UserId,
+		"s_platform": this.Platform,
+	}
+	res, ok := db.Mgo.FindOne(BaseFuncInfo.Cfcollotion, queryMap)
+	if ok && len(*res) > 0 {
+		names := util.ObjToString((*res)["s_names"])
+		if names != "" {
+		L:
+			for _, nv := range strings.Split(names, ",") {
+				if len(fns) >= BaseFuncInfo.Total {
+					break
+				}
+				for _, v := range BaseFuncInfo.CommonFunctions {
+					if v.Name == nv {
+						fns = append(fns, &FuncNames{
+							Name: v.Name,
+							Url:  thisByPlat(this.Platform, "url", &v),
+							Img:  thisByPlat(this.Platform, "img", &v),
+						})
+						continue L
+					}
+				}
+			}
+		}
+	} else {
+		for _, v := range BaseFuncInfo.CommonFunctions {
+			if v.Isbase {
+				if v.Name == "订阅管理" && !IsPower(v.Name, this.UserId) {
+					continue
+				}
+				fns = append(fns, &FuncNames{
+					Name: v.Name,
+					Url:  thisByPlat(this.Platform, "url", &v),
+					Img:  thisByPlat(this.Platform, "img", &v),
+				})
+			}
+			if len(fns) >= BaseFuncInfo.Total {
+				break
+			}
+		}
+	}
+	return fns
+}
+
+var ChargeMap = map[string]bool{}
+
+//获取所有用户可用功能
+func (this *UserInfo) AllNames() (fns []*FuncNames) {
+	for _, v := range BaseFuncInfo.CommonFunctions {
+		ChargeMap[v.Name] = v.Charge
+		if !v.Charge || IsPower(v.Name, this.UserId) {
+			fns = append(fns, &FuncNames{
+				Name: v.Name,
+				Url:  thisByPlat(this.Platform, "url", &v),
+				Img:  thisByPlat(this.Platform, "img", &v),
+			})
+		}
+	}
+	return fns
+}
+
+//
+func thisByPlat(platform, name string, bcv *initjson.BaseFunc) (res string) {
+	switch platform {
+	case "APP":
+		switch name {
+		case "url":
+			res = bcv.APP.Url
+		case "img":
+			res = bcv.APP.Img
+		}
+	case "WX":
+		switch name {
+		case "url":
+			res = bcv.WX.Url
+		case "img":
+			res = bcv.WX.Img
+		}
+	default:
+		switch name {
+		case "url":
+			res = bcv.PC.Url
+		case "img":
+			res = bcv.PC.Img
+		}
+	}
+	return
+}
+
+//查看是否有使用此功能的权限
+func IsPower(name, userId string) (b bool) {
+	BigPower := jy.GetBigVipUserBaseMsg(userId, db.Mysql, db.Mgo)
+	if BigPower.Status > 0 {
+		switch name {
+		case "企业情报监控":
+			b = BigPower.PowerMap[4] || BigPower.PowerMap[12] || BigPower.PowerMap[13]
+		case "潜在客户挖掘", "客户关注":
+			b = BigPower.PowerMap[7]
+		case "潜在竞争对手/合作伙伴挖掘":
+			b = BigPower.PowerMap[8]
+		case "中标企业预测":
+			b = BigPower.PowerMap[15]
+		case "投标决策分析":
+			b = BigPower.PowerMap[6]
+		case "潜在项目预测":
+			b = BigPower.PowerMap[9]
+		case "周报", "月报":
+			b = BigPower.PowerMap[10]
+		case "订阅管理":
+			b = util.If(BigPower.Pid == "", true, false).(bool)
+		default:
+			b = true
+		}
+	}
+	return b
+}

+ 43 - 0
src/jfw/modules/publicapply/src/userbase/entity/menu.go

@@ -0,0 +1,43 @@
+package entity
+
+import (
+	"userbase/initjson"
+)
+
+type MenuInfoStruct struct {
+	UserId string `json:"userId"`
+}
+
+func NewMenuInfo(userId string) *MenuInfoStruct {
+	return &MenuInfoStruct{userId}
+}
+
+//大会员菜单
+func (this *MenuInfoStruct) GetMenuInfo() (menus []*initjson.MenuLevel) {
+	for _, v := range initjson.MenuMap {
+		mll := &initjson.MenuLevel{}
+		mll.Firstlevel = v.Firstlevel
+		mll.Secondarylevel = []*initjson.MenuInfo{}
+		for _, mv := range v.Secondarylevel {
+			msll := &initjson.MenuInfo{
+				Name:     mv.Name,
+				Url:      mv.Url,
+				Isusable: mv.Isusable,
+			}
+			if !msll.Isusable {
+				if IsPower(msll.Name, this.UserId) {
+					msll.Isusable = true
+				} else {
+					//子账号 隐藏订阅管理
+					if msll.Name == "订阅管理" {
+						continue
+					}
+					msll.Url = ""
+				}
+			}
+			mll.Secondarylevel = append(mll.Secondarylevel, msll)
+		}
+		menus = append(menus, mll)
+	}
+	return
+}

+ 13 - 0
src/jfw/modules/publicapply/src/userbase/init.go

@@ -0,0 +1,13 @@
+//用户基础: 大会员常用功能;大会员菜单。
+package userbase
+
+import (
+	_ "userbase/initjson"
+	"userbase/service"
+
+	"github.com/go-xweb/xweb"
+)
+
+func init() {
+	xweb.AddAction(&service.ServiceStruct{})
+}

+ 47 - 0
src/jfw/modules/publicapply/src/userbase/initjson/initjson.go

@@ -0,0 +1,47 @@
+package initjson
+
+import (
+	"log"
+	"qfw/util"
+)
+
+type BaseFunc struct {
+	Name   string `json:"name"`
+	Charge bool   `json:"charge"` //是否需要验证权限
+	Isbase bool   `json:"isbase"` //是否是基本功能
+	PC     fcBaseInfo
+	WX     fcBaseInfo
+	APP    fcBaseInfo
+}
+
+type fcBaseInfo struct {
+	Url, Img string
+}
+
+type baseFuncInfo struct {
+	Cfcollotion     string     `json:"cfcollotion"`
+	Total           int        `json:"total"`
+	CommonFunctions []BaseFunc `json:"commonFunctions"`
+}
+
+var BaseFuncInfo baseFuncInfo
+
+//
+type MenuLevel struct {
+	Firstlevel     string      `json:"firstlevel"`
+	Secondarylevel []*MenuInfo `json:"secondarylevel"`
+}
+type MenuInfo struct {
+	Name     string `json:"name"`
+	Url      string `json:"url"`
+	Isusable bool   `json:"isusable"` //是否可用
+}
+
+var MenuMap []*MenuLevel
+
+func init() {
+	log.Println("初始化 常用功能配置")
+	util.ReadConfig("./userbase/commonfunctions.json", &BaseFuncInfo)
+	log.Println("初始化 大会员菜单配置")
+	util.ReadConfig("./userbase/bigmembermenu.json", &MenuMap)
+}

+ 13 - 0
src/jfw/modules/publicapply/src/userbase/service/action.go

@@ -0,0 +1,13 @@
+package service
+
+import (
+	"github.com/go-xweb/xweb"
+)
+
+type ServiceStruct struct {
+	*xweb.Action
+	ubFunctions   xweb.Mapper `xweb:"/userbase/functions"`     //获取用户常用功能
+	saveFunctions xweb.Mapper `xweb:"/userbase/saveFunctions"` //保存用户常用功能
+	allFunctions  xweb.Mapper `xweb:"/userbase/allFunctions"`  //获取所有用户可用功能
+	bigmemberMenu xweb.Mapper `xweb:"/userbase/bigmemberMenu"` //大会员菜单
+}

+ 78 - 0
src/jfw/modules/publicapply/src/userbase/service/service.go

@@ -0,0 +1,78 @@
+package service
+
+import (
+	. "api"
+	qu "qfw/util"
+	"userbase/entity"
+)
+
+//大会员菜单
+func (this *ServiceStruct) BigmemberMenu() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		if !entity.IsPower("", userId) {
+			return Result{Data: nil, Error_msg: Error_msg_1004}
+		}
+		newMenu := entity.NewMenuInfo(userId)
+		return Result{Data: newMenu.GetMenuInfo()}
+	}()
+	this.ServeJson(r)
+}
+
+//
+func (this *ServiceStruct) AllFunctions() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		if !entity.IsPower("", userId) {
+			return Result{Data: nil, Error_msg: Error_msg_1004}
+		}
+		newFN := entity.NewUserInfo(userId, "", "")
+		return Result{Data: newFN.AllNames()}
+	}()
+	this.ServeJson(r)
+}
+
+//保存用户常用功能
+func (this *ServiceStruct) SaveFunctions() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		names := this.GetString("names")
+		if !entity.IsPower("", userId) {
+			return Result{Data: nil, Error_msg: Error_msg_1004}
+		}
+		platform := this.GetString("platform")
+		newFN := entity.NewUserInfo(userId, platform, names)
+		return Result{Data: newFN.SaveNameByUserId()}
+	}()
+	this.ServeJson(r)
+}
+
+//获取用户常用功能
+func (this *ServiceStruct) UbFunctions() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qu.Catch()
+	r := func() Result {
+		if this.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		if !entity.IsPower("", userId) {
+			return Result{Data: nil, Error_msg: Error_msg_1004}
+		}
+		platform := this.GetString("platform")
+		newFN := entity.NewUserInfo(userId, platform, "")
+		return Result{Data: newFN.GetNameByUserId()}
+	}()
+	this.ServeJson(r)
+}

+ 1 - 0
src/jfw/modules/subscribepay/src/config/config.go

@@ -139,6 +139,7 @@ type memberConfig struct {
 		Trial_bidfile     int //大会员试用用户文件解读次数
 		Formal_enterprise int //大会员正式用户企业情报和监控功能企业数量
 		Formal_project    int //大会员正式用户关注项目数量
+		Formal_customer   int //大会员正式用户关注客户数量
 	}
 	AiForecastPack float64 //AI预测包价格
 }

+ 2 - 0
src/jfw/modules/subscribepay/src/entity/member.go

@@ -120,6 +120,8 @@ func normal_member(level int, enddate time.Time, userId string) {
 					frequency = config.MemberConfig.Power.Formal_enterprise
 				case "14": //项目进度监控 默认关注项目数量
 					frequency = config.MemberConfig.Power.Formal_project
+				case "7": //潜在客户 默认关注客户数量
+					frequency = config.MemberConfig.Power.Formal_customer
 				}
 			}
 			if util.Mysql.CountBySql(`select count(*) from `+jy.BigmemberUserPowerTable+` where s_userid=? and s_serviceid=?`, userId, v) == 0 {

+ 2 - 1
src/jfw/modules/subscribepay/src/member.json

@@ -12,7 +12,8 @@
 		"trial_potential":5,
 		"trial_bidfile":1,
 		"formal_enterprise":500,
-		"formal_project":500
+		"formal_project":500,
+		"formal_customer":500
 	},
 	"aiForecastPack":20000
 }

+ 49 - 5
src/jfw/modules/subscribepay/src/report/report.go

@@ -32,6 +32,7 @@ var (
 //vip订阅报告
 type Report struct {
 	*xweb.Action
+	newest    xweb.Mapper `xweb:"/report/newest"`
 	index     xweb.Mapper `xweb:"/report/index"`
 	detail    xweb.Mapper `xweb:"/report/detail"`
 	tip       xweb.Mapper `xweb:"/report/tip"`
@@ -40,12 +41,55 @@ type Report struct {
 	starttime xweb.Mapper `xweb:"/report/starttime"`
 }
 
+func (r *Report) Newest() {
+	userId, _ := r.GetSession("userId").(string)
+	t := r.GetString("type")
+	coll := getColl("", t, false)
+	weeks, _ := util.MQFW.Find(coll, map[string]interface{}{
+		"userid": userId,
+		"type":   2,
+	}, `{"startdate":-1}`, `{"startdate":1,"enddate":1,"type":1,"pushcount":1,"pushtime":1,"unread":1}`, false, 0, 1)
+	result_weeks := []map[string]interface{}{}
+	if weeks != nil {
+		for _, v := range *weeks {
+			result_weeks = append(result_weeks, map[string]interface{}{
+				"pushtime":  v["pushtime"],
+				"pushcount": v["pushcount"],
+				"unread":    qutil.IntAll(v["unread"]),
+				"startdate": v["startdate"],
+				"enddate":   v["enddate"],
+			})
+		}
+	}
+	months, _ := util.MQFW.Find(coll, map[string]interface{}{
+		"userid": userId,
+		"type":   3,
+	}, `{"startdate":-1}`, `{"startdate":1,"enddate":1,"type":1,"pushcount":1,"pushtime":1,"unread":1}`, false, 0, 1)
+	result_months := []map[string]interface{}{}
+	if months != nil {
+		for _, v := range *months {
+			result_months = append(result_months, map[string]interface{}{
+				"pushtime":  v["pushtime"],
+				"pushcount": v["pushcount"],
+				"unread":    qutil.IntAll(v["unread"]),
+				"startdate": v["startdate"],
+				"enddate":   v["enddate"],
+			})
+		}
+	}
+	r.ServeJson(map[string]interface{}{
+		"weeks":  result_weeks,
+		"months": result_months,
+	})
+}
+
+//
 func (r *Report) Index() {
 	ym, _ := r.GetInteger("ym")
 	result := map[string]interface{}{}
 	userId, _ := r.GetSession("userId").(string)
 	t := r.GetString("type")
-	list, ok := util.MQFW.Find(getColl(userId, r.Header("referer"), t, true), map[string]interface{}{
+	list, ok := util.MQFW.Find(getColl(r.Header("referer"), t, true), map[string]interface{}{
 		"userid": userId,
 		"dateym": ym,
 		"type": map[string]interface{}{
@@ -361,7 +405,7 @@ func formatInfo(ri interface{}) []map[string]interface{} {
 
 func (r *Report) Tip() {
 	userId, _ := r.GetSession("userId").(string)
-	coll := getColl(userId, "", r.GetString("type"), false)
+	coll := getColl("", r.GetString("type"), false)
 	unread := util.MQFW.Count(coll, map[string]interface{}{
 		"userid": userId,
 		"unread": 1,
@@ -380,7 +424,7 @@ func (r *Report) Tip() {
 }
 func (r *Report) Tipover() {
 	userId, _ := r.GetSession("userId").(string)
-	coll := getColl(userId, "", r.GetString("type"), false)
+	coll := getColl("", r.GetString("type"), false)
 	r.ServeJson(map[string]interface{}{"flag": tipover(userId, coll)})
 }
 
@@ -403,7 +447,7 @@ func (r *Report) Wxtplmsg() error {
 
 func (r *Report) Starttime() {
 	userId, _ := r.GetSession("userId").(string)
-	list, _ := util.MQFW.Find(getColl(userId, r.Header("referer"), r.GetString("type"), true), map[string]interface{}{
+	list, _ := util.MQFW.Find(getColl(r.Header("referer"), r.GetString("type"), true), map[string]interface{}{
 		"userid": userId,
 		"type": map[string]interface{}{
 			"$in": []int{2, 3},
@@ -420,7 +464,7 @@ func (r *Report) Starttime() {
 }
 
 //
-func getColl(userId, referer, t string, flag bool) string {
+func getColl(referer, t string, flag bool) string {
 	if t == "free" {
 		return "pushspace_experience_member_statistic"
 	} else if t == "member" {

+ 2 - 0
src/jfw/modules/weixin/src/wx/wx.go

@@ -834,6 +834,7 @@ func Subscribe(w ResponseWriter, r *Request) {
 					data["s_openid"] = openid
 					data["i_ispush"] = 1
 					data["l_createtime"] = time.Now().Unix()
+					data["l_lastpushtime"] = time.Now().Unix()
 					data["s_id"] = s_id
 					if followId := tools.MQFW.Save("jylab_followent", data); len(followId) > 0 {
 						pchints := config.Sysconfig["company"].(map[string]interface{})
@@ -1306,6 +1307,7 @@ func ScanHandler(w ResponseWriter, r *Request) {
 						data["s_openid"] = openid
 						data["i_ispush"] = 1
 						data["l_createtime"] = time.Now().Unix()
+						data["l_lastpushtime"] = time.Now().Unix()
 						data["s_id"] = s_id
 						if followId := tools.MQFW.Save("jylab_followent", data); len(followId) > 0 {
 							pchints := config.Sysconfig["company"].(map[string]interface{})

二進制
src/web/staticres/big-member/image/customer/customer-wx.png


二進制
src/web/staticres/commonFunctions/pc_ai_search.png


二進制
src/web/staticres/commonFunctions/pc_analysis_search.png


二進制
src/web/staticres/commonFunctions/pc_bidfile_landpage.png


二進制
src/web/staticres/commonFunctions/pc_collection.png


二進制
src/web/staticres/commonFunctions/pc_dataExport_index.png


二進制
src/web/staticres/commonFunctions/pc_dataPack_history.png


二進制
src/web/staticres/commonFunctions/pc_dataPack_me.png


二進制
src/web/staticres/commonFunctions/pc_docs_collections.png


二進制
src/web/staticres/commonFunctions/pc_ent_follow.png


二進制
src/web/staticres/commonFunctions/pc_entsearch.png


二進制
src/web/staticres/commonFunctions/pc_follow_project.png


二進制
src/web/staticres/commonFunctions/pc_forecast_list.png


二進制
src/web/staticres/commonFunctions/pc_integral.png


二進制
src/web/staticres/commonFunctions/pc_mycoupon.png


二進制
src/web/staticres/commonFunctions/pc_mydocs.png


二進制
src/web/staticres/commonFunctions/pc_myorder.png


二進制
src/web/staticres/commonFunctions/pc_potential_c.png


二進制
src/web/staticres/commonFunctions/pc_potential_r.png


二進制
src/web/staticres/commonFunctions/pc_search.png


二進制
src/web/staticres/commonFunctions/pc_subreport_month.png


二進制
src/web/staticres/commonFunctions/pc_subreport_week.png


二進制
src/web/staticres/commonFunctions/pc_subscribe_info.png


二進制
src/web/staticres/commonFunctions/pc_subscribe_manage.png


+ 1 - 1
src/web/staticres/css/follow.css

@@ -63,7 +63,7 @@ top:17px;
 .listpage .tip{
 	font-size: 14px;
 	padding: 5px 20px;
-	margin-bottom:170px;
+	margin-bottom:70px;
 }
 .listpage .tip img{
 	margin-right: 10px;

+ 9 - 1
src/web/templates/common/pchead.html

@@ -370,6 +370,9 @@
     .public-nav .iner .jynav li .navDX>a{
         display: initial;
     }
+    #public-nav .useronline{
+      height: 50px;
+    }
 </style>
 <style type="text/css">
     @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
@@ -862,7 +865,12 @@ $("body").click(function(event){
 	}
 })
 $(function(){
-	commonMouseEvent();
+  commonMouseEvent();
+  $('.useronline').on('mouseover',function(){
+    $(".infoList").show();
+	}).mouseout(function(){
+    $(".infoList").hide();
+	})
 })
 function commonMouseEvent(){
 	$('.exitDiv,.myorderDiv').on('mouseover',function(){

+ 17 - 12
src/web/templates/pc/biddetail_rec.html

@@ -2672,9 +2672,11 @@ function companyAdd(){
 							+'</div></div>');
 	}
 	$("#hst").hover(function(){
-		thishtlists();
-		hstShowFlag = true;
-		$(".animathistory").fadeIn(1000);
+    setTimeout(function(){
+  		thishtlists();
+  		hstShowFlag = true;
+  		$(".animathistory").fadeIn(1000);
+  },1000);
 	},function(){
 		hstShowFlag = false;
 		setTimeout(function(){
@@ -2803,16 +2805,19 @@ var thishtlists = function(){
 	if (thishtlists_hasLoad){
 		return
 	}
+  thishtlists_hasLoad=true;
 	var _id = {{.T.obj._id}};
 	var projectname = projectName;
 	var projectcode = {{.T.obj.projectcode}};
-	$.post("/front/pcAllNotice",{id:_id,projectname:projectname,projectcode:projectcode},function(D){
-		thishtlists_hasLoad=true;
-		var htdata = D.data["res"]
+	$.post("/publicapply/project/history",{sid:_id},function(D){
+    var htdata = [];
+    if ( D.data.projectInfo){
+		 htdata = D.data.projectInfo["list"]
+    }
 		if(htdata&&htdata.length>0){
-			var htlist = D.data["res"];
+			var htlist = D.data.projectInfo["list"].reverse();
 			var hthtml = '';
-			var myflag = true;
+			var myflag = false;
 			for(var i in htlist){
 				var listone = htlist[i]
 				var httime = listone["l_publishtime"];
@@ -2843,8 +2848,8 @@ var thishtlists = function(){
 						hthtml += '<span class="type">'+httype+'</span>'
 					}
 						hthtml += '</div><div class="timeaxis"><span></span></div>'
-					if(typeof(listone["s_eid"])!=""){
-						hthtml += '<div><a target="_blank" href="/article/content/'+listone["s_eid"]+'.html">'
+					if(typeof(listone["s_id"])!=""){
+						hthtml += '<div><a target="_blank" href="/article/content/'+listone["s_id"]+'.html">'
 					}else{
 						hthtml += '<div><a target="_blank" href="#">'
 					}
@@ -2904,8 +2909,8 @@ var thishtlists = function(){
 						hthtml += '<span class="type">'+httype+'</span>'
 					}
 						hthtml += '</div><div class="timeaxis"><span></span></div>'
-					if(typeof(listone["s_eid"])!=""){
-						hthtml += '<div><a target="_blank" href="/article/content/'+listone["s_eid"]+'.html">'
+					if(typeof(listone["s_id"])!=""){
+						hthtml += '<div><a target="_blank" href="/article/content/'+listone["s_id"]+'.html">'
 					}else{
 						hthtml += '<div><a target="_blank" href="#">'
 					}

+ 1 - 1
src/web/templates/weixin/follow/list.html

@@ -242,7 +242,7 @@ $(function(){
 <body class="listpage">
 	<ul>
 	</ul>
-	<div class="divbtn"{{if .T.datas}}{{if eq (len .T.datas) 10}} disabled="disabled"{{end}}{{end}}><img class="jybtnimg" src="/images/wx/jyaddfw.png"/></div>
+<!--	<div class="divbtn"{{if .T.datas}}{{if eq (len .T.datas) 10}} disabled="disabled"{{end}}{{end}}><img class="jybtnimg" src="/images/wx/jyaddfw.png"/></div>-->
 	<div class="limit"></div>
 	<div class="tip">
 		<img src="/images/wx/jyprompt.png">剑鱼标讯提示:<front>可关注{{.T.followLimit}}个项目</front>

+ 1 - 1
src/web/templates/weixin/historypush.html

@@ -1188,7 +1188,7 @@
               }
               if (parseInt(isExpire) < 0 && parseInt(isOnTail) == -1) {
                   if (localStorage.getItem("nv_vip_" + userId) == null) {
-                      $(".nv_renew_toast").show();
+                    //   $(".nv_renew_toast").show();
                   }
               }
           } else {