liumiaomiao 3 năm trước cách đây
mục cha
commit
4f87b12210
100 tập tin đã thay đổi với 5184 bổ sung1208 xóa
  1. 1 0
      README.md
  2. 29 0
      src/jfw/front/areaPack.go
  3. 1 0
      src/jfw/front/commonPayWx.go
  4. 13 2
      src/jfw/front/front.go
  5. 2 0
      src/jfw/front/login.go
  6. 2 1
      src/jfw/front/otherAct.go
  7. 2 2
      src/jfw/front/pcIndex.go
  8. 3 2
      src/jfw/front/pchelper.go
  9. 11 4
      src/jfw/front/supsearch.go
  10. 14 9
      src/jfw/front/swordfish.go
  11. 6 0
      src/jfw/front/vipsubscribe.go
  12. 5 1
      src/jfw/front/wxkeyset.go
  13. 18 0
      src/jfw/modules/app/src/app/front/areaPack.go
  14. 3 1
      src/jfw/modules/app/src/app/front/commonPay.go
  15. 12 2
      src/jfw/modules/app/src/app/front/front.go
  16. 13 7
      src/jfw/modules/app/src/app/front/login.go
  17. 7 3
      src/jfw/modules/app/src/app/front/swordfish.go
  18. 4 0
      src/jfw/modules/app/src/app/front/vipsubscribe.go
  19. 7 0
      src/jfw/modules/app/src/app/front/wxkeyset.go
  20. 90 15
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/analysis_result.css
  21. 37 2
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_portrait.css
  22. 54 10
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/unit_portrayal.css
  23. 233 42
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/analysis_result.js
  24. 148 50
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js
  25. 32 11
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/set_area.js
  26. 157 59
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js
  27. 5 4
      src/jfw/modules/app/src/web/staticres/jyapp/css/searchindex.css
  28. 5 2
      src/jfw/modules/app/src/web/staticres/jyapp/css/subscribe.css
  29. 32 0
      src/jfw/modules/app/src/web/staticres/jyapp/js/historypush.js
  30. 175 55
      src/jfw/modules/app/src/web/staticres/jyapp/js/searchindex.js
  31. 11 3
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyWord.css
  32. 16 3
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyword-common.css
  33. 3 0
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/subscribe_list.css
  34. 66 0
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_purchase.css
  35. BIN
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/image/gotolevelup.png
  36. BIN
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/image/help-icon.png
  37. 30 2
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/change_industry.js
  38. 54 19
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyWord.js
  39. 36 3
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyset-list.js
  40. 45 9
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyword-info.js
  41. 100 24
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_index_new.js
  42. 10 6
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_order_detail.js
  43. 25 18
      src/jfw/modules/app/src/web/staticres/jyapp/wxtsguide/main.js
  44. 129 0
      src/jfw/modules/app/src/web/templates/areaPack/page_buy.html
  45. 54 0
      src/jfw/modules/app/src/web/templates/areaPack/page_buy_area.html
  46. 350 0
      src/jfw/modules/app/src/web/templates/areaPack/page_set_area.html
  47. 6 3
      src/jfw/modules/app/src/web/templates/big-member/component_set_area.html
  48. 2 2
      src/jfw/modules/app/src/web/templates/big-member/component_set_cate.html
  49. 1 0
      src/jfw/modules/app/src/web/templates/big-member/component_set_infotype.html
  50. 42 16
      src/jfw/modules/app/src/web/templates/big-member/page_analysis_result.html
  51. 42 25
      src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait.html
  52. 2 2
      src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait_change.html
  53. 1 2
      src/jfw/modules/app/src/web/templates/big-member/page_forecast_detail.html
  54. 7 5
      src/jfw/modules/app/src/web/templates/big-member/page_forecast_list.html
  55. 144 0
      src/jfw/modules/app/src/web/templates/big-member/page_free_buyer_project_news.html
  56. 2 2
      src/jfw/modules/app/src/web/templates/big-member/page_free_ent_project_news.html
  57. 142 0
      src/jfw/modules/app/src/web/templates/big-member/page_free_high_set.html
  58. 210 0
      src/jfw/modules/app/src/web/templates/big-member/page_free_other_project.html
  59. 48 36
      src/jfw/modules/app/src/web/templates/big-member/page_unit_portrayal.html
  60. 117 0
      src/jfw/modules/app/src/web/templates/commonPay/areaPack/orderDetail.html
  61. 6 2
      src/jfw/modules/app/src/web/templates/commonPay/checkout.html
  62. 1 1
      src/jfw/modules/app/src/web/templates/commonPay/myOrder.html
  63. 46 5
      src/jfw/modules/app/src/web/templates/commonPay/paySuccess.html
  64. 3 3
      src/jfw/modules/app/src/web/templates/vipsubscribe/commonRules.html
  65. 3 2
      src/jfw/modules/app/src/web/templates/vipsubscribe/infoWord.html
  66. 8 5
      src/jfw/modules/app/src/web/templates/vipsubscribe/keyWord.html
  67. 129 11
      src/jfw/modules/app/src/web/templates/vipsubscribe/vip_index_new.html
  68. 1 1
      src/jfw/modules/app/src/web/templates/vipsubscribe/vip_introduce.html
  69. 83 1
      src/jfw/modules/app/src/web/templates/vipsubscribe/vip_purchase.html
  70. 12 4
      src/jfw/modules/app/src/web/templates/vipsubscribe/vip_viewPage.html
  71. 182 69
      src/jfw/modules/app/src/web/templates/weixin/historypush.html
  72. 97 15
      src/jfw/modules/app/src/web/templates/weixin/search/mainSearch.html
  73. 1 1
      src/jfw/modules/app/src/web/templates/weixin/search/tabSearch.html
  74. 78 3
      src/jfw/modules/app/src/web/templates/weixin/wxkeyset/index.html
  75. 4 4
      src/jfw/modules/app/src/web/templates/weixin/wxtsguide.html
  76. 4 3
      src/jfw/modules/bigmember/src/config.json
  77. 2 1
      src/jfw/modules/bigmember/src/config/config.go
  78. 348 0
      src/jfw/modules/bigmember/src/entity/analysis.go
  79. 131 0
      src/jfw/modules/bigmember/src/entity/analysisEntName.go
  80. 14 5
      src/jfw/modules/bigmember/src/entity/followEnterprise.go
  81. 3 30
      src/jfw/modules/bigmember/src/entity/portrailUtil.go
  82. 60 59
      src/jfw/modules/bigmember/src/entity/portrait.go
  83. 0 2
      src/jfw/modules/bigmember/src/entity/portraitBuyerSearch.go
  84. 86 42
      src/jfw/modules/bigmember/src/entity/portraitWinnerSearch.go
  85. 32 35
      src/jfw/modules/bigmember/src/entity/portrait_manager.go
  86. 0 224
      src/jfw/modules/bigmember/src/entity/portrait_project.go
  87. 340 0
      src/jfw/modules/bigmember/src/entity/portrait_screen.go
  88. 37 59
      src/jfw/modules/bigmember/src/service/analysis/analysis.go
  89. 54 19
      src/jfw/modules/bigmember/src/service/analysis/decision.go
  90. 27 25
      src/jfw/modules/bigmember/src/service/analysis/esquery.go
  91. 387 14
      src/jfw/modules/bigmember/src/service/analysis/forecastproject.go
  92. 6 6
      src/jfw/modules/bigmember/src/service/analysis/forecastwinner.go
  93. 1 0
      src/jfw/modules/bigmember/src/service/analysis/util.go
  94. 6 2
      src/jfw/modules/bigmember/src/service/follow/enterprise.go
  95. 85 48
      src/jfw/modules/bigmember/src/service/portrait/memberPortraitAction.go
  96. 44 30
      src/jfw/modules/bigmember/src/service/portrait/subvipPortraitAction.go
  97. 9 0
      src/jfw/modules/bigmember/src/service/use/use.go
  98. 6 5
      src/jfw/modules/common/src/qfw/util/bidsearch/search.go
  99. 27 3
      src/jfw/modules/common/src/qfw/util/jy/bigVipPower.go
  100. 5 5
      src/jfw/modules/common/src/qfw/util/jy/switchService.go

+ 1 - 0
README.md

@@ -2,5 +2,6 @@
 微信和pc端功能
 weixin sdk https://github.com/wizjin/weixin
 web用xweb框架
+
 v4.6.2.3
 Firstdata关联广告位

+ 29 - 0
src/jfw/front/areaPack.go

@@ -0,0 +1,29 @@
+package front
+
+import (
+	"jfw/config"
+
+	"github.com/go-xweb/xweb"
+)
+
+//省份订阅包
+
+type AreaPackAction struct {
+	*xweb.Action
+	pcViewPage xweb.Mapper `xweb:"/areaPack/pc/page/(.*)"` //省份订阅包pc
+	wxViewPage xweb.Mapper `xweb:"/areaPack/wx/page/(.*)"` //省份订阅包wx
+}
+
+func init() {
+	xweb.AddAction(&AreaPackAction{})
+}
+
+func (this *AreaPackAction) PcViewPage(htmlName string) error {
+	this.T["logid"] = config.Seoconfig["bigmember"].(string)
+	return this.Render("/areaPack/pc/page_"+htmlName+".html", &this.T)
+}
+
+func (this *AreaPackAction) WxViewPage(htmlName string) error {
+	this.T["logid"] = config.Seoconfig["bigmember"].(string)
+	return this.Render("/areaPack/wx/page_"+htmlName+".html", &this.T)
+}

+ 1 - 0
src/jfw/front/commonPayWx.go

@@ -26,6 +26,7 @@ var (
 		"datareport":   []string{"数据报告"},
 		"onlineCourse": []string{"中标必听课"},
 		"dataPack":     []string{"数据流量包"},
+		"areaPack":     []string{"省份订阅包"},
 	}
 )
 

+ 13 - 2
src/jfw/front/front.go

@@ -14,6 +14,7 @@ import (
 	"net/url"
 	"qfw/util"
 	"qfw/util/elastic"
+	"qfw/util/jy"
 	"qfw/util/redis"
 	"regexp"
 	"strconv"
@@ -1041,6 +1042,7 @@ func (f *Front) TSGuide() error {
 		return f.Render("/weixin/wxtsguide.html")
 	} else {
 		reqType := f.GetString("reqType")
+		// index, _ := f.GetInteger("index")
 		result := make(bson.M)
 		if reqType == "save" {
 			var keyMaps []map[string]interface{}
@@ -1056,7 +1058,6 @@ func (f *Front) TSGuide() error {
 					}
 					keyMaps = append(keyMaps, map[string]interface{}{
 						"key":      vs,
-						"area":     []string{area},
 						"infotype": []string{},
 						"notkey":   []string{},
 						"from":     1, //用于记录是否可以选择全国
@@ -1065,7 +1066,11 @@ func (f *Front) TSGuide() error {
 						break
 					}
 				}
+				areas := map[string]interface{}{
+					area: []string{},
+				}
 				saveData := bson.M{
+					"o_jy.o_area":       areas,
 					"o_jy.a_key":        keyMaps,
 					"o_jy.l_modifydate": time.Now().Unix(),
 					"i_ts_guide":        2,
@@ -1073,7 +1078,10 @@ func (f *Front) TSGuide() error {
 				result["flag"] = mongodb.UpdateById("user", userid, bson.M{"$set": saveData})
 			}
 		} else if reqType == "over" {
-			mongodb.UpdateById("user", userid, bson.M{"$set": bson.M{"i_ts_guide": 1}})
+			saveData := bson.M{
+				"i_ts_guide": 1,
+			}
+			result["flag"] = mongodb.UpdateById("user", userid, bson.M{"$set": saveData})
 		} else if reqType == "preview" {
 			rlt := elastic.GetByNgram(INDEX, TYPE, strings.Split(f.GetString("key"), " "), "", FINDF, `{"publishtime":-1}`, `"_id","title","publishtime","toptype","subtype","type","area","href","areaval"`, 0, 10)
 			if *rlt != nil && len(*rlt) > 0 {
@@ -1083,6 +1091,9 @@ func (f *Front) TSGuide() error {
 			}
 			result["data"] = rlt
 		}
+		if result["flag"] != nil && result["flag"].(bool) {
+			jy.ClearBigVipUserPower(userid)
+		}
 		f.ServeJson(result)
 	}
 	return nil

+ 2 - 0
src/jfw/front/login.go

@@ -115,10 +115,12 @@ func (l *Login) Login() error {
 						"s_company":     s_company,
 						"o_jy": map[string]interface{}{
 							"i_apppush":    1,
+							// "i_newfree":    1, //新免费用户=>新订阅设置页面 20211122
 							"i_ratemode":   2,
 							"l_modifydate": time.Now().Unix(),
 						},
 						"s_regsource": "pc",
+						"s_platform":  "pc",
 					}
 					source := l.GetString("source") //用户手机号用户记录百度统计
 					if ck, err := l.GetCookie("source"); err == nil && ck.Value != "" {

+ 2 - 1
src/jfw/front/otherAct.go

@@ -134,7 +134,8 @@ func (f *Front) Lpsubmit() error {
 				"l_registedate": time.Now().Unix(),
 				"i_ts_guide":    2,
 				"o_jy": map[string]interface{}{
-					"i_apppush":    1,
+					"i_apppush": 1,
+					// "i_newfree":    1, //新免费用户=>新订阅设置页面 20211122
 					"i_ratemode":   2,
 					"l_modifydate": time.Now().Unix(),
 				},

+ 2 - 2
src/jfw/front/pcIndex.go

@@ -151,7 +151,7 @@ func GetNewArticle(typ int) (list []map[string]interface{}) {
 	if l, ok := redis.Get("other", rediskey).([]interface{}); ok && l != nil && len(l) > 0 {
 		list = util.ObjArrToMapArr(l)
 	} else {
-		_, _, lists := bidsearch.GetPcBidSearchData("", "", "", subtype, "", "", "", "", "", "", "", 1, bidsearch.SearchPageSize_PC, false, nil, bidSearch_field_1, "")
+		_, _, lists := bidsearch.GetPcBidSearchData("", "", "", subtype, "", "", "", "", "", "", "", 1, bidsearch.SearchPageSize_PC, false, nil, bidSearch_field_1, "", false)
 		if lists != nil && len(*lists) > 5 {
 			*lists = (*lists)[0:6]
 			for _, v := range *lists {
@@ -415,7 +415,7 @@ func (f *PcIndex) SearchResult(at, name string) error {
 
 			} else {
 				//关键词
-				_, _, datas = bidsearch.GetPcBidSearchData(keywords, "", "", "", key_industry, "", "", "", "", "", "", 0, bidsearch.SearchPageSize_PC, false, nil, bidSearch_field_1, "")
+				_, _, datas = bidsearch.GetPcBidSearchData(keywords, "", "", "", key_industry, "", "", "", "", "", "", 0, bidsearch.SearchPageSize_PC, false, nil, bidSearch_field_1, "", false)
 				if datas != nil && len(*datas) > limitcount {
 					*datas = (*datas)[0:limitcount]
 				}

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

@@ -126,8 +126,9 @@ func (l *PcHelper) Login() error {
 							"l_registedate": time.Now().Unix(),
 							"i_ts_guide":    2,
 							"o_jy": map[string]interface{}{
-								"i_apppush":    1,
-								"i_ratemode":   2,
+								"i_apppush":  1,
+								"i_ratemode": 2,
+								// "i_newfree":    1, //新免费用户=>新订阅设置页面 20211122
 								"l_modifydate": time.Now().Unix(),
 							},
 							"s_regsource": "pchelper",

+ 11 - 4
src/jfw/front/supsearch.go

@@ -110,10 +110,10 @@ func (p *Pcsearch) ProposedProject() error {
 	var totalPage int64
 	var list *[]map[string]interface{}
 	var status = 1
+	var count int64
 	if len(s_word) > 0 {
 		status = 2
-		var count int64
-		count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, "", "", "", "", "", "", "", 0, bidsearch.SearchPageSize_PC, true, nil, bidSearch_field_1, "")
+		count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, "", "", "", "", "", "", "", 0, bidsearch.SearchPageSize_PC, true, nil, bidSearch_field_1, "", false)
 		listSize := 0
 		if list != nil {
 			listSize = len(*list)
@@ -128,6 +128,8 @@ func (p *Pcsearch) ProposedProject() error {
 	} else {
 		p.DisableHttpCache()
 		p.T["list"] = PCS_list("nijian") //Newbids("nijian")[0]
+		totalPage = 10
+		count = 500
 	}
 	if status == 2 {
 		if list != nil {
@@ -155,6 +157,7 @@ func (p *Pcsearch) ProposedProject() error {
 	p.T["publishtime"] = publishtime
 	p.T["timeslot"] = p.GetString("timeslot")
 	p.T["totalPage"] = totalPage
+	p.T["count"] = count
 	p.T["keywords"] = b_word
 	p.T["searchvalue"] = s_word
 	p.T["login"] = p.Session().Get("user")
@@ -224,7 +227,9 @@ func (p *Pcsearch) GetNewBids() error {
 	}
 
 	p.ServeJson(map[string]interface{}{
-		"list": list,
+		"list":      list,
+		"count":     500,
+		"totalPage": 10,
 	})
 	return nil
 }
@@ -295,7 +300,7 @@ func (p *Pcsearch) PcSearchIndex() error {
 	secondKWS := ""
 	if len(s_word) > 0 || len(industry) > 0 {
 		status = 2
-		count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, 0, bidsearch.SearchPageSize_PC, true, queryItems, bidSearch_field_1, notkey)
+		count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, 0, bidsearch.SearchPageSize_PC, true, queryItems, bidSearch_field_1, notkey, isPayedUser)
 		listSize := 0
 		if list != nil {
 			listSize = len(*list)
@@ -344,6 +349,7 @@ func (p *Pcsearch) PcSearchIndex() error {
 	} else {
 		p.DisableHttpCache()
 		p.T["list"] = PCS_list("") //Newbids("")[0]
+		count, totalPage = 500, 10
 	}
 	if status == 2 {
 		if list != nil {
@@ -414,6 +420,7 @@ func (p *Pcsearch) PcSearchIndex() error {
 		}
 	}
 	p.T["login"] = p.Session().Get("user")
+	log.Println("xxxx", count, totalPage)
 	p.T["count"] = count
 	p.T["totalPage"] = totalPage
 	p.T["keywords"] = b_word

+ 14 - 9
src/jfw/front/swordfish.go

@@ -153,7 +153,7 @@ func (m *Front) PcAjaxReq() {
 	if len(s_word) > 0 || len(industry) > 0 {
 		if reqType == "filter" {
 			if status == 1 {
-				count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, 0, bidsearch.SearchPageSize_PC, true, queryItems, field, notkey)
+				count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, 0, bidsearch.SearchPageSize_PC, true, queryItems, field, notkey, isPayedUser)
 			}
 		} else if reqType == "bidSearch" {
 			//全文检索限制
@@ -168,7 +168,7 @@ func (m *Front) PcAjaxReq() {
 				if limitFlag {
 					if start == 0 {
 						limit_count := public.Lst.TotalPage * bidsearch.SearchPageSize_PC
-						count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, 0, limit_count, true, queryItems, field, notkey)
+						count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, 0, limit_count, true, queryItems, field, notkey, isPayedUser)
 						if totalPage > int64(public.Lst.TotalPage) {
 							totalPage = int64(public.Lst.TotalPage)
 						}
@@ -177,7 +177,7 @@ func (m *Front) PcAjaxReq() {
 						}
 					}
 				} else {
-					count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, start, bidsearch.SearchPageSize_PC, true, queryItems, field, notkey)
+					count, totalPage, list = bidsearch.GetPcBidSearchData(s_word, area, publishtime, subtype, industry, minprice, maxprice, "", buyerclass, hasBuyerTel, hasWinnerTel, start, bidsearch.SearchPageSize_PC, true, queryItems, field, notkey, isPayedUser)
 				}
 				listSize := 0
 				if list != nil {
@@ -225,7 +225,7 @@ func (m *Front) PcAjaxReq() {
 				})
 			}
 		} else if reqType == "lastNews" {
-			_, list = getLastNewsData(s_word, area, publishtime, subtype, industry, minprice, maxprice, buyerclass, hasBuyerTel, hasWinnerTel, tabularflag, start, false, true, "")
+			count, list = getLastNewsData(s_word, area, publishtime, subtype, industry, minprice, maxprice, buyerclass, hasBuyerTel, hasWinnerTel, tabularflag, start, true, true, "")
 		}
 	}
 	if list != nil && len(*list) > 0 {
@@ -282,10 +282,10 @@ func getLastNewsData(searchvalue, area, publishtime, subtype, industry, minprice
 	//最新招标信息
 	findfields := `"title"`
 	qstr := bidsearch.GetSearchQuery(searchvalue, industry, minprice, maxprice, hasBuyerTel, hasWinnerTel, findfields, bidsearch.GetBidSearchQuery(area, publishtime, subtype, "", buyerclass), notkey)
-	if isGetCount {
+	if isGetCount && start == 0 {
 		count = elastic.Count(INDEX, TYPE, qstr)
 	}
-	if !isGetCount || count > 0 {
+	if !(isGetCount && start == 0) || count > 0 {
 		if tabularflag == "Y" {
 			repl := elastic.GetAllByNgram(INDEX, TYPE, qstr, findfields, bidSearch_sort, bidSearch_field, start, bidsearch.SearchPageSize_PC, 115, highlight)
 			if repl != nil && *repl != nil && len(*repl) > 0 {
@@ -419,7 +419,7 @@ func (m *Front) WxsearchlistPaging() {
 	var list *[]map[string]interface{}
 	var secRel *[]map[string]interface{}
 	pageNum, _ := m.GetInteger("pageNum")
-	if userId != "" && pageNum <= bidsearch.SearchMaxPageNum_WX {
+	if userId != "" && pageNum <= bidsearch.SearchMaxPageNum_PAYED {
 		//历史记录和订阅查询
 		one, _ := mongodb.FindById("user", userId, `{"o_jy":1}`)
 		history := redis.GetStr("other", "s_"+userId)
@@ -430,6 +430,7 @@ func (m *Front) WxsearchlistPaging() {
 		limitFlag := false
 		secondKWS := ""
 		secondFlag := ""
+		isPayedUser := false
 		var secondList []map[string]interface{}
 		if searchvalue != "" {
 			filed := ""
@@ -452,13 +453,17 @@ func (m *Front) WxsearchlistPaging() {
 			var notkey string = ""                        //排除词
 
 			vipStatus := jy.GetVipState(public.Mysql, public.MQFW, userId)
-			isPayedUser := vipStatus.IsPayedUser()
+			isPayedUser = vipStatus.IsPayedUser()
 			queryItems := vipStatus.GetQueryItems(selectType, util.Int64All(config.Sysconfig["bidSearchOldUserLimit"]))
 			if isPayedUser {
 				buyerclass = m.GetString("buyerclass")
 				hasBuyerTel, hasWinnerTel = m.GetString("buyertel"), m.GetString("winnertel")
 				notkey = m.GetString("notkey")
 			} else {
+				//免费用户最多500条数据
+				if pageNum > bidsearch.SearchMaxPageNum_WX {
+					pageNum = bidsearch.SearchMaxPageNum_WX
+				}
 				//时间自定义选择默认是vip 大会员 等权限
 				if len(strings.Split(publishtime, "_")) == 2 {
 					publishtime = ""
@@ -564,7 +569,7 @@ func (m *Front) WxsearchlistPaging() {
 			}
 			m.T["msgset"] = keys
 		}
-		hasNextPage := list != nil && len(*list) == bidsearch.SearchPageSize_WX && pageNum < bidsearch.SearchMaxPageNum_WX
+		hasNextPage := list != nil && len(*list) == bidsearch.SearchPageSize_WX && pageNum < util.If(isPayedUser, bidsearch.SearchMaxPageNum_PAYED, bidsearch.SearchMaxPageNum_WX).(int)
 		if limitFlag {
 			hasNextPage = false
 		}

+ 6 - 0
src/jfw/front/vipsubscribe.go

@@ -10,6 +10,7 @@ import (
 	"log"
 	"net/url"
 	"qfw/util"
+	"qfw/util/jy"
 	"qfw/util/redis"
 	"strings"
 	"time"
@@ -129,6 +130,11 @@ func (s *Subscribepay) ToSetInfoTypePage() {
 
 //订阅设置
 func (s *Subscribepay) ToSetPage() {
+	userid := util.ObjToString(s.GetSession("userId"))
+	vipMsg := jy.GetBigVipUserBaseMsg(userid, public.Mysql, public.MQFW)
+	if vipMsg.VipStatus <= 0 && vipMsg.Status <= 0 && isInTSguide(userid) { //仅免费用户跳转向导页面
+		s.Redirect("/front/tenderSubscribe/guide")
+	}
 	nowTime := time.Now().Unix()
 	if nowTime >= liveActiveStartTime && nowTime < liveActiveEndTime {
 		s.T["isLiveActive"] = true

+ 5 - 1
src/jfw/front/wxkeyset.go

@@ -33,9 +33,13 @@ func (m *Front) WxKeyset(tpl string) error {
 		})
 	}
 	vipMsg := jy.GetBigVipUserBaseMsg(userid, public.Mysql, public.MQFW)
-	if tpl == "index" && vipMsg.VipStatus < 0 && vipMsg.Status < 0 && isInTSguide(userid) { //仅免费用户跳转向导页面
+	if (tpl == "index" || tpl == "filterset") && vipMsg.VipStatus <= 0 && vipMsg.Status <= 0 && isInTSguide(userid) { //仅免费用户跳转向导页面
 		return m.Redirect("/front/tenderSubscribe/guide")
 	}
+	//到新订阅设置
+	if vipMsg.IsUpgrade {
+		return m.Redirect("/front/vipsubscribe/toSubVipSetPage")
+	}
 	if tpl == "seniorset" {
 		data, ok := mongodb.FindById("user", userid, `{"o_jy":1}`)
 		if ok && data != nil && len(*data) > 0 {

+ 18 - 0
src/jfw/modules/app/src/app/front/areaPack.go

@@ -0,0 +1,18 @@
+package front
+
+import (
+	"github.com/go-xweb/xweb"
+)
+
+type AreaPackAction struct {
+	*xweb.Action
+	pageManager xweb.Mapper `xweb:"/jyapp/areaPack/page/(.*)"` //大会员
+}
+
+func init() {
+	xweb.AddAction(&AreaPackAction{})
+}
+
+func (this *AreaPackAction) PageManager(htmlName string) error {
+	return this.Render("/areaPack/page_" + htmlName + ".html")
+}

+ 3 - 1
src/jfw/modules/app/src/app/front/commonPay.go

@@ -3,8 +3,9 @@ package front
 import (
 	"errors"
 	"fmt"
-	"github.com/go-xweb/xweb"
 	"qfw/util"
+
+	"github.com/go-xweb/xweb"
 )
 
 /*
@@ -21,6 +22,7 @@ var (
 		"member":       []string{"大会员"},
 		"integral":     []string{"剑鱼币充值"},
 		"dataPack":     []string{"数据流量包"},
+		"areaPack":     []string{"省份订阅包"},
 	}
 )
 

+ 12 - 2
src/jfw/modules/app/src/app/front/front.go

@@ -291,6 +291,7 @@ func (f *Front) TSGuide() error {
 		return f.Render("/weixin/wxtsguide.html")
 	} else {
 		reqType := f.GetString("reqType")
+		// index, _ := f.GetInteger("index")
 		result := make(bson.M)
 		if reqType == "save" {
 			var keyMaps []map[string]interface{}
@@ -306,7 +307,6 @@ func (f *Front) TSGuide() error {
 					}
 					keyMaps = append(keyMaps, map[string]interface{}{
 						"key":      vs,
-						"area":     []string{area},
 						"infotype": []string{},
 						"notkey":   []string{},
 						"from":     1, //用于记录是否可以选择全国
@@ -315,7 +315,11 @@ func (f *Front) TSGuide() error {
 						break
 					}
 				}
+				areas := map[string]interface{}{
+					area: []string{},
+				}
 				saveData := bson.M{
+					"o_jy.o_area":       areas,
 					"o_jy.a_key":        keyMaps,
 					"o_jy.l_modifydate": time.Now().Unix(),
 					"i_ts_guide":        2,
@@ -323,7 +327,10 @@ func (f *Front) TSGuide() error {
 				result["flag"] = mongodb.UpdateById("user", userid, bson.M{"$set": saveData})
 			}
 		} else if reqType == "over" {
-			mongodb.UpdateById("user", userid, bson.M{"$set": bson.M{"i_ts_guide": 1}})
+			saveData := bson.M{
+				"i_ts_guide": 1,
+			}
+			result["flag"] = mongodb.UpdateById("user", userid, bson.M{"$set": saveData})
 		} else if reqType == "preview" {
 			rlt := elastic.GetByNgram(INDEX, TYPE, strings.Split(f.GetString("key"), " "), "", FINDF, `{"publishtime":-1}`, `"_id","title","publishtime","toptype","subtype","type","area","href","areaval"`, 0, 10)
 			if *rlt != nil && len(*rlt) > 0 {
@@ -333,6 +340,9 @@ func (f *Front) TSGuide() error {
 			}
 			result["data"] = rlt
 		}
+		if result["flag"] != nil && result["flag"].(bool) {
+			jy.ClearBigVipUserPower(userid)
+		}
 		f.ServeJson(result)
 	}
 	return nil

+ 13 - 7
src/jfw/modules/app/src/app/front/login.go

@@ -204,10 +204,12 @@ func (l *Login) Login() error {
 						"s_appponetype": phoneType,
 						"i_ts_guide":    2,
 						"o_jy": map[string]interface{}{
-							"i_apppush":    1,
-							"i_ratemode":   2,
+							"i_apppush":  1,
+							"i_ratemode": 2,
+							// "i_newfree":    1, //新免费用户=>新订阅设置页面 20211122
 							"l_modifydate": time.Now().Unix(),
 						},
+						"s_platform": "app",
 					}
 					data["s_regsource"] = isAndroidOrIOS(l.Header("User-Agent"))
 					_id := mongodb.Save("user", data)
@@ -460,11 +462,13 @@ func (l *Login) Register() error {
 					data["l_registedate"] = time.Now().Unix()
 					data["i_ts_guide"] = 2
 					data["o_jy"] = map[string]interface{}{
-						"i_apppush":    1,
-						"i_ratemode":   2,
+						"i_apppush":  1,
+						"i_ratemode": 2,
+						// "i_newfree":    1, //新免费用户=>新订阅设置页面 20211122
 						"l_modifydate": time.Now().Unix(),
 					}
 					data["s_regsource"] = isAndroidOrIOS(l.Header("User-Agent"))
+					data["s_platform"] = "app"
 					saveid = mongodb.Save("user", data)
 					saveSuccess = saveid != ""
 				}
@@ -603,12 +607,14 @@ func (l *Login) WxLogin() {
 				"s_city":         u.City,
 				"s_headimageurl": u.HeadImageUrl,
 				"o_jy": map[string]interface{}{
-					"i_apppush":    1,
-					"i_ratemode":   2,
+					"i_apppush":  1,
+					"i_ratemode": 2,
+					// "i_newfree":    1, //新免费用户=>新订阅设置页面 20211122
 					"l_modifydate": time.Now().Unix(),
 				},
+				"s_platform": "app", //用户注册平台 app 微信 pc
 			}
-			newUser["s_regsource"] = isAndroidOrIOS(l.Header("User-Agent"))
+			newUser["s_regsource"] = isAndroidOrIOS(l.Header("User-Agent")) //用户注册终端 ios 安卓 pc
 			if _id := mongodb.Save("user", newUser); _id != "" {
 				returnSign = afterLogin(newUser, l.Session(), rid, oid, phoneType, channel, deviceId, 2, true, l.ResponseWriter)
 				if disWord != "" {

+ 7 - 3
src/jfw/modules/app/src/app/front/swordfish.go

@@ -222,7 +222,7 @@ func (m *Front) WxsearchlistPaging() {
 	defer util.Catch()
 	var list *[]map[string]interface{}
 	var secRel *[]map[string]interface{}
-	if pageNum, _ := m.GetInteger("pageNum"); pageNum <= bidsearch.SearchMaxPageNum_APP {
+	if pageNum, _ := m.GetInteger("pageNum"); pageNum <= bidsearch.SearchMaxPageNum_PAYED {
 		searchvalue := strings.TrimSpace(m.GetString("searchvalue"))
 		userid := util.ObjToString(m.GetSession("userId"))
 		if userid != "" {
@@ -252,6 +252,7 @@ func (m *Front) WxsearchlistPaging() {
 		limitFlag := false
 		secondKWS := ""
 		secondFlag := ""
+		isPayedUser := false
 		var secondList []map[string]interface{}
 		if searchvalue != "" {
 			selectType := m.GetString("selectType")
@@ -268,13 +269,16 @@ func (m *Front) WxsearchlistPaging() {
 			var notkey string = ""                        //排除词
 
 			vipStatus := jy.GetVipState(public.Mysql, public.MQFW, userid)
-			isPayedUser := vipStatus.IsPayedUser()
+			isPayedUser = vipStatus.IsPayedUser()
 			queryItems := vipStatus.GetQueryItems(selectType, util.Int64All(config.Sysconfig["bidSearchOldUserLimit"]))
 			if isPayedUser {
 				buyerclass = m.GetString("buyerclass")
 				hasBuyerTel, hasWinnerTel = m.GetString("buyertel"), m.GetString("winnertel")
 				notkey = m.GetString("notkey")
 			} else {
+				if pageNum > bidsearch.SearchMaxPageNum_APP {
+					pageNum = bidsearch.SearchMaxPageNum_APP
+				}
 				//时间自定义选择默认是vip 大会员 等权限
 				if len(strings.Split(publishtime, "_")) == 2 {
 					publishtime = ""
@@ -363,7 +367,7 @@ func (m *Front) WxsearchlistPaging() {
 			"limitFlag":     limitFlag,
 			"status":        isLimit,
 			"list":          list,
-			"hasNextPage":   list != nil && len(*list) == bidsearch.SearchPageSize_APP && pageNum < bidsearch.SearchMaxPageNum_APP,
+			"hasNextPage":   list != nil && len(*list) == bidsearch.SearchPageSize_APP && pageNum < util.If(isPayedUser, bidsearch.SearchMaxPageNum_PAYED, bidsearch.SearchMaxPageNum_APP).(int),
 			"history":       m.T["history"],
 			"msgset":        m.T["msgset"],
 			"interceptWord": a_word,

+ 4 - 0
src/jfw/modules/app/src/app/front/vipsubscribe.go

@@ -113,6 +113,10 @@ func (s *Subscribepay) ToSetPage() {
 		s.Redirect("/jyapp/big/page/init") //跳转至首次初始化页面
 		return
 	}
+	//仅免费用户跳转向导页面
+	if bigBaseMsg.Status <= 0 && bigBaseMsg.VipStatus <= 0 && isInTSguide(userid) {
+		s.Redirect("/jyapp/tenderSubscribe/guide")
+	}
 	s.Render("/vipsubscribe/vip_index_new.html")
 }
 

+ 7 - 0
src/jfw/modules/app/src/app/front/wxkeyset.go

@@ -5,7 +5,9 @@ import (
 	. "app/jyutil"
 	"fmt"
 	"jfw/config"
+	"jfw/public"
 	"qfw/util"
+	"qfw/util/jy"
 	"regexp"
 	"strconv"
 	"strings"
@@ -22,6 +24,11 @@ func (m *Front) WxKeyset(tpl string) error {
 	if tpl == "index" && isInTSguide(userid) { //仅免费用户跳转向导页面
 		return m.Redirect("/jyapp/tenderSubscribe/guide")
 	}
+	//到新订阅设置
+	vipMsg := jy.GetBigVipUserBaseMsg(userid, public.Mysql, public.MQFW)
+	if vipMsg.IsUpgrade {
+		return m.Redirect("/jyapp/vipsubscribe/toSubVipSetPage")
+	}
 	if tpl == "seniorset" {
 		data, ok := mongodb.FindById("user", userid, `{"o_jy":1}`)
 		if ok && data != nil && len(*data) > 0 {

+ 90 - 15
src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/analysis_result.css

@@ -136,7 +136,7 @@
     padding: .24rem .32rem;
 }
 
-#analysis-result .van-cell__title {
+#analysis-result .filter-content .van-cell__title {
     font-size: .32rem;
     color: #171826;
     width: 2.2rem;
@@ -144,7 +144,7 @@
     white-space: nowrap;
 }
 
-#analysis-result .van-cell__value {
+#analysis-result .filter-content .van-cell__value {
     font-size: .28rem;
     color: #9B9CA3;
     text-overflow: ellipsis;
@@ -333,18 +333,40 @@
     color: #171826;
     font-weight: bold;
 }
+#analysis-result .win-capital{
+  padding: 8px 24px;
+  font-size: .22rem;
+  color: #171826;
+  line-height: .36rem;
+}
+#analysis-result .win-info{
+  background: linear-gradient(180deg, rgba(108, 218, 237, 0.2) 0%, rgba(255, 255, 255, 0) 100%);
+  border-radius: 6px;
+}
+#analysis-result .w-title{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 9px 8px 0;
+}
+.w-title-label{
+  font-size: .26rem;
+  color: #1d1d1d;
+  line-height: .36rem;
+}
 #analysis-result .company-info{
     display: flex;
     align-items: center;
-    margin-top: 0.08rem;
+    justify-content: space-between;
+    padding: 5px 6px 8px;
     color: #5F5E64;
-    font-size: .22rem;
+    font-size: .2rem;
     line-height: .36rem;
 }
 #analysis-result .company-info span{
-    flex: 1;
+    /* flex: 1; */
     white-space: nowrap;
-    margin-right: .24rem;
+    /* margin-right: .14rem; */
 }
 #analysis-result .same-history,.other-history{
     margin-top: .16rem;
@@ -352,32 +374,35 @@
     border-radius: 8px;
 }
 #analysis-result .same-history{
-    background: rgba(251, 72, 61, 0.06);
+  background: linear-gradient(180deg, rgba(108, 218, 237, 0.2) 0%, rgba(255, 255, 255, 0) 100%);
 }
 #analysis-result .other-history{
-    background: rgba(255, 159, 64, 0.06);
+  background: linear-gradient(180deg, rgba(188, 188, 188, 0.2) 0%, rgba(215, 215, 215, 0.2) 0.01%, rgba(255, 255, 255, 0) 100%);
 }
 #analysis-result .same-title,.other-title{
     font-size: .26rem;
     line-height: .4rem;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
 }
 #analysis-result .same-title{
-    color: #FB483D;
+    color: #171826;
 }
 #analysis-result .other-title{
-    color: #FF9F40;
+    color: #171826;
 }
 #analysis-result .same-info,.other-info{
     display: flex;
     align-items: center;
-    margin-top: 0.08rem;
+    margin-top: 0.1rem;
     font-size: .2rem;
 }
 #analysis-result .same-info span{
     flex: 1;
     width: 33.33%;
     margin-right: .24rem;
-    color: #FB483D;
+    color: #5F5E64;
     opacity: 0.8;
     white-space: nowrap;
 }
@@ -385,11 +410,17 @@
     flex: 1;
     width: 33.33%;
     margin-right: .24rem;
-    color: #FF9F40;
+    /* color: #FF9F40; */
     opacity: 0.8;
     white-space: nowrap;
 }
-
+#analysis-result .win-arrow{
+  font-size: .24rem;
+  color: #5F5E64;;
+}
+.highLight{
+  color: #2ABED1;
+}
 #analysis-result .bar-tip{
     padding: 0.2rem .32rem .32rem;
     text-align: justify;
@@ -465,9 +496,9 @@
 }
 #analysis-result .project-list{
     padding: .24rem .32rem;
-    margin-bottom:.2rem;
     background: #fff;
     border-radius: 8px;
+    margin: .2rem.32rem;
 }
 #analysis-result .pl-title{
     font-size: .32rem;
@@ -520,4 +551,48 @@
     color: #9B9CA3;
     font-size: .22rem;
     line-height: .36rem;
+}
+.detail-filter{
+  margin: .2rem .32rem;
+}
+.detail-filter .van-collapse-item__content{
+  padding: 0;
+}
+.detail-filter .van-cell__title{
+  font-size: .32rem;
+  line-height: .48rem;
+  color: #171826;
+}
+.detail-filter .d-f-search{
+  padding: .26rem 0;
+  text-align: center;
+  color: #2ABED1;
+  font-size: .32rem;
+  line-height: .48rem;
+}
+.detail-filter .filter-input .van-field__label{
+  width: 1.6rem;
+  font-size: .3rem;
+  color: #5f5e64;
+  margin-right: 0;
+}
+.jy-empty{
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin: 0 auto;
+  width: 5rem;
+  text-align: center;
+}
+.jy-empty-img{
+  width: 4rem;
+  height: 4rem;
+  background: url('/common-module/public/image/jy-chagrin.png') no-repeat center center;
+  background-size: contain;
+}
+.jy-empty-text{
+  font-size: .26rem;
+  color: #9B9BA3!important;
+  line-height: .4rem;
+  padding-bottom: .24rem;
 }

+ 37 - 2
src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_portrait.css

@@ -105,7 +105,7 @@
     padding: .32rem 0 .12rem;
     width: 100%;
     font-size: .36rem;
-    font-weight: 700;
+    /* font-weight: 700; */
     line-height: .52rem;
     color: #171826;
 }
@@ -251,7 +251,7 @@
     text-align: center;
 }
 .client .c-name{
-    font-weight: bold;
+    /* font-weight: bold; */
     font-size: .3rem;
     color: #171826;
 }
@@ -383,3 +383,38 @@
     text-decoration: underline;
     margin-right: .08rem;
 }
+.win-analyse{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: .24rem .32rem;
+  margin-top: .24rem;
+  background: #fff;
+}
+.win-bid-title{
+  position: relative;
+  padding-left: .16rem;
+  color: #171826;
+  font-size: .36rem;
+  line-height: .52rem;
+}
+.win-bid-title::after{
+  position: absolute;
+  content: '';
+  width:3px;
+  height: .32rem;
+  background: #2abed1;
+  border-radius: 11px;
+  left:0;
+  top: 50%;
+  transform: translateY(-50%);
+}
+.win-analyse .high-link{
+  display: flex;
+  align-items: center;
+  color: #2abed1;
+  font-size: .28rem;
+}
+.win-analyse .high-link > span{
+  margin-right: .08rem;
+}

+ 54 - 10
src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/unit_portrayal.css

@@ -21,9 +21,54 @@
     font-size: .24rem;
     line-height: .36rem;
 }
+.win-analyse{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: .24rem .32rem;
+  margin-top: .24rem;
+  background: #fff;
+}
+.win-bid-title{
+  position: relative;
+  padding-left: .16rem;
+  color: #171826;
+  font-size: .36rem;
+  line-height: .52rem;
+}
+.win-bid-title::after{
+  position: absolute;
+  content: '';
+  width:3px;
+  height: .32rem;
+  background: #2abed1;
+  border-radius: 11px;
+  left:0;
+  top: 50%;
+  transform: translateY(-50%);
+}
+.win-analyse .high-link{
+  display: flex;
+  align-items: center;
+  color: #2abed1;
+  font-size: .28rem;
+}
+.win-analyse .high-link > span{
+  margin-right: .08rem;
+}
+.buyer-statistic{
+  margin-top: 0.08rem;
+  background: #fff;
+}
+.statistic-title{
+  padding: .32rem .32rem .12rem;
+  color: #171826;
+  line-height: .52rem;
+  font-size: .36rem;
+}
 .buyer-type{
     margin-top: 0.04rem;
-    padding: 0 .32rem;
+    padding: 0 .32rem .24rem;
     color: #5F5E64;
     font-size: .24rem;
     line-height: .36rem;
@@ -33,11 +78,10 @@
     display: flex;
     align-items: center;
     justify-content: space-between;
-    margin-top: .24rem;
+    /* margin-top: .24rem; */
     padding: .24rem .16rem;
 }
 .buyer-info::after{
-    
     position: absolute;
     box-sizing: border-box;
     content: ' ';
@@ -47,7 +91,7 @@
     bottom: -50%;
     left: .32rem;
     border: 0 solid #ebedf0;
-    border-top-width: 1px;
+    /* border-top-width: 1px; */
     border-bottom-width: 1px;
     -webkit-transform: scaleY(.5);
     transform: scaleY(.5);
@@ -85,7 +129,7 @@
 }
 .d_title{
     padding: .32rem .32rem .12rem;
-    font-weight: bold;
+    /* font-weight: bold; */
     font-size: .36rem;
     line-height: .52rem;
     color: #171826;
@@ -132,7 +176,7 @@
     color: #2ABED1;
     font-size: .24rem;
     border-radius: 4px;
-    font-weight: bold;
+    /* font-weight: bold; */
 }
 .i_time{
     font-size: .2rem;
@@ -301,7 +345,7 @@
 }
 .chart_title,.rank_title,.distribute_title{
     padding: .32rem .32rem .12rem;
-    font-weight: bold;
+    /* font-weight: bold; */
     font-size: .36rem;
     line-height: .52rem;
     color: #171826;
@@ -314,7 +358,7 @@
 }
 .client-title,.agency-title{
     padding: .32rem .32rem .12rem;
-    font-weight: bold;
+    /* font-weight: bold; */
     font-size: .36rem;
     line-height: .52rem;
     color: #171826;
@@ -354,7 +398,7 @@
     text-align: center;
 }
 .client .c-name{
-    font-weight: bold;
+    /* font-weight: bold; */
     font-size: .3rem;
     color: #171826;
 }
@@ -484,4 +528,4 @@
     height: 100%;
     background: linear-gradient(270deg, #2ABED1 0.81%, #8DE0EB 100%);
     border-radius: 0 .28rem .28rem 0;
-}
+}

+ 233 - 42
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/analysis_result.js

@@ -1,5 +1,3 @@
-var hotChart = null;
-var pieChart = null;
 var vNode = {
     delimiters: ['${', '}'],
     el: '#analysis-result',
@@ -98,7 +96,14 @@ var vNode = {
             appVersion: '',
             initRendererSvg:{
                 renderer:'svg'
-            }
+            },
+            activeNames: [],
+            winnerVal: '',
+            buyerVal: '',
+            scrollTop: 0,
+            defaultProjectDetail: [],
+            hotChartRef: null,
+            pieChartRef: null
         }
     },
     computed: {
@@ -112,6 +117,34 @@ var vNode = {
             return 320 - 22*this.minusRows  + 'px'
         }
     },
+    watch: {
+      active: function(newVal) {
+        // 监听切换到类似项目明细 页面滚动到筛选条件位置
+        if (newVal == 1) {
+          this.$nextTick(function() {
+            if (this.$refs.detailFilter) {
+              this.$refs.detailFilter.scrollIntoView()
+            }
+          })
+        }
+      },
+      // 监听热力图
+      hotChartRef: function (newVal) {
+        // console.log(newVal, chartOptions.hotChart, '热力图')
+        if (newVal) {
+          newVal.setOption(chartOptions.hotChart);
+          newVal.resize()
+        }
+      },
+      // 监听饼图
+      pieChartRef: function (newVal) {
+        // console.log(newVal, chartOptions.deformPieChart, '饼图')
+        if (newVal) {
+          newVal.setOption(chartOptions.deformPieChart);
+          newVal.resize()
+        }
+      }
+    },
     created () {
         try {
             this.mobileModel = JyObj.getPhoneBrand();
@@ -139,47 +172,61 @@ var vNode = {
             this.currentVal.buyerClass = prevState.currentVal.buyerClass;
         }
         this.isFollowProject();
-        this.init();
-        var restore = this.restoreData()
-        if (!restore) {
-            this.getChartData();
-            this.getBaseInfo();
-        }
     },
     beforeDestroy() {
         window.removeEventListener("resize", this.init,20);
-        if(hotChart) {
-            hotChart.dispose();
-        }
-        if(pieChart) {
-            pieChart.dispose();
-        }
+        // if(this.hotChartRef) {
+        //   this.hotChartRef.dispose();
+        // }
+        // if(this.pieChartRef) {
+        //   this.pieChartRef.dispose();
+        // }
     },
     mounted() {
+        var restore = this.restoreData()
+        if (!restore) {
+            this.getChartData();
+            this.getBaseInfo();
+        }
         this.year = new Date().getFullYear() - 2;
         // 动态调整sticky距离顶部的高度
         this.getStickyTop()
         window.addEventListener('scroll', this.handleScroll, true);
+        this.init();
     },
     methods: {
+        showLoading: function () {
+          var loading = this.$toast.loading({
+            duration: 0,
+            forbidClick: true,
+            message: 'loading...',
+          })
+          return loading
+        },
         // 金额转换
         formatterMoney: function(data) {
             return utils.moneyUnit(data);
         },
+        // 时间转换
+        formatterTime: function(data) {
+          return new Date(Number(data + '000')).pattern('yyyy/MM/dd')
+        },
         // 返回筛选条件
         setBack:function(){
             history.back()
         },
         // resize 屏幕尺寸
         init: function(){
-            var that = this
-            setTimeout(function() {
-                window.addEventListener('resize', function() {
-                    hotChart.resize();
-                    pieChart.resize();
-                    that.screenWidth = document.body.clientWidth
-                })
-            }, 20)
+          var that = this
+          window.addEventListener('resize', function() {
+            if (that.hotChartRef) {
+              that.hotChartRef.resize();
+            }
+            if (that.pieChartRef) {
+              that.pieChartRef.resize();
+            }
+            that.screenWidth = document.body.clientWidth || window.screen.width
+          })
         },
         // 跳企业画像
         goEntImg:function(name) {
@@ -235,7 +282,7 @@ var vNode = {
             this.scroll = this.$refs.backTop.getBoundingClientRect().top
         },
         getStickyTop: function () {
-            this.stickyTop = $('.jy-app-header').height() - 0.5;
+            this.stickyTop = $('.jy-app-header').height() - 1;
         },
         // 取消关注
         cancelFollow:function(){
@@ -333,18 +380,26 @@ var vNode = {
         // 处理行业提交数据
         formatterIndustryData:function(data) {
             // var data = {"建筑工程": ["勘察设计", "工程施工", "监理咨询", "材料设备", "机电安装"],"信息技术": ['系统集成及安全','软件开发','运维服务','其他']}
-            var arr = []
+            // var result = []
             if(data) {
                 if(Object.keys(data).length === 0) {
                     return ''
                 } else {
+                    var k = ''
+                    var arr = []
                     for (var key in data) {
+                        k = key
                         for (var i = 0; i < data[key].length; i++) {
-                            data[key][i] = key + '_' + data[key][i]
+                            // data[key][i] = key + '_' + data[key][i]
                             arr.push(data[key][i])
                         }
                     }
-                    return arr;
+                    var result = arr.map(function(v) {
+                      v = k + '_' + v
+                      return v
+                    })
+                    console.log(result,'111')
+                    return result;
                 }
             }
         },
@@ -404,6 +459,7 @@ var vNode = {
                                     item.firsttime = new Date(Number(item.firsttime + '000')).pattern('yyyy/MM/dd')
                                 }
                             })
+                            that.defaultProjectDetail = res.data.PDeatils
                             that.projectListDetail = res.data.PDeatils; // 类似项目明细
                         }
                         // 类似项目分析
@@ -426,6 +482,70 @@ var vNode = {
                 }
             })
         },
+        // 单独查类似项目明细接口
+        getProjectDetail: function(type, winner, buyer) {
+          var that = this;
+          var loading = that.showLoading()
+          var data = {
+              area: that.areaData,
+              buyerContent: that.contentData,
+              buyerClass: that.buyerClassData,
+              minPrice: utils.deepCompare(that.moneyData, []) ? '' : Number(that.moneyData[0]),
+              maxPrice: Number(that.moneyData[1]) || '',
+              industry: that.industriesData ? that.formatterIndustryData(that.industriesData).toString() : '',
+              pname: that.project.projectName,
+              pid: that.project.pId,
+              sid: that.project.infoId,
+              mobileModel: that.mobileModel,
+              appVersion: that.appVersion,
+              // 以下为新增
+              searchType: type,
+              winner: winner,
+              buyer: buyer,
+          }
+          $.ajax({
+            type:'POST',
+            url:'/bigmember/decision/projectInfoByBW',
+            contentType: 'application/json;charset=utf-8' ,
+            data:JSON.stringify(data),
+            success:function(res) {
+              if(res.error_code == 0) {
+                loading.clear()
+                // 类似项目明细数据
+                if(res.data){
+                  res.data.forEach(function (item,i) {
+                    if (item.budget && item.budget !== '') {
+                        item.budget = (item.budget / 10000).fixed(2)
+                    } else {
+                        item.budget = '-'
+                    }
+                    if (item.bidamount && item.bidamount !== '') {
+                        item.bidamount = (item.bidamount / 10000).fixed(2)
+                    } else {
+                        item.bidamount = '--'
+                    }
+                    if(item.review_experts){
+                        item.review_experts = item.review_experts.join(',')
+                    }
+                    if(item.project_rate){
+                        item.project_rate = (item.project_rate*100).fixed(2) + '%'
+                    }
+                    if(item.firsttime){
+                        item.firsttime = new Date(Number(item.firsttime + '000')).pattern('yyyy/MM/dd')
+                    }
+                  })
+                  that.projectListDetail = res.data;
+                }
+              } else {
+                loading.clear()
+              }
+            },
+            error:function(err) {
+              loading.clear()
+              console.log(err)
+            }
+          })
+        },
         // 初始化画像数据
         initChartData:function(){
             var item = this.cacheImgData;
@@ -599,30 +719,30 @@ var vNode = {
             var index;
             that.$nextTick(function(){
                 var ref = that.$refs.hotChart;
-                hotChart = echarts.init(ref,null,{renderer: "svg"});
-                hotChart.setOption(chartOptions.hotChart);
+                that.hotChartRef = echarts.init(ref,null,{renderer: "svg"});
+                that.hotChartRef.setOption(chartOptions.hotChart);
                 setTimeout(function(){
                     // 默认展示某一个
-                    hotChart.dispatchAction({
+                    that.hotChartRef.dispatchAction({
                         type: 'highlight',
                         seriesIndex: 0,  // 显示第几个series
                         dataIndex: that.getMaxProjectCount(data) // 最大值所在数组的索引
                     });
                 },20)
-                hotChart.on("mouseover", function(e) {
+                that.hotChartRef.on("mouseover", function(e) {
                     index = that.getMaxProjectCount(data)
                     if (e.dataIndex != index) {
-                        hotChart.dispatchAction({
+                      that.hotChartRef.dispatchAction({
                             type: "downplay",
                             seriesIndex: 0,
                             dataIndex: index
                         });
                     }
                 });
-                hotChart.on("mouseout", function(e) {
+                that.hotChartRef.on("mouseout", function(e) {
                     index = that.getMaxProjectCount(data)
                     if (e.dataIndex != index) {
-                        hotChart.dispatchAction({
+                      that.hotChartRef.dispatchAction({
                             type: "highlight",
                             seriesIndex: 0,
                             dataIndex: that.getMaxProjectCount(data)
@@ -671,7 +791,7 @@ var vNode = {
             }
             var maxNum = Math.max.apply(null,arr);
             var curIndex = this.getArrayIndex(arr,maxNum,'count')
-            console.log('最大值:'+ maxNum + ',索引:' + curIndex)
+            // console.log('最大值:'+ maxNum + ',索引:' + curIndex)
             setTimeout(function(){
                 $event.dispatchAction({
                     type: 'showTip',
@@ -737,12 +857,12 @@ var vNode = {
             var curIndex = that.getArrayIndex(data,true,'pie'); // 当前项目采购类型在饼图数组中的坐标
             that.$nextTick(function(){
                 var ref = that.$refs.pieChart;
-                pieChart = echarts.init(ref);
-                pieChart.setOption(chartOptions.deformPieChart);
-                pieChart.resize();
+                that.pieChartRef = echarts.init(ref);
+                that.pieChartRef.setOption(chartOptions.deformPieChart);
+                that.pieChartRef.resize();
                 if(curIndex) {
                     setTimeout(function(){
-                        pieChart.dispatchAction({
+                        that.pieChartRef.dispatchAction({
                             type: 'showTip',
                             seriesIndex:0,
                             dataIndex: curIndex
@@ -850,34 +970,105 @@ var vNode = {
             var data = {
                 cacheImgData: this.cacheImgData,
                 projectListDetail: this.projectListDetail,
+                defaultProjectDetail: this.defaultProjectDetail,
                 skeletonShow: this.skeletonShow,
                 isShow: this.isShow,
                 minusRows: this.minusRows,
                 screenWidth: this.screenWidth,
                 year: this.year,
-                baseInfo: this.baseInfo
+                baseInfo: this.baseInfo,
+                scrollTop: this.$refs.wrapper.scrollTop
             }
-            console.log(data)
+            // console.log(data)
             sessionStorage.setItem('$data-analysis-result',JSON.stringify(data))
         },
         // 恢复页面数据
         restoreData:function(){
             var $data = sessionStorage.getItem('$data-analysis-result')
-            // console.log($data)
             if ($data) {
                 $data = JSON.parse($data)
                 this.cacheImgData = $data.cacheImgData || {}
                 this.projectListDetail = $data.projectListDetail
+                this.defaultProjectDetail = $data.projectListDetail
                 this.skeletonShow = $data.skeletonShow
                 this.isShow = $data.isShow
                 this.minusRows = $data.minusRows
                 this.screenWidth = $data.screenWidth
                 this.year = $data.year
                 this.baseInfo = $data.baseInfo
+                this.scrollTop = $data.scrollTop
+                var _this = this
+                this.$nextTick(function(){
+                  _this.$refs.wrapper.scrollTop = $data.scrollTop || 0
+                })
                 this.initChartData()
                 sessionStorage.removeItem('$data-analysis-result')
             }
             return !!$data
+        },
+        goDetail (winner, buyer) {
+          this.active = 1
+          this.activeNames = ['1']
+          this.winnerVal = winner ? winner : ''
+          this.buyerVal = buyer ? buyer : ''
+          this.scrollTop = this.$refs.wrapper.scrollTop
+          if (buyer) {
+            this.getProjectDetail(0, winner, buyer)
+          } else {
+            this.getProjectDetail(0, winner)
+          }
+        },
+        onTabClick (page) {
+          if (page == 1) {
+            var loading = this.showLoading()
+            var _this = this
+            setTimeout(function() {
+              _this.projectListDetail = _this.defaultProjectDetail
+              loading.clear()
+            }, 50)
+          } else {
+            var _this = this
+            this.$nextTick(function(){
+              _this.$refs.wrapper.scrollTop = this.scrollTop
+            })
+          }
+          this.activeNames = []
+          this.winnerVal = ''
+          this.buyerVal = ''
+        },
+        // 类似项目明细搜素
+        onSearch () {
+          if (!this.winnerVal && !this.buyerVal) return
+          if (this.winnerVal && this.buyerVal) {
+            this.getProjectDetail(0, this.winnerVal, this.buyerVal)
+          } else {
+            this.getProjectDetail(0, this.winnerVal, this.buyerVal)
+          }
+        },
+        // 跳转其他项目明细页面
+        goOtherDetail (winner, buyer) {
+          this.savePageData()
+          var data = {
+            area: this.areaData,
+            buyerContent: this.contentData,
+            buyerClass: this.buyerClassData,
+            minPrice: utils.deepCompare(this.moneyData, []) ? '' : Number(this.moneyData[0]),
+            maxPrice: Number(this.moneyData[1]) || '',
+            industry: this.industriesData ? this.formatterIndustryData(this.industriesData).toString() : '',
+            pname: this.project.projectName,
+            pid: this.project.pId,
+            sid: this.project.infoId,
+            buyer: this.project.buyer,
+            mobileModel: this.mobileModel,
+            appVersion: this.appVersion,
+            // 以下为新增
+            winner: winner,
+            searchType: 1
+          }
+          if (winner || buyer) {
+            sessionStorage.setItem('analysis_other_project', JSON.stringify(data))
+            location.href = "./free_other_project?winner=" + winner + '&buyer=' + buyer
+          }
         }
     }
 }

+ 148 - 50
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js

@@ -123,7 +123,16 @@ var vNode = {
         visited: false // 是否查看中标信息
       },
       portrait: 'winner',
-      showBaseInfo: false
+      showBaseInfo: false,
+      show: {
+        yearData: true,
+        monthData: true,
+        areaData: true,
+        rate: true,
+        top10: true,
+        topShow: true,
+        dt: true
+      }
     }
   },
   created: function () {
@@ -146,6 +155,13 @@ var vNode = {
       // 获取企业基本信息
       this.getEntBaseInfo()
     }
+    var storageId = sessionStorage.getItem('winner_high_eid')
+    // 判断如果url中的企业id和高级分析设置中存的企业id不一致就清除高级分析设置中存的筛选条件
+    console.log('缓存里的企业id和当前企业id是否相同', storageId !== eId)
+    if (storageId && storageId !== eId) {
+      sessionStorage.removeItem('winner_high_set')
+      sessionStorage.removeItem('winner_high_eid')
+    }
   },
   mounted: function () {
     var _this = this
@@ -162,43 +178,34 @@ var vNode = {
     })
   },
   watch: {
-    // tabActiveName: function (newVal, oldVal) {
-    //   console.log(newVal)
-    //     var _this = this
-    //     if (newVal == '2' || newVal == '1') {
-    //         this.$nextTick(function () {
-    //             if (_this.gotTab2) {
-    //                 // 初始化图表
-    //                 if (_this.entPortraitInfo && _this.conf.showPortraitAll && !_this.singleTab) {
-    //                     _this.initChartsData();
-    //                 }
-    //             } else {
-    //                 if (_this.conf._4) {
-    //                     // 获取企业画像信息-4
-    //                     _this.getEntPortrait(function () {
-    //                         _this.initChartsData()
-    //                     })
-    //                     _this.gotTab2 = true
-    //                     console.log('获取企业全景分析...')
-    //                 }
-    //                 // 获取企业中标动态-13
-    //                 if (_this.conf._13) {
-    //                     // _this.getProjectNews()
-    //                     _this.gotTab2 = true
-    //                     console.log('获取企业中标动态...')
-    //                 }
-    //                 if(_this.powerInfo.memberStatus <= 0) {
-    //                     // 不是大会员点击中标信息使用次数加一
-    //                     // if(!_this.entvisit.visited) {
-    //                     //     _this.entvisit.usage++
-    //                     //     _this.entvisit.visited = true
-    //                     // }
-    //                 }
-    //                 _this.gotTab2 = true
-    //             }
-    //         });
-    //     }
-    // },
+    tabActiveName: function (newVal, oldVal) {
+        var _this = this
+        if (newVal == '2') {
+            this.$nextTick(function () {
+                if (_this.gotTab2) {
+                    // 初始化图表
+                    if (_this.entPortraitInfo && _this.conf.showPortraitAll && !_this.singleTab) {
+                        _this.initChartsData();
+                    }
+                } else {
+                    if (_this.conf._4) {
+                        // 获取企业画像信息-4
+                        _this.getEntPortrait(function () {
+                            _this.initChartsData()
+                        })
+                        _this.gotTab2 = true
+                        console.log('获取企业全景分析...')
+                    }
+                    // 获取企业中标动态-13
+                    if (_this.conf._13) {
+                        // _this.getProjectNews()
+                        _this.gotTab2 = true
+                        console.log('获取企业中标动态...')
+                    }
+                }
+            });
+        }
+    },
   },
   computed: {
     // 3个权限有1个就为true(取反为3个权限1个都没有)
@@ -233,6 +240,17 @@ var vNode = {
     },
     isMemberAndSvip: function () {
       return this.powerInfo.memberStatus > 0 || this.powerInfo.vipStatus > 0
+    },
+    allNot: function() {
+      var data = this.show
+      var arr = []
+      for (var key in data) {
+        arr.push(data[key])
+      }
+      var isShow = arr.some(function(item) {
+        return item
+      })
+      return !isShow
     }
   },
   methods: {
@@ -312,6 +330,7 @@ var vNode = {
     },
     // 获取画像信息
     getEntPortrait: function (callback) {
+      var storageSet = JSON.parse(sessionStorage.getItem('winner_high_set'))
       var _this = this
       var data = {
         entId: _this.entInfo.id
@@ -334,16 +353,12 @@ var vNode = {
       } else {
         urls = '/bigmember/portrait/subVipPortrait/winner'
       }
-      // if (_this.powerInfo.memberStatus <= 0 || _this.svip || _this.isVip) {
-      //   urls = '/bigmember/portrait/subVipPortrait/winner'
-      // } else {
-      //   urls = '/bigmember/portrait/winner/getData'
-      // }
       _this.getEntPortraitInfoTimes++
       $.ajax({
         type: 'POST',
         url: urls,
-        data: data,
+        data: storageSet ? Object.assign(data, storageSet) : data,
+        timeout: 10000,
         success: function (res) {
           if (res.error_code == 0) {
             _this.loading.clear()
@@ -367,10 +382,25 @@ var vNode = {
                 _this.getEntPortrait()
               }
             }
+          } else {
+            _this.$toast(res.error_msg)
+            _this.show.yearData = false
+            _this.show.monthData = false
+            _this.show.areaData = false
+            _this.show.rate = false
+            _this.show.top10 = false
+            _this.show.topShow = false
           }
         },
         error: function (error) {
-          _this.$toast('请求失败')
+          // _this.$toast('请求失败')
+          // 处理ios请求超时后 再次请求
+          _this.loading.clear()
+          setTimeout(function(){
+            _this.getEntPortrait(function () {
+              _this.initChartsData()
+            })
+          }, 3000)
         }
       })
     },
@@ -380,6 +410,7 @@ var vNode = {
       $.ajax({
         type: "POST",
         url: "/bigmember/portrait/subVipPortrait/usage",
+        timeout: 5000,
         data: {
           entId: _this.entInfo.id
         },
@@ -393,6 +424,9 @@ var vNode = {
               _this.entvisit = res.data
             }
           }
+        },
+        error: function (error) {
+          console.log(error)
         }
       });
     },
@@ -419,6 +453,7 @@ var vNode = {
     },
     // 获取项目动态
     getProjectNews: function () {
+      var storageSet = JSON.parse(sessionStorage.getItem('winner_high_set'))
       var _this = this
       var data = {
         entId: _this.entInfo.id,
@@ -433,21 +468,31 @@ var vNode = {
       $.ajax({
         type: 'POST',
         url: urls,
-        data: data,
+        data: storageSet ? Object.assign(data, storageSet) : data,
+        timeout: 8000,
         success: function (res) {
           if (res.error_code == 0) {
             _this.loading.clear()
             _this.topProject.count = res.data.count
+            if (!res.data.list || res.data.list.length == 0) {
+              // 新加变量 判断中标动态有无数据 用于展示缺省页组件
+              _this.show.dt = false
+            }
             if (res.data.list && $.isArray(res.data.list)) {
               _this.singleTab = false
               _this.topProject.list = res.data.list
             }
           } else {
             _this.$toast(res.error_msg)
+            _this.show.dt = false
           }
         },
         error: function (error) {
-          _this.$toast('请求失败')
+          // _this.$toast('请求失败')
+          _this.loading.clear()
+          setTimeout(function() {
+            _this.getProjectNews()
+          }, 3000)
         }
       })
     },
@@ -466,9 +511,9 @@ var vNode = {
         data: {
           entId: _this.entInfo.id
         },
+        timeout: 6000,
         success: function (res) {
           if (res.error_code == 0) {
-            _this.loading.clear()
             if (res.data && Object.keys(res.data).length !== 0) {
               _this.entInfo.name = res.data.entName
               for (var key in res.data) {
@@ -477,11 +522,14 @@ var vNode = {
             }
           } else {
             // 不显示提示信息
-            // _this.$toast(res.error_msg)
+            _this.$toast(res.error_msg)
           }
         },
         error: function (error) {
           console.log(error)
+          setTimeout(function() {
+            _this.getEntBaseInfo()
+          }, 3000)
         }
       })
     },
@@ -495,6 +543,7 @@ var vNode = {
         data: {
           entId: _this.entInfo.id
         },
+        timeout: 5000,
         success: function (res) {
           if (res.error_code == 0) {
             _this.entInfo.followSearchFinish = true
@@ -537,6 +586,7 @@ var vNode = {
       $.ajax({
         type: 'GET',
         url: '/bigmember/use/isAdd',
+        timeout: 5000,
         success: function (res) {
           if (res.error_code == 0) {
             _this.conf.powerLoaded = true
@@ -597,6 +647,7 @@ var vNode = {
         },
         error: function (error) {
           console.log(error)
+          _this.loading.clear()
         }
       })
     },
@@ -615,6 +666,7 @@ var vNode = {
         data: {
           entId: _this.entInfo.id
         },
+        timeout: 5000,
         success: function (res) {
           if (res.error_code == 0) {
             // 清除上个页面缓存
@@ -633,6 +685,7 @@ var vNode = {
         },
         error: function (error) {
           console.log(error)
+          loading.clear()
         }
       })
     },
@@ -743,7 +796,7 @@ var vNode = {
     // 2. 月度中标金额(折线图)
     lineChartConfig: function (options) {
       options.yAxis[0].name = '中标金额(万元)';
-      options.legend.itemGap = 20;
+      options.legend.itemGap = 10;
       options.tooltip.formatter = function (params) {
         var tip = '';
         for (var i = 0; i < params.length; i++) {
@@ -844,6 +897,8 @@ var vNode = {
       // 数据总量为0,不赋值
       if (count != 0) {
         this.annualData.rows = rows;
+      } else {
+        this.show.yearData = false
       }
     },
     // 整理月度项目统计数据
@@ -889,6 +944,8 @@ var vNode = {
       if (count != 0 && maxNum !== 0) {
         this.monthZbData.columns = columns;
         this.monthZbData.rows = rows;
+      } else {
+        this.show.monthData = false
       }
     },
     // 整理主要市场分布(中国地图)数据
@@ -912,6 +969,8 @@ var vNode = {
       // 数据总量为0,不赋值
       if (count != 0) {
         this.mapChartData.rows = mapRows;
+      } else {
+        this.show.areaData = false
       }
     },
     // 整理平均折扣率数据
@@ -948,11 +1007,17 @@ var vNode = {
       if (count != 0) {
         this.rateData.columns = columns;
         this.rateData.rows = rows;
+      } else {
+        this.show.rate = false
       }
     },
     // 初始化饼图
     initPieChartData: function (d) {
       if (!d) return
+      if (d && d.length == 0) {
+        // 新增变量 用于判断是否展示缺省页
+        this.show.top10 = false
+      }
       var that = this
       var arr = []
       var data = JSON.parse(JSON.stringify(d))
@@ -1000,6 +1065,9 @@ var vNode = {
     // 整理重要客户数据
     arrangeImportantData: function (data) {
       if (!data) return
+      if (data && data.length == 0) {
+        this.show.topShow = false
+      }
       var arr = []
       if ($.isArray(data)) {
         data.forEach(function (list) {
@@ -1089,7 +1157,37 @@ var vNode = {
         sessionStorage.removeItem(this.sessKey)
       }
       return !!$data
+    },
+    // 高级分析设置
+    goHighSet () {
+      var url = this.getProjectNewsUrl()
+      var reqSign = url.indexOf('subVipPortrait') === -1 ? 'bigmember' : 'svip'
+      if (this.conf._4) {
+        location.href = './free_high_set?header=中标信息高级分析设置&eid=' + utils.getParam('eId') + '&reqSign=' + reqSign
+      } else {
+        this.$dialog.confirm({
+          className:'promatch',
+          title: '您暂无使用权限',
+          message: '您未购买此服务,如需使用请联系您的销售人员或客服升级套餐,谢谢!',
+          showCancelButton: false,
+          confirmButtonColor: '#2cb7ca',
+          confirmButtonText: '我知道了'
+        }).then(function () {})
+      }
     }
   }
 }
 var vueComponent = new Vue(vNode)
+$(function () {   
+  var u = navigator.userAgent;
+  var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
+  var isPageHide = false;   
+  window.addEventListener('pageshow', function () {   
+      if (isPageHide && isiOS) {   
+      window.location.reload();   
+      }   
+  });   
+  window.addEventListener('pagehide', function () {   
+      isPageHide = true;   
+  });
+})

+ 32 - 11
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/set_area.js

@@ -2,6 +2,10 @@ var vNode = {
     delimiters: ['${', '}'],
     el: '#set-area',
     data: {
+        // 默认配置项
+        config: {
+            onlyProvince: false, // 只能选省份
+        },
         // 原始城市数据
         chinaMap: chinaMapJSON,
         // 省份与字母IndexBar对照表
@@ -72,6 +76,7 @@ var vNode = {
         }
     },
     created: function () {
+        this.getConfig()
         this.initIndexBarAndAreaMap()
         this.provinceListMap['#'][0].selectedState = 'checked'
     },
@@ -83,6 +88,10 @@ var vNode = {
     },
     mounted: function () {},
     methods: {
+        getConfig: function () {
+            if (!window.__page_config) return
+            Object.assign(this.config, window.__page_config)
+        },
         // 整理城市数据列表(并初始化indexBar数据)
         initIndexBarAndAreaMap: function () {
             var _this = this
@@ -179,7 +188,9 @@ var vNode = {
         // 根据城市的选择情况判断省份的选择情况
         changeCityState(province, city) {
             if (city === '#') {
-                return this.setCitySelected()
+                this.setCitySelected()
+                this.onChange()
+                return
             }
             // 全国置为空
             this.provinceListMap['#'][0].selectedState = ''
@@ -210,11 +221,7 @@ var vNode = {
                 province.selectedState = ''
             }
 
-            var pState = this.checkAllProvinceState()
-            // 如果所有省份被全选,则取消所有选中,让全国选中
-            if (pState.allSelected || pState.noSelected) {
-                this.setCitySelected()
-            }
+            this.onChange()
         },
         // 省份checkbox点击事件
         clickCheckbox(province) {
@@ -236,11 +243,7 @@ var vNode = {
                 province.selectedState = ''
             }
             
-            var pState = this.checkAllProvinceState()
-            // 如果所有省份被全选,则取消所有选中,让全国选中
-            if (pState.allSelected || pState.noSelected) {
-                this.setCitySelected()
-            }
+            this.onChange()
         },
         // 检查是否所有省份按钮被全选中
         // 全部被全选->返回true
@@ -423,11 +426,28 @@ var vNode = {
                 zh: tipText
             }
         },
+        onChange: function () {
+            var pState = this.checkAllProvinceState()
+            // 如果所有省份被全选,则取消所有选中,让全国选中
+            if (pState.allSelected || pState.noSelected) {
+                this.setCitySelected()
+            }
+            
+            // 获取当前状态
+            var selectedCity = this.getSelectedCity()
+            try {
+                onChange && onChange(selectedCity)
+            } catch (error) {
+                console.warn(error)
+                console.warn(arguments.callee.name + '必须定义为函数')
+            }
+        },
         onReset: function () {
             this.setCitySelected(this.initCityMap)
             try {
                 onReset && onReset(this.initCityMap)
             } catch (error) {
+                console.log(error)
                 console.error(arguments.callee.name + '必须定义为函数')
             }
         },
@@ -436,6 +456,7 @@ var vNode = {
             try {
                 onConfirm && onConfirm(selectedCity)
             } catch (error) {
+                console.log(error)
                 console.error(arguments.callee.name + '必须定义为函数')
             }
         }

+ 157 - 59
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js

@@ -1,5 +1,5 @@
-var hotChart = null;
-var pieChart = null;
+// var hotChart = null;
+// var pieChart = null;
 var vNode = {
     delimiters: ['${', '}'],
     el: '#unit_portrayal',
@@ -42,7 +42,6 @@ var vNode = {
                 showLine: ['项目金额'],
                 axisSite: { right: ['项目金额'] }
             },
-            // hotChart: null,
             isShow:{
                 showDynamic: false,
                 showYearData: false,
@@ -117,7 +116,9 @@ var vNode = {
             },
             bigStatus: 0,
             encryptId: '', // 首次埋点返回的加密id 用于点击去开通传参
-            power: []
+            power: [],
+            hotChart: null,
+            pieChart: null
         }
     },
     computed: {
@@ -157,31 +158,52 @@ var vNode = {
           return this.power.indexOf(5)  == -1 // power == 5
         },
     },
+    watch: {
+      // 监听热力图
+      hotChart: function (newVal) {
+        // console.log(newVal, chartOptions.hotChart, '热力图')
+        if (newVal) {
+          newVal.setOption(chartOptions.hotChart);
+          newVal.resize()
+        }
+      },
+      // 监听饼图
+      pieChart: function (newVal) {
+        // console.log(newVal, chartOptions.deformPieChart, '饼图')
+        if (newVal) {
+          newVal.setOption(chartOptions.deformPieChart);
+          newVal.resize()
+        }
+      }
+    },
     created () {
       this.getPowerInfo()
-      this.init();
     },
     mounted: function () {
-        this.buyer.name = decodeURIComponent(utils.getParam('entName'));
+        this.buyer.name = decodeURIComponent(utils.getParam('entName'))
+        var storageName = decodeURIComponent(sessionStorage.getItem('buyer_high_name'))
+        // 判断如果url中的采购单位和高级分析设置中采购单位不一致就清除高级分析设置中存的筛选条件
+        console.log('缓存中的采购单位名称和当前采购单位名称是否相同:',storageName == this.buyer.name)
+        if (storageName && storageName !== this.buyer.name) {
+          sessionStorage.removeItem('buyer_high_set')
+          sessionStorage.removeItem('buyer_high_name')
+        }
+        
         this.getNewMsg(); // 中标动态
         this.getChartData(); // 企业画像
+        // this.init();
     },
     beforeDestroy() {
-        window.removeEventListener("resize", this.init,20);
-        if(hotChart) {
-            hotChart.dispose();
-        }
-        if(pieChart) {
-            pieChart.dispose();
-        }
+      window.removeEventListener("resize", this.init,20);
     },
     methods: {
         // 获取权限信息
         getPowerInfo: function () {
             var _this = this
             $.ajax({
-              type: 'GET',
+              type: 'POST',
               url: '/bigmember/use/isAdd?t=' + Date.now(),
+              timeout: 6000,
               success: function (res) {
                   if (res.data) {
                     _this.power = res.data.power
@@ -216,6 +238,9 @@ var vNode = {
               },
               error: function (error) {
                 console.log(error)
+                setTimeout(function() {
+                  _this.getPowerInfo()
+                }, 3000)
               }
             })
         },
@@ -269,11 +294,16 @@ var vNode = {
           })
         },
         init() {
-            setTimeout(function() {
-                window.addEventListener('resize', function() {
-                    hotChart.resize();
-                })
-            }, 20)
+          setTimeout(function() {
+            window.addEventListener('resize', function() {
+              if (this.hotChart) {
+                this.hotChart.resize();
+              }
+              if (this.pieChart) {
+                this.pieChart.resize();
+              }
+            })
+          }, 20)
         },
         goEntInfo: function(item) {
             location.href = './ent_portrait?eId=' + encodeURIComponent(item.entId)
@@ -305,18 +335,30 @@ var vNode = {
                 }
             })
         },
+        // 跳转招标动态新页面
+        goProjectPage: function () {
+          if (this.power.indexOf(5) == -1) {
+            this.openDialog()
+            return
+          } else {
+            location.href = './free_buyer_project_news?entName=' + decodeURIComponent(utils.getParam('entName'))
+          }
+        },
         // 获取中标动态数据
         getNewMsg: function(){
+          var storageSet = JSON.parse(sessionStorage.getItem('buyer_high_set'))
           var that = this;
           var data = {
               buyer: decodeURIComponent(utils.getParam('entName')),
-              count: that.dt.pageCount,
-              pageSign: that.dt.isMore
+              // count: that.dt.pageCount,
+              // pageSign: that.dt.isMore,
+              pageNum: 1
           }
           $.ajax({
             type:'POST',
             url:'/bigmember/portrait/buyer/getNewMsg',
-            data:data,
+            data: storageSet ? Object.assign(data, storageSet) : data,
+            timeout: 8000,
             success:function(res) {
               if(res.error_code == 0) {
                 if (res.data.list && res.data.list.length && res.data.list.length > 0) {
@@ -327,25 +369,29 @@ var vNode = {
                         v.firsttime = new Date(Number(v.firsttime + '000')).pattern('yyyy/MM/dd');
                         v.bidamount = v.bidamount ? utils.moneyUnit(v.bidamount) : ''
                     })
-                    if (!that.dt.isMore) {
-                        that.dt.list = []
-                        that.dt.isMore = 'more'
-                        if(res.data.count <= 3) {
-                            that.dt.isNext = false
-                        }
-                    } else if (that.dt.isMore === 'more') {
-                        if (that.power.indexOf(5) == -1) {
-                          that.openDialog()
-                          return
-                        }
-                        that.dt.isMore = 'max'
-                        if(res.data.count <= 23) {
-                            that.dt.isNext = false
-                        }
-                    } else if (that.dt.isMore === 'max') {
-                        that.dt.isNext = false
+                    if (res.data.count <= 10) {
+                      that.dt.isNext = false
                     }
-                    that.dt.list = that.dt.list.concat(res.data.list)
+                    that.dt.list = res.data.list
+                    // if (!that.dt.isMore) {
+                    //     that.dt.list = []
+                    //     that.dt.isMore = 'more'
+                    //     if(res.data.count <= 3) {
+                    //         that.dt.isNext = false
+                    //     }
+                    // } else if (that.dt.isMore === 'more') {
+                    //     if (that.power.indexOf(5) == -1) {
+                    //       that.openDialog()
+                    //       return
+                    //     }
+                    //     that.dt.isMore = 'max'
+                    //     if(res.data.count <= 23) {
+                    //         that.dt.isNext = false
+                    //     }
+                    // } else if (that.dt.isMore === 'max') {
+                    //     that.dt.isNext = false
+                    // }
+                    // that.dt.list = that.dt.list.concat(res.data.list)
                   }
                 }
               } else {
@@ -353,31 +399,44 @@ var vNode = {
               }
             },
             error:function(err) {
-              console.log(err)
+              setTimeout(function() {
+                that.getNewMsg()
+              }, 3000)
             }
           })
         },
         // 获取采购单位画像所有数据
         getChartData: function() {
           var that = this;
+          var storageSet = JSON.parse(sessionStorage.getItem('buyer_high_set'))
+          var data = {
+            buyer: decodeURIComponent(utils.getParam('entName'))
+          }
           $.ajax({
             type:'POST',
             url:'/bigmember/portrait/buyer/getData',
-            data:{
-              buyer: decodeURIComponent(utils.getParam('entName'))
-            },
+            data: storageSet ? Object.assign(data, storageSet) : data,
+            timeout: 10000,
             success:function(res) {
                 if(res.error_code == 0) {
                   if(res.data && Object.keys(res.data).length > 0) {
                       that.chartLoading = false;
                       that.initChartData('', res.data)
                   } else {
-                    that.getSectionChartData('a')
+                    // that.getSectionChartData('a')
+                    if (that.reqCount < 5) {
+                      that.getChartData()
+                    } else {
+                      that.chartLoading = false;
+                    }
                   }
                 }
             },
             error:function(err) {
               console.log(err)
+              setTimeout(function() {
+                that.getChartData()
+              }, 3000)
             }
           })
         },
@@ -494,16 +553,22 @@ var vNode = {
         formatYearsData: function(data) {
           if(data && Object.keys(data).length > 0){
             var rows = [];
+            var count = 0
             for (var key in data) {
               rows.push({
                 '年份': key,
                 '项目数量': data[key].Count,
                 '项目金额': (data[key].Money/10000).fixed(0),
               })
+              count += data[key].Count
+            }
+            if (count !== 0) {
+              this.projectData.columns = ['年份', '项目数量', '项目金额'];
+              this.projectData.rows = rows;
+              this.isShow.showYearData = true;
+            } else {
+              this.isShow.showYearData = false;
             }
-            this.projectData.columns = ['年份', '项目数量', '项目金额'];
-            this.projectData.rows = rows;
-            this.isShow.showYearData = true;
           }
         },
         // 3.处理月度采购规模数据
@@ -512,9 +577,13 @@ var vNode = {
             var rows = [];
             var columns = ['月份'];
             var count = 0;
+            var allNum = []
             var yearArr = []
             for (var key in data) {
               yearArr.push(parseInt(key))
+              for(var n in data[key]) {
+                allNum.push(data[key][n])
+              }
             }
             yearArr.sort(function (a, b) { return a - b })
             yearArr.forEach(function (item) {
@@ -537,8 +606,9 @@ var vNode = {
               })
               rows.push(columnsItem)
             }
+            var maxNum = Math.max.apply(Math, allNum.map(function(o) { return o }))
             // 数据总量为0,不赋值
-            if (count != 0) {
+            if (count != 0 && maxNum !== 0) {
               this.monthScaleData.columns = columns;
               this.monthScaleData.rows = rows;
               this.isShow.showMonthScale = true;
@@ -932,30 +1002,30 @@ var vNode = {
             var index;
             that.$nextTick(function(){
                 var ref = that.$refs.hotChart;
-                hotChart = echarts.init(ref,null,{renderer: "svg"});
-                hotChart.setOption(chartOptions.hotChart);
+                that.hotChart = echarts.init(ref,null,{renderer: "svg"});
+                that.hotChart.setOption(chartOptions.hotChart);
                 setTimeout(function(){
                     // 默认展示某一个tooltip
-                    hotChart.dispatchAction({
+                    that.hotChart.dispatchAction({
                         type: 'highlight',
                         seriesIndex: 0,  // 显示第几个series
                         dataIndex: that.getMaxProjectCount(data) // 显示第几个数据
                     });
                 },20)
-                hotChart.on("mouseover", function(e) {
+                that.hotChart.on("mouseover", function(e) {
                     index = that.getMaxProjectCount(data)
                     if (e.dataIndex != index) {
-                        hotChart.dispatchAction({
+                      that.hotChart.dispatchAction({
                             type: "downplay",
                             seriesIndex: 0,
                             dataIndex: index
                         });
                     }
                 });
-                hotChart.on("mouseout", function(e) {
+                that.hotChart.on("mouseout", function(e) {
                     index = that.getMaxProjectCount(data)
                     if (e.dataIndex != index) {
-                        hotChart.dispatchAction({
+                      that.hotChart.dispatchAction({
                             type: "highlight",
                             seriesIndex: 0,
                             dataIndex: that.getMaxProjectCount(data)
@@ -1037,9 +1107,9 @@ var vNode = {
             }
             that.$nextTick(function(){
                 var ref = that.$refs.pieChart;
-                pieChart = echarts.init(ref,null,{renderer: "svg"});
-                pieChart.setOption(chartOptions.deformPieChart);
-                pieChart.resize();
+                that.pieChart = echarts.init(ref,null,{renderer: "svg"});
+                that.pieChart.setOption(chartOptions.deformPieChart);
+                that.pieChart.resize();
             })
         },
         arrTrans: function(num, arr) { // 一维数组转换为二维数组
@@ -1247,6 +1317,34 @@ var vNode = {
             })
             return maxIndex
         },
+        goHighSet: function() {
+          location.href = './free_high_set?header=采购单位高级分析设置&entName=' + decodeURIComponent(utils.getParam('entName'))
+          // if (!this.getStatus) {
+          //   location.href = './free_high_set?header=采购单位高级分析设置&entName=' + decodeURIComponent(utils.getParam('entName'))
+          // } else {
+          //   this.$dialog.confirm({
+          //     className:'promatch',
+          //     title: '您暂无使用权限',
+          //     message: '您未购买此服务,如需使用请联系您的销售人员或客服升级套餐,谢谢!',
+          //     showCancelButton: false,
+          //     confirmButtonColor: '#2cb7ca',
+          //     confirmButtonText: '我知道了'
+          //   }).then(function () {})
+          // }
+        }
     }
 }
 var unit = new Vue(vNode)
+$(function () {   
+  var u = navigator.userAgent;
+  var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
+  var isPageHide = false;   
+  window.addEventListener('pageshow', function () {   
+      if (isPageHide && isiOS) {   
+      window.location.reload();   
+      }   
+  });   
+  window.addEventListener('pagehide', function () {   
+      isPageHide = true;   
+  });
+})

+ 5 - 4
src/jfw/modules/app/src/web/staticres/jyapp/css/searchindex.css

@@ -40,8 +40,8 @@
   background-position: -0.88rem 0;
 }
 .jy_sprite_main {
-    background-image: url(/common-module/mainSearch/image/mainSearch.png?v=51430);
-    background-size: 8.98rem 4.71rem;
+    background: url(/common-module/public/image/jy-back.png?v=51431) no-repeat;
+    background-size: 100% 100%;
     display: inline-block;
 }
 .sprite_jysorry_1 {
@@ -52,9 +52,10 @@
     overflow: hidden;
 }
 .sprite_jysorry_1_wx {
-    background-position: -3.02rem -0px;
+    /* background-position: -3.02rem -0px; */
     background-repeat: no-repeat;
-    height: 2.58rem;
+		/* height: 2.58rem; */
+		height: 4rem;
     width: 3.26rem;
     overflow: hidden;
 }

+ 5 - 2
src/jfw/modules/app/src/web/staticres/jyapp/css/subscribe.css

@@ -746,6 +746,9 @@ em,i{
 .jymobile-setting-dialog {
   font-size: .32rem;
 }
+.jymobile-setting-dialog .weui-dialog {
+    background: #fff;
+}
 
 .jymobile-setting-dialog .weui-dialog__hd {
   padding: 0;
@@ -1957,7 +1960,7 @@ html, body {
   line-height: 22px;
 }
 .product-switch .vipproduct{
-  box-shadow: 0px 1px 0px 0px rgba(0,0,0,0.05) inset, 16px 0px 0px 0px #ffffff inset; 
+  box-shadow: 0px 1px 0px 0px rgba(0,0,0,0.05) inset, 16px 0px 0px 0px #ffffff inset;
 }
 .product-switch .icon-blue-duihao{
   display: flex;
@@ -2038,7 +2041,7 @@ html, body {
   height: 109px;
   opacity: 1;
   background: linear-gradient(180deg,#f5fffe 0%, #ffffff 100%);
-  box-shadow: 0px 4px 16px 0px rgba(8,31,38,0.15); 
+  box-shadow: 0px 4px 16px 0px rgba(8,31,38,0.15);
   border-radius: .16rem;
 }
 .housemov{

+ 32 - 0
src/jfw/modules/app/src/web/staticres/jyapp/js/historypush.js

@@ -471,6 +471,23 @@ var vm = new Vue({
           } else {
             _this.screenShow = false
           }
+          // 从页面移植来的
+          if(!res.data.entniche && !res.data.member && res.data.vip <= 0) {
+            sessionStorage.removeItem('switch-product')
+            setTimeout(function() {
+                (window.slotbydup = window.slotbydup || []).push({
+                    id: "u6603902",
+                    container: "_36y1d8lbx9n",
+                    async: true
+                });
+                (window.slotbydup = window.slotbydup || []).push({
+                    id: "u6603902",
+                    container: "_061vbh43quq3",
+                    async: true
+                });
+            },1000)
+            _this.getAjaxAdv()
+          }
         }
       })
       $.ajax({
@@ -479,6 +496,7 @@ var vm = new Vue({
           dataType: "json",
           success: function (res) {
               if (res.data) {
+                window.userNewType = res.data.isUpgrade // 原页面里的用户版本 变量赋值
                 _this.rootInfo = res.data
                 let switchProduct = sessionStorage.getItem('switch-product')
                 // res.data.memberStatus = 3
@@ -736,6 +754,20 @@ var vm = new Vue({
       this.$refs.areaCityItem.toggle(false)
       this.$refs.industryItem.toggle(false)
       this.$refs.moreDropdownItems.toggle(false)
+    },
+    getAjaxAdv: function () {
+      $.ajax({
+        type: 'POST',
+        url: '/publicapply/adLeague/exposure',
+        data: {
+            client: 'APP',
+            id: 'ad6',
+            position: '订阅推送列表页'
+        },
+        success: function(res) {
+            console.log(res)
+        }
+      })
     }
   }
 })

+ 175 - 55
src/jfw/modules/app/src/web/staticres/jyapp/js/searchindex.js

@@ -1,4 +1,49 @@
 var nowClientHeight = document.documentElement.clientHeight || document.body.clientHeight
+var userReadnum = 0
+var vSwitch = 'f'
+var newUserType = false
+// 判断用户权限版本
+function getUserType() {
+  $.ajax({
+      type: 'POST',
+      url: '/publicapply/subscribe/vipSwitch',
+      success: function(res) {
+        vSwitch = res.data.vt || 'f'
+      }
+  })
+}
+getUserType()
+function hiddenTips() {
+  $('#UserTips').hide()
+}
+function gotoPay() {
+  $('#UserTips').hide()
+  location.href = '/jyapp/areaPack/page/buy?type=buy'
+}
+// 获取用户是否为新用户
+function getUserNewType() {
+  $.ajax({
+      url: '/bigmember/use/isAdd',
+      type: 'POST',
+      success: function (res) {
+        newUserType = res.data.isUpgrade
+      }
+  })
+}
+getUserNewType()
+function hiddenTips2() {
+  $('#tipsType').hide()
+}
+function updateJump2() {
+  $('#tipsType').hide()
+  // location.replace('/jyapp/vipsubscribe/toSubVipSetPage?vSwitch=v')
+  $.ajax({
+    url: '/publicapply/free/oneProvinceSet',
+    type: 'POST',
+    success: function (res) {
+      location.href = '/jyapp/vipsubscribe/toSubVipSetPage'
+    }})
+}
 $(function () {
   // var vConsole = new VConsole();
   if(mySysIsIos()){//ios登陆后页面不刷新;导致重复登陆
@@ -394,69 +439,120 @@ var SuperSearch = {
       SuperSearch.dyDiv=true;
     });
 
-    //订阅
-    $("#supersearchPage #zjdy").on("tap",function(even){
-      if(userId == ""||userId == null){
-        SuperSearch.setSessionStorage();
-        window.location.href = "/jyapp/free/login?to=back";
-        return;
-      }
-      var rFlag = false;
-      if(SuperSearch.isVip || window.jyUserPower.member){
-        $.ajax({
-          type: "post",
-          url: "/publicapply/subscribe/setUserInfo",
-          data: {
-            pageType:'keyWords',
-            actionType: 'directSubKWS',
-            kws_name:SuperSearch.s_words,
-            vSwitch: vSwitch
-          },
-          // dataType: "json",
-          async: false,
-          success: function(r){
-            if(r.flag=="y"){
-              rFlag = true;
-            }else if(r.flag=="o"){
-              EasyAlert.show("您已经订阅过此关键字");
-            }else if(r.flag=="m"){
-              EasyAlert.show("您已经超过订阅<br>关键字上限");
+    // 获取用户信息-用于立即订阅按钮
+    function getKeyUserInfo () {
+      // 免费用户
+      // --> 已设置10组关键词,订阅失败提示
+      // --> 小于10组
+      //    --> 历史老用户-未选择区域-提示更新
+      //           --> 选择区域-关键词列表
+      //    --> 新用户-未选择区域-订阅页面
+      //           --> 选择区域-关键词列表
+
+      var isOldUser = false
+      var nowKeyLength = 8
+      var isSelectArea = false
+
+     // 获取用户关键词数据
+      $.ajax({
+        url: '/publicapply/free/subscribe',
+        type: 'post',
+        success: function (res) {
+          if (res.error_code === 0 && res.data) {
+            try {
+              isSelectArea = !!res.data.area
+              nowKeyLength = res.data.keys.length
+            } catch (e) {
+              console.warn('error format keys length')
             }
-          },error: function(){
-            rFlag = true;
           }
-        });
-        if(rFlag){
+        },
+      })
+
+      // S-直接订阅
+      $("#supersearchPage #zjdy").on("tap",function(even){
+        if(userId == ""||userId == null){
           SuperSearch.setSessionStorage();
-          window.location.href = "/jyapp/vipsubscribe/toSetKeyWordPage";
+          window.location.href = "/jyapp/free/login?to=back";
+          return;
         }
-      }else{
-        $.ajax({
-          type: "post",
-          url: "/jyapp/member/swordfish/ajaxReq",
-          data: {keys:SuperSearch.s_words,reqType: "subscribe"},
-          dataType: "json",
-          async: false,
-          success: function(r){
-            if(r.flag=="y"){
+        var rFlag = false;
+        if(SuperSearch.isVip || window.jyUserPower.member){
+          $.ajax({
+            type: "post",
+            url: "/publicapply/subscribe/setUserInfo",
+            data: {
+              pageType:'keyWords',
+              actionType: 'directSubKWS',
+              kws_name:SuperSearch.s_words,
+              vSwitch: vSwitch
+            },
+            // dataType: "json",
+            async: false,
+            success: function(r){
+              if(r.flag=="y"){
+                rFlag = true;
+              }else if(r.flag=="o"){
+                EasyAlert.show("您已经订阅过此关键字");
+              }else if(r.flag=="m"){
+                EasyAlert.show("您已经超过订阅<br>关键字上限");
+              }
+            },error: function(){
+              rFlag = true;
+            }
+          });
+          if(rFlag){
+            SuperSearch.setSessionStorage();
+            window.location.href = "/jyapp/vipsubscribe/toSetKeyWordPage";
+          }
+        }else{
+          // 免费用户
+          isOldUser = !jyAddInfo.isUpgrade
+          if (nowKeyLength >= 10) {
+            return EasyAlert.show("您已经超过订阅<br>关键字上限");
+          } else {
+            if (isSelectArea) {
+              // 执行下方原有逻辑
+            } else if (isOldUser) {
+              return $('#tipsType').show()
+            }
+          }
+
+          $.ajax({
+            type: "post",
+            url: "/jyapp/member/swordfish/ajaxReq",
+            data: {keys:SuperSearch.s_words,reqType: "subscribe"},
+            dataType: "json",
+            async: false,
+            success: function(r){
+              if(r.flag=="y"){
+                rFlag = true;
+              }else if(r.flag=="o"){
+                EasyAlert.show("您已经超过订阅<br>关键字上限");
+              }
+            },
+            error: function(){
               rFlag = true;
-            }else if(r.flag=="o"){
-              EasyAlert.show("您已经超过订阅<br>关键字上限");
             }
-          },error: function(){
-            rFlag = true;
+          });
+          if(rFlag){
+            SuperSearch.setSessionStorage();
+            var goHref = "/jyapp/vipsubscribe/toSetKeyWordPage";
+            if (!isSelectArea) {
+              goHref = "/jyapp/vipsubscribe/toSubVipSetPage";
+            }
+            setTimeout(function(){
+              window.location.href = goHref
+            },100);
           }
-        });
-        if(rFlag){
-          //JyObj.redirectKeyset();
-          SuperSearch.setSessionStorage();
-          setTimeout(function(){
-            window.location.href = "/jyapp/wxkeyset/keyset/index";
-          },100);
         }
-      }
-    });
-    //订阅结束==========================================================================
+      });
+      // E-直接订阅
+    }
+
+    getKeyUserInfo()
+
+
     //删除历史搜索
     $("#supersearchPage").on("click", " #del_history", function(){
       if(localStorage){
@@ -981,6 +1077,12 @@ var SuperSearch = {
             SuperSearch.noMoreData();
             return;
           }
+          // 免费用户搜索结果查看大于11页时弹窗提示
+          // if (!vMainSearchComponent.checkNowPower() && SuperSearch.reqParam["pageNum"] > 10) {
+          //   vMainSearchComponent.showBuyTip('招标搜索结果', '免费用户最多可查看500条招标搜素结果,可前往购买超级订阅解锁查看更多信息')
+          //   SuperSearch.noMoreData();
+          //   return;
+          // }
           if(SuperSearch.limitFlag){
             setTimeout(function(){
               SuperSearch.limitPaging(me);
@@ -1000,6 +1102,15 @@ var SuperSearch = {
             data: SuperSearch.reqParam,
             dataType: 'json',
             success: function(data){
+              if (vSwitch === 'f') {
+                userReadnum += data.list.length
+                if (userReadnum >= 500) {
+                  // 展示提示窗
+                  $('#UserTips').show()
+                } else {
+                  $('#UserTips').hide()
+                }
+              }
               //没有数据
               if(data["list"] == null || data["list"].length == 0){
                 SuperSearch.noMoreData();
@@ -1347,6 +1458,15 @@ var SuperSearch = {
       data: SuperSearch.reqParam,
       dataType: "json",
       success: function(data){
+        if (vSwitch === 'f') {
+          userReadnum += data.list.length
+          if (userReadnum >= 500) {
+            // 展示提示窗
+            $('#UserTips').show()
+          } else {
+            $('#UserTips').hide()
+          }
+        }
         SuperSearch.secondList=data.secondList;
         SuperSearch.secondFlag=data.secondFlag;
         SuperSearch.secondKWS=data.secondKWS;

+ 11 - 3
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyWord.css

@@ -8,8 +8,11 @@
 .group-filter-container .group-name {
   max-width: 2rem;
 }
+.j-container .grey-bg {
+  background-color: rgba(0, 0, 0, 0.05);
+}
+
 .filter-text {
-  margin-right: .16rem;
   font-size: .28rem;
   color: #5f5e64;
   line-height: .4rem;
@@ -19,6 +22,7 @@
   display: flex;
   align-items: center;
   justify-content: space-between;
+  margin: 0 .16rem;
   padding: .08rem .24rem;
   font-size: .24rem;
   color: #171826;
@@ -40,7 +44,6 @@
   justify-content: space-between;
 }
 .j-key-card-bottom {
-  
   margin-top: .2rem;
   color: #5f5e64;
   line-height: .36rem;
@@ -54,8 +57,12 @@
 .j-key-card-bottom.ls .subinfo-text  {
   flex: 1;
 }
+
+.j-key-card .k-c-t-l {
+  margin-right: .2rem;
+}
+
 .j-key-card .k-c-t-c {
-  margin: 0 .2rem;
   flex: 1;
   font-size: .28rem;
   font-weight: 500;
@@ -63,6 +70,7 @@
   line-height: .4rem;
 }
 .j-key-card .k-c-t-r {
+  margin-left: .2rem;
   line-height: .4rem;
 }
 

+ 16 - 3
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyword-common.css

@@ -274,9 +274,8 @@
   width: 100%;
 }
 .key-empty .empty-img-container {
-  padding: .5rem;
-  width: 3.2rem;
-  height: 3.2rem;
+  width: 4rem;
+  height: 4rem;
 }
 .key-empty .empty-img {
   display: block;
@@ -289,3 +288,17 @@
   color: #5f5e64;
   line-height: .4rem;
 }
+
+.key-tag {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: .02rem .12rem;
+  font-size: .2rem;
+  border: 1px solid;
+  border-radius: .26rem;
+}
+.key-tag.red {
+  color: #FA483C;
+  border-color: #FA483C;
+}

+ 3 - 0
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/subscribe_list.css

@@ -50,6 +50,9 @@
 .jymobile-setting-dialog {
   font-size: .32rem;
 }
+.jymobile-setting-dialog .weui-dialog {
+  background: #fff;
+}
 
 .jymobile-setting-dialog .weui-dialog__hd {
   padding: 0;

+ 66 - 0
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_purchase.css

@@ -1032,3 +1032,69 @@
 .origin-price .price-num {
   text-decoration: line-through;
 }
+
+/* 弹出框样式 */
+.back-tip-wrapper {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+  height: 6.7rem;
+  padding-top: .48rem;
+  padding-bottom: .56rem;
+  width: calc(100% - 0.72rem * 2);
+  background-image: url(/common-module/area-pack/images/messageCard@2x.png);
+  background-repeat: no-repeat;
+  background-size: contain;
+  background-position: center center;
+  background-color: transparent;
+}
+.back-tip-wrapper .b-t-title {
+  width: 2.12rem;
+}
+.back-tip-wrapper .b-t-title img {
+  width: 100%;
+}
+.back-tip-wrapper .b-t-content {
+  margin-top: .24rem;
+  max-width: 4.4rem;
+  flex: 1;
+}
+.back-tip-wrapper .b-t-content-item {
+  margin-bottom: .24rem;
+  padding: .06rem .2rem;
+  width: 100%;
+  color: #5E5E64;
+  font-size: .28rem;
+  line-height: .44rem;
+  text-align: center;
+  border-radius: .16rem;
+}
+.b-t-content-item.bg-f-orange {
+  font-size: .24rem;
+  line-height: .4rem;
+  color: #D69E55;
+  background-color: #FAE7CA;
+}
+.b-t-footer {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.b-t-footer .button {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 2.2rem;
+  height: .8rem;
+  font-size: .36rem;
+  color: #D69E55;
+  border-radius: .7rem;
+  border: 1px solid #D69E55;
+  background-color: transparent;
+}
+.b-t-footer .button.confirm {
+  margin-left: .4rem;
+  color: #fff;
+  background-color: #D69E55;
+}

BIN
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/image/gotolevelup.png


BIN
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/image/help-icon.png


+ 30 - 2
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/change_industry.js

@@ -360,6 +360,9 @@ $(function () {
         } else {
           areaParams = data.data.industry.join(',')
         }
+        if (vSwitch === 'm') {
+          data.data.area = bigmemberArea
+        }
         var params = {
           area: JSON.stringify(data.data.area),
           industry: areaParams
@@ -413,8 +416,33 @@ $(function () {
           history.back()
         }
     })
-
-
+    var vSwitch = ''
+    var bigmemberArea = {}
+    function getBigmemberMsg() {
+      $.ajax({
+          type: 'POST',
+          url: '/bigmember/use/info?t=' + new Date().getTime(),
+          data: {
+          },
+          success: function(res) {
+            bigmemberArea = res.data.member_jy.o_area
+          }
+      })
+    }
+    getBigmemberMsg()
+    function switehAjax(data) {
+      $.ajax({
+          type: 'POST',
+          url: '/publicapply/subscribe/vipSwitch',
+          data: {
+              vt:data || ''
+          },
+          success: function(res) {
+            vSwitch = res.data.vt || 'f'
+          }
+      })
+    }
+    switehAjax()
     function getDataWitXHR() {
         $DoPost('/subscribepay/vipsubscribe/getSubBuyMsg', {}, function (res) {
             if (!res.success) return;

+ 54 - 19
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyWord.js

@@ -2,7 +2,7 @@ var vm = new Vue({
   delimiters: ['${', '}'],
   el: '.app-layout-content-b',
   data: {
-    vSwitch: 'v', // 超级订阅v/大会员m
+    vSwitch: 'f', // 超级订阅v/大会员m/免费用户f
     conf: {
       sessKey: '$data-vipsubscribe-keyword-list',
       keywordMax: 300
@@ -31,13 +31,27 @@ var vm = new Vue({
     scrollTop: 0 // 记录滚动高度
   },
   computed: {
+    // 关键词是否达到上限
+    fullKeys: function () {
+      return this.filter.allKeywordsList.length >= this.conf.keywordMax
+    },
+    addNewKeyButtonText: function () {
+      if (this.vSwitch !== 'f') return '新增关键词组'
+      if (this.fullKeys) {
+        return '解锁更多关键词组'
+      } else {
+        return '新增关键词组'
+      }
+    },
     getInfoUrl: function () {
       // 超级订阅v/大会员m
-      var url = '/subscribepay/afterPay/getUserInfo'
       if (this.vSwitch === 'm') {
-        url = '/bigmember/use/info'
+        return '/bigmember/use/info'
+      } else if (this.vSwitch === 'v') {
+        return '/subscribepay/afterPay/getUserInfo'
+      } else {
+        return '/publicapply/free/subscribe'
       }
-      return url
     },
     keyListSorted: function () {
       return this.filter.keywordsList.sort(function (a, b) {
@@ -59,20 +73,6 @@ var vm = new Vue({
       return selectedArr.length
     },
     totalKeywordsCount: function () {
-      // var count = 0
-      // this.filter.allKeywordsList.forEach(function (item) {
-      //   if (item.matchway == 1) {
-      //     // 模糊匹配
-      //     var key = item.key
-      //     if (Array.isArray(item.appendkey)) {
-      //       key = key.concat(item.appendkey)
-      //     }
-      //     count += key.length
-      //   } else {
-      //     // 精准匹配(matchway:0/undefined)
-      //     count++
-      //   }
-      // })
       return this.filter.allKeywordsList.length
     }
   },
@@ -136,7 +136,7 @@ var vm = new Vue({
         url: '/publicapply/subscribe/vipSwitch',
         async: false,
         success: function (res) {
-          this.vSwitch = res.data.vt || 'v'
+          this.vSwitch = res.data.vt || 'f'
         }.bind(this)
       })
     },
@@ -183,6 +183,25 @@ var vm = new Vue({
               if (res.userData && res.userData.o_vipjy) {
                 kList = res.userData.o_vipjy.a_items || []
               }
+            } else {
+              // 免费用户
+              _this.conf.keywordMax = 10
+              _this.userData = res.data
+              // 关键词赋值
+              if (res.data) {
+                try {
+                  var a_key = res.data.keys || []
+                  kList = [
+                    {
+                      a_key: a_key,
+                      s_item: '未分类'
+                    }
+                  ]
+                } catch (error) {
+                  kList = []
+                  console.log(error)
+                }
+              }
             }
 
             if (kList.length) {
@@ -275,6 +294,7 @@ var vm = new Vue({
       }
     },
     showFilterPicker: function (f) {
+      if (this.vSwitch === 'f') return
       this.filter.pickerShow = f
     },
     checkThisGroup: function (item) {
@@ -398,6 +418,7 @@ var vm = new Vue({
         url: '/publicapply/subscribe/setUserInfo',
         type: 'POST',
         data: {
+          vSwitch: this.vSwitch,
           pageType: 'keyWords',
           actionType: 'DK',
           delete_key: JSON.stringify(deleteKey)
@@ -496,6 +517,15 @@ var vm = new Vue({
       })
       return groupIndex
     },
+    clickAddKeyWordButton: function () {
+      if (this.fullKeys) {
+        if (this.vSwitch === 'f') {
+          this.toBuyVIPService()
+        }
+      } else {
+        this.addKeyWord()
+      }
+    },
     addKeyWord: function () {
       var query = {
         type: 'add'
@@ -510,6 +540,11 @@ var vm = new Vue({
       var queryString = this.qsStringify(query)
       location.href = '/jyapp/vipsubscribe/toSetinfoPage' + '?' + queryString
     },
+    toBuyVIPService: function () {
+      this.savePageState()
+      // location.href = '/jyapp/vipsubscribe/introducePage'
+      location.href = '/jyapp/vipsubscribe/vipsubscribe_new'
+    },
     toKeyManagePage: function () {
       this.filter.pickerShow = false
       this.savePageState()

+ 36 - 3
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyset-list.js

@@ -138,7 +138,9 @@ var keySet = new Vue({
     // 关键词数组
     keyList: [],
     loading: '',
-    swiper: ''
+    swiper: '',
+    userNewType: false, // 1为新用户.0为老用户
+    tipsType: false // 提示升级弹窗状态
   },
   computed: {
     reverseList: function () {
@@ -150,6 +152,7 @@ var keySet = new Vue({
   created: function () {
     this.getKeyList()
     sessionStorage.removeItem('free-keyset-detail')
+    this.getUserType()
   },
   mounted: function () {
     pTools.iosBackRefresh()
@@ -360,7 +363,11 @@ var keySet = new Vue({
       if (index === -1) {
         index = this.keyList.length
       }
-      location.href = '/jyapp/wxkeyset/keyset/filterset?type=' + type + '&index=' + index
+      if (!this.userNewType) {
+        this.tipsType = true
+      } else {
+        location.href = '/jyapp/wxkeyset/keyset/filterset?type=' + type + '&index=' + index
+      }
     },
     // 调整底部按钮距离
     adjustAddButtonPadding: function () {
@@ -386,6 +393,32 @@ var keySet = new Vue({
       sessionStorage.removeItem('historypushScrollTop')
       sessionStorage.removeItem('historypushHasNextPage')
       sessionStorage.removeItem('closeAdvert')
-    }
+    },
+    // 获取用户权限
+    getUserType: function () {
+      let _this = this
+      $.ajax({
+          url: '/bigmember/use/isAdd',
+          type: 'POST',
+          success: function (res) {
+              _this.userNewType = res.data.isUpgrade
+          }
+      })
+    },
+    hiddenTips: function () {
+      this.tipsType = false
+    },
+    updateJump: function () {
+      this.tipsType = false
+      // location.replace('/jyapp/vipsubscribe/toSubVipSetPage?vSwitch=v')
+      sessionStorage.setItem('userIsNew', true)
+      $.ajax({
+        url: '/publicapply/free/oneProvinceSet',
+        type: 'POST',
+        success: function (res) {
+          location.replace('/jyapp/vipsubscribe/toSubVipSetPage')
+        }})
+      // 
+    },
   }
 })

+ 45 - 9
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyword-info.js

@@ -2,7 +2,7 @@ var vm = new Vue({
   delimiters: ['${', '}'],
   el: '.app-layout-content-b',
   data: {
-    vSwitch: 'v', // 超级订阅v/大会员m
+    vSwitch: 'f', // 超级订阅v/大会员m
     conf: {
       keywordMax: 300
     },
@@ -55,12 +55,20 @@ var vm = new Vue({
   },
   computed: {
     getInfoUrl: function () {
-      // 超级订阅v/大会员m
-      var url = '/subscribepay/afterPay/getUserInfo'
       if (this.vSwitch === 'm') {
-        url = '/bigmember/use/info'
+        return '/bigmember/use/info'
+      } else if (this.vSwitch === 'v') {
+        return '/subscribepay/afterPay/getUserInfo'
+      } else {
+        return '/publicapply/free/subscribe'
+      }
+    },
+    keywordPlaceHolder: function () {
+      if (this.vSwitch === 'f') {
+        return '请输入关键词'
+      } else {
+        return '请输入关键词,多个关键词用空格隔开,例如:税务局 软件'
       }
-      return url
     },
     tooLittleTipShow: function () {
       return this.pInfo.pushCount !== '' && this.pInfo.pushCount < 30 && this.keyInfo.key
@@ -124,9 +132,12 @@ var vm = new Vue({
   },
   mounted: function () {},
   methods: {
-    // 输入内容格式化
+    keywordInput(value) {
+      if (this.vSwitch === 'f') {
+        this.keyInfo.key = value.replace(/\s+/g, '')
+      }
+    },
     formatter(value) {
-      // 过滤输入的前后空格
       return value.trim()
     },
     showLoading: function () {
@@ -182,7 +193,7 @@ var vm = new Vue({
         url: '/publicapply/subscribe/vipSwitch',
         async: false,
         success: function (res) {
-          this.vSwitch = res.data.vt || 'v'
+          this.vSwitch = res.data.vt || 'f'
         }.bind(this)
       })
     },
@@ -222,6 +233,25 @@ var vm = new Vue({
               if (res.userData && res.userData.o_vipjy) {
                 kList = res.userData.o_vipjy.a_items || []
               }
+            } else {
+              // 免费用户
+              _this.conf.keywordMax = 10
+              _this.userData = res.data
+              // 关键词赋值
+              if (res.data && res.data.keys) {
+                try {
+                  var a_key = res.data.keys || []
+                  kList = [
+                    {
+                      a_key: a_key,
+                      s_item: '未分类'
+                    }
+                  ]
+                } catch (error) {
+                  kList = []
+                  console.log(error)
+                }
+              }
             }
 
             if (kList.length) {
@@ -389,6 +419,7 @@ var vm = new Vue({
         url: '/publicapply/subscribe/setUserInfo',
         type: 'POST',
         data: {
+          vSwitch: this.vSwitch,
           pageType: 'keyWords',
           actionType: 'DK',
           delete_key: JSON.stringify(deleteKey)
@@ -508,6 +539,7 @@ var vm = new Vue({
       //  SK:保存关键词; DK:删除关键词; SC:保存分类
       var groupInfo = this.getGKIndex()
       var params = {
+        vSwitch: this.vSwitch,
         pageType: 'keyWords',
         actionType: 'SK',
         match_way: this.keyInfo.matchWay,
@@ -717,7 +749,11 @@ var vm = new Vue({
       if (key) {
         var keyArr = this.keyInfo.key.split(/\s+/)
         keyArr.push(item)
-        this.keyInfo.key = utils.unique(keyArr).join(' ')
+        if (this.vSwitch === 'f') {
+          this.keyInfo.key = utils.unique(keyArr).join('')
+        } else {
+          this.keyInfo.key = utils.unique(keyArr).join(' ')
+        }
       } else {
         this.keyInfo.key = item
       }

+ 100 - 24
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_index_new.js

@@ -11,14 +11,21 @@ var subNode = new Vue({
                 industry: '/jyapp/vipsubscribe/toChangeIndustry?header=save',
                 keyword: '/jyapp/vipsubscribe/toSetKeyWordPage',
                 infotype: '/jyapp/vipsubscribe/toSetInfoTypePage',
-                resultview: '/jyapp/vipsubscribe/toVIPViewPage',
-                pushsetting: '/jyapp/big/page/push_setting_detail?header=超级订阅推送设置&type=super_subscribe'
+                resultview: '/jyapp/vipsubscribe/toVIPViewPage?vSwitch=v',
+                pushsetting: '/jyapp/big/page/push_setting_detail?header=超级订阅推送设置&type=super_subscribe',
+                freepush: '/jyapp/big/page/push_setting_detail?header=订阅&type=free_subscribe',
             },
             initData: {},
             memberStatus: 0,
             vipLink: '/jyapp/vipsubscribe/vipsubscribe_renew',
             arrowShow: true,
-            subInfoAjax: '/subscribepay/vipsubscribe/getSubBuyMsg?t=' + new Date().getTime()
+            subInfoAjax: '/subscribepay/vipsubscribe/getSubBuyMsg?t=' + new Date().getTime(),
+            userAreaNum: 1, // 用户修改地区剩余次数
+            userType: false, // 用户是否为付费用户
+            userAreaAllNum: 1, // 用户可修改地区总次数
+            subscribeTime: '', // 用户订阅的时间
+            vSwitch: '', // 用户权限
+            freeUserArea: {}, // 购买省份订阅包的用户所选择的地区
         }
     },
     created () {
@@ -28,7 +35,46 @@ var subNode = new Vue({
       this.switchShow()
       this.switehAjax()
     },
+    mounted () {
+        this.$nextTick(function () {
+            $(".app-layout-content-b").removeAttr('v-cloak')
+        })
+    },
     methods: {
+        // 省份订阅包续费
+        renewBtn: function () {
+            location.href = '/jyapp/areaPack/page/buy?type=renew'
+        },
+        // 省份订阅包升级
+        updateBtn: function () {
+            location.href = '/jyapp/areaPack/page/buy?type=upgrade&area=' +  encodeURIComponent(JSON.stringify(this.freeUserArea))
+        },
+        // 得到用户是否购买省份包
+        getUserSubscribe: function () {
+            let _this = this
+            _this.$refs.subComponent.getUserSubscribe(function (res) {
+                    if (res && res.data) {
+                        _this.freeUserArea = res.data.area
+                        _this.userType = res.data.provincenum === 0 ? false : true
+                        _this.userAreaAllNum = res.data.provincenum === -1 ? '全国' : res.data.provincenum
+                        _this.subscribeTime = new Date(res.data.ppstart * 1000).pattern('yyyy年MM月dd日') + "-" + new Date(res.data.ppend * 1000).pattern('yyyy年MM月dd日')
+                        _this.initdata = res.data
+                        _this.linkObj.pushsetting = _this.linkObj.freepush
+
+                    }
+            })
+
+
+            $.ajax({
+                url: '/publicapply/free/pushcount',
+                type: 'POST',
+                success: function (res) {
+                    if (res && res.count) {
+                        _this.$refs.subComponent.$data.resultTime = '(近3个月内共' + res.count + '条信息)'
+                    }
+                }
+            })
+        },
         initPage: function(num) {
             let swipro = sessionStorage.getItem('switch-product')
             if(swipro) {
@@ -41,8 +87,10 @@ var subNode = new Vue({
                             $('.custom-header-title').html('<span class="title-text"><em class="title_icon icon_zj"></em>订阅管理-大会员</span>')
                         } else if(num == 2) {
                             $('.custom-header-title').html('<span class="title-text"><em class="title_icon icon_zh"></em>订阅管理-大会员</span>')
+
                         } else if(num == 3) {
                             $('.custom-header-title').html('<span class="title-text"><em class="title_icon icon_sj"></em>订阅管理-大会员</span>')
+
                         } else {
                             $('.custom-header-title').html('<span class="title-text"><em class="title_icon icon_zj"></em>订阅管理-大会员</span>')
                         }
@@ -55,17 +103,26 @@ var subNode = new Vue({
                             pushsetting: '/jyapp/big/page/push_setting_detail?header=大会员推送设置&type=member_subscribe'
                         }
                         this.subInfoAjax = '/bigmember/use/info?t=' + new Date().getTime()
+                    } else if(num <= 0) {
+                        $('.custom-header-title').html('<span class="title-text">订阅管理-免费订阅</span>')
+                        this.subInfoAjax = '/publicapply/free/subscribe'
+                        this.linkObj.resultview = '/jyapp/vipsubscribe/toVIPViewPage?vSwitch=f'
                     } else {
                         $('.custom-header-title').html('<span class="title-text"><em class="title_icon icon_vip"></em>订阅管理-超级订阅</span>')
                         this.subInfoAjax = '/subscribepay/vipsubscribe/getSubBuyMsg?t=' + new Date().getTime()
                     }
-                } else {
+                } else if(swipro == 'supervip') {
                     $('.custom-header-title').html('<span class="title-text"><em class="title_icon icon_vip"></em>订阅管理-超级订阅</span>')
                     this.subInfoAjax = '/subscribepay/vipsubscribe/getSubBuyMsg?t=' + new Date().getTime()
+                } else {
+                    $('.custom-header-title').html('<span class="title-text">订阅管理-免费订阅</span>')
+                    this.linkObj.resultview = '/jyapp/vipsubscribe/toVIPViewPage?vSwitch=f'
+                    this.subInfoAjax = '/publicapply/free/subscribe'
                 }
             } else {
-                $('.custom-header-title').html('<span class="title-text"><em class="title_icon icon_vip"></em>订阅管理-超级订阅</span>')
-                this.subInfoAjax = '/subscribepay/vipsubscribe/getSubBuyMsg?t=' + new Date().getTime()
+                $('.custom-header-title').html('<span class="title-text">订阅管理-免费订阅</span>')
+                this.linkObj.resultview = '/jyapp/vipsubscribe/toVIPViewPage?vSwitch=f'
+                this.subInfoAjax = '/publicapply/free/subscribe'
             }
         },
         // 是否显示切换图标
@@ -97,25 +154,52 @@ var subNode = new Vue({
                 success: function(res) {
                     console.log(res)
                     if(res.data) {
+                        _this.vSwitch = res.data.vt || 'f'
+                        // f 免费 m 大会员 v 超级订阅
                         if(res.data.vt == 'm') {
                             _this.vipLink = 'javascript:;'
                             _this.arrowShow = false
                             sessionStorage.setItem('switch-product','bigmember')
                             _this.subInfoAjax = '/bigmember/use/info?t=' + new Date().getTime()
-                        } else {
+                        } else if (res.data.vt == 'v') {
                             _this.vipLink = '/jyapp/vipsubscribe/vipsubscribe_renew'
                             _this.arrowShow = true
                             sessionStorage.setItem('switch-product','supervip')
+                            $('.update_renew').show()
+                            $('.super-title').show();
                             _this.subInfoAjax = '/subscribepay/vipsubscribe/getSubBuyMsg?t=' + new Date().getTime()
+                        } else {
+                            _this.vipLink = 'javascript:;'
+                            _this.arrowShow = false
+                            _this.subInfoAjax = '/publicapply/free/subscribe'
+                            sessionStorage.setItem('switch-product', 'free')
                         }
                         let bms = sessionStorage.getItem('big_member_status')
                         _this.initPage(bms)
                         if(bms) {
                             _this.memberStatus = bms
                         }
+                        if (_this.vSwitch === 'f') {
+                            // 判断是否购买省份订阅包
+                            _this.getUserSubscribe()
+                            $('.update_renew').hide()
+                        } else {
+                            $DoPost('/subscribepay/vipsubscribe/getSubBuyMsg', {}, function(sum) {
+                                if(sum.success) {
+                                    getDataWitXHR(sum)
+                                }
+                            })
+                        }
                     }
                 }
             })
+        },
+        // 点击广告跳转超级订阅落地页
+        toPaySupSub: function() {
+            if (this.vSwitch === 'f') {
+                var href = '/jyapp/vipsubscribe/introducePage'
+                location.href = href
+            }
         }
     }
 })
@@ -237,9 +321,8 @@ $(function () {
       }
       $(".list-content").html(returnHtml);
   }
-  function getDataWitXHR() {
+  window.getDataWitXHR = function (res) {
       $DoPost(subNode.subInfoAjax, {}, function (r) {
-          let res  = resObj
           let switchProduct = sessionStorage.getItem('switch-product')
           if(switchProduct) {
               if(switchProduct == 'bigmember') {
@@ -269,11 +352,12 @@ $(function () {
                     res.data.startTime = r.data.member_starttime
                     res.data.endTime = r.data.member_endtime
                   }
-              }else {
+              } else if (switchProduct == 'free') {
+                subNode.initData = r.data
+              } else {
                 res = r
               }
           }
-          if (!res.success) return;
           if(!res.data.industry) {
               res.data.industry = []
           }
@@ -292,16 +376,6 @@ $(function () {
           init(res.data)
       })
   }
-  var resObj = {}
-  // 每次请求接口
-  console.log(document.referrer)
-  let subUrl = '/subscribepay/vipsubscribe/getSubBuyMsg'
-    $DoPost(subUrl, {}, function(sum) {
-        if(sum.success) {
-            resObj = sum
-            getDataWitXHR()
-        }
-    })
 
   // 设置已选择的区域和行业
   function setSelectedAreaAndInd(selected) {
@@ -343,13 +417,14 @@ $(function () {
   // 设置已购买的区域和行业
   function setBuyAreaAndInd(buySet) {
       // 设置已购买区域
-      var buySetCitySum = arrSum(buySet.newcitys)
+      if (buySet) {
+        var buySetCitySum = arrSum(buySet.newcitys)
+      }
       var text = {
           p: buySet.areacount === 0 ? '' : buySet.areacount + '个省',
           c: buySetCitySum === 0 ? '' : buySetCitySum + '个市',
           s: buySet.newcitys.length === 1 ? '' : '(分布在' + buySet.newcitys.length + '个省内)'
       }
-
       if (buySet.areacount === -1) {
           $('.vip-body .area .buy-set-area').text('全国')
       } else {
@@ -570,11 +645,12 @@ $(function () {
       checkmerge(state.industry, state.isread)
       // init 已选择的区域和行业
       // var selectedAreaAndInd = getBuySet(state.area, state.industry);
-      // 2021-5-21修改 初始化已选择的区域和行业 
+      // 2021-5-21修改 初始化已选择的区域和行业
       var selectedAreaAndInd = getSelectBuyset(state.area, state.industry)
       setSelectedAreaAndInd(selectedAreaAndInd);
       // 初始化,已购买的城市和行业
       setBuyAreaAndInd(state.buyset);
+
       //是否提示即将到期
       showTimeOut(state.endTime, state.isTrial);
       selectTime = sessionStorage.getItem("vip_change_time");

+ 10 - 6
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_order_detail.js

@@ -30,11 +30,11 @@ $(function () {
                     $(".productType").text("超级订阅(试用)");
                 }
             }
-            if (r.data.order.discount_price==undefined) {
+            if (!r.data.order.discount_price || (r.data.order.discount_price && r.data.order.discount_price <= 0)) {
             		$(".discountPrice").parent().hide();
             }
             //价格
-            $(".price").text("¥ " + formatMoney(parseFloat(r.data.order.order_money) / 100));
+            $(".price").text("¥ " + formatMoney(parseFloat(r.data.order.pay_money  || r.data.order.order_money) / 100));
             $(".totalPrice").text("¥ " + formatMoney(parseFloat(r.data.order.order_money) / 100) + "元");
             if (!r.data.order.isLiveActive) {
                 $(".origin-price-container").hide();
@@ -304,9 +304,11 @@ $(function () {
                   discount_price = r.data.order.discount_price;
                   var totalPrice = Number(r.data.order.discount_price)+Number(r.data.order.order_money);
                   $(".totalPrice").text('¥'+ formatMoney(totalPrice / 100)+'元')
-                  $(".discountPrice").text('-¥'+ formatMoney(parseFloat(r.data.order.discount_price) / 100)+'元')
+                  if (r.data.order.discount_price && r.data.order.discount_price > 0) {
+                    $(".discountPrice").text('-¥'+ formatMoney(parseFloat(r.data.order.discount_price) / 100)+'元')
+                  }
                 }
-                $(".payPrice").text("¥ " + formatMoney(parseFloat(r.data.order.order_money) / 100) + "元");
+                $(".payPrice").text("¥ " + formatMoney(parseFloat(r.data.order.pay_money || r.data.order.order_money) / 100) + "元");
                 //未支付
                 $("#card-header-bg").addClass("bg nopay-bg")
                 $("#pageTitle").addClass("status")
@@ -358,9 +360,11 @@ $(function () {
                   discount_price = r.data.order.discount_price;
                   var totalPrice = Number(r.data.order.discount_price)+Number(r.data.order.order_money);
                   $(".totalPrice").text('¥'+ formatMoney(totalPrice / 100)+'元')
-                  $(".discountPrice").text('-¥'+ formatMoney(parseFloat(r.data.order.discount_price) / 100)+'元')
+                  if (r.data.order.discount_price && r.data.order.discount_price > 0) {
+                    $(".discountPrice").text('-¥'+ formatMoney(parseFloat(r.data.order.discount_price) / 100)+'元')
+                  }
                 }
-                $(".payPrice").text("¥ " + formatMoney(parseFloat(r.data.order.order_money) / 100) + "元");
+                $(".payPrice").text("¥ " + formatMoney(parseFloat(r.data.order.pay_money || r.data.order.order_money) / 100) + "元");
 
 
 

+ 25 - 18
src/jfw/modules/app/src/web/staticres/jyapp/wxtsguide/main.js

@@ -56,24 +56,31 @@ var Guide = {
 		});
 	},
 	//跳过向导
-	skip: function(){
-		$.post("/jyapp/tenderSubscribe/guide",{reqType: "over"},function(){
-      var guideKey = localStorage.tsGuide_keywords
-      if(localStorage){
-        localStorage.tsGuide_status = "1";
-        localStorage.removeItem("tsGuide_selectIndustrys");
-        localStorage.removeItem("tsGuide_keywords");
-        localStorage.removeItem("tsGuide_preview");
-        localStorage.removeItem("tsGuide_step");
-      }
-			if (!mySysIsIos()){
-				JyObj.finishGuide();
-      }
-      if (guideKey) {
-        window.location.replace('/jyapp/wxkeyset/keyset/index')
-      } else {
-        window.location.replace('/jyapp/wxkeyset/keyset/filterset?type=add&index=0&from=guide')
-      }
+	skip: function(index){
+		$.post("/jyapp/tenderSubscribe/guide",{reqType: "over",index:index},function(r){
+		    var guideKey = localStorage.tsGuide_keywords
+		      if(localStorage){
+		        localStorage.tsGuide_status = "1";
+		        localStorage.removeItem("tsGuide_selectIndustrys");
+		        localStorage.removeItem("tsGuide_keywords");
+		        localStorage.removeItem("tsGuide_preview");
+		        localStorage.removeItem("tsGuide_step");
+		    }
+			//Android客户端没有使用
+//			if (!mySysIsIos()){
+//				JyObj.finishGuide();
+//		    }
+			
+			if (guideKey) {
+		        window.location.replace('/jyapp/vipsubscribe/toSubVipSetPage')
+		    } else {
+		        window.location.replace('/jyapp/vipsubscribe/toSetKeyWordPage?type=add&index=0&from=guide')
+		    }
+//		    if (guideKey) {
+//		        window.location.replace('/jyapp/wxkeyset/keyset/index')
+//		    } else {
+//		        window.location.replace('/jyapp/wxkeyset/keyset/filterset?type=add&index=0&from=guide')
+//		    }
 		});
 	},
 	//下一步

+ 129 - 0
src/jfw/modules/app/src/web/templates/areaPack/page_buy.html

@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <!--引入公共资源头部-->
+    {{include "/big-member/meta.html"}}
+    <title></title>
+    <!--S-当前页面的css资源-->
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/j-icons.css?v={{Msg "seo" "version"}}'>
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/coupon/css/pay-order-template.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/area-pack/css/buy.css?v={{Msg "seo" "version"}}' />
+</head>
+<body>
+  <div class="j-container">
+    {{include "/big-member/header.html"}}
+    <div class="j-main" id="app" v-cloak>
+      <div class="j-container">
+        <div class="j-main">
+          <div class="area-count-cell clickable" @click="toBuyArea">
+            <div class="area-count-content">
+              <div class="a-c-l">
+                <div class="a-c-label">省份数量</div>
+                <van-tag round color="#2abed1" text-color="#fff">已选:${ selectAreaCount === -1 ? '全国' : selectAreaCount }</van-tag>
+              </div>
+              <div class="a-c-r" v-if="buyType !== 'renew'">
+                <div class="a-c-area-text ellipsis">${ selectAreaText }</div>
+                <van-icon name="arrow"></van-icon>
+              </div>
+            </div>
+            <div class="area-count-footer" v-if="selectAreaCount >= 0 && (buyType === 'buy' || buyType === 'renew') && alreadyBuyInfo.loaded">
+              <span class="van-tag van-tag--round default" v-if="(selectAreaCount > priceInfo.provinceFreeCount) || (buyType === 'renew')">本次${ buyTypeText }省份数量:${ buyAreaText }</span>
+              <span class="van-tag van-tag--round red" v-else-if="selectAreaCount >= 0 && selectAreaCount <= priceInfo.provinceFreeCount && alreadyBuyInfo.loaded">${ priceInfo.provinceFreeCount } 个省份免费,请增加省份数量再进行购买</span>
+            </div>
+            <div class="area-count-footer" v-if="buyType === 'upgrade' && selectAreaCount !== -1 && alreadyBuyInfo.loaded">
+              <span class="van-tag van-tag--round default" v-if="upgradeAreaCount > 0">本次${ buyTypeText }省份数量:${ upgradeAreaText  }</span>
+              <span class="van-tag van-tag--round red" v-else>无法升级,选择省份数量需大于原套餐数</span>
+            </div>
+          </div>
+          <div class="spec-list-container border-line-t" v-if="buyType !== 'upgrade'">
+            <div class="spec-title" v-show="specTitleShow">请选择规格</div>
+            <div class="spec-list">
+              <div
+                class="spec-item"
+                :class="{ active: item.cycleType == specActive }"
+                v-for="(item, index) in specList"
+                @click="clickSpec(item)"
+                :key="index">
+                <span class="preferential-tag" v-if="preferentialShow">限时x折</span>
+                <div class="spec-i-label">
+                  <span class="spec-i-l-text">${item.label}</span>
+                  <span class="spec-i-l-info" v-if="item.labelSubInfo" v-html="item.labelSubInfo"></span>
+                </div>
+                <div class="spec-i-sub">
+                  <div class="spec-i-text del" v-show="item.before">&yen; ${ item.before || 0 }</div>
+                  <div class="spec-i-text"><span>&yen;</span> <span class="price-count">${ item.price }</span></div>
+                </div>
+                <div class="spec-i-desc">${ item.desc }</div>
+              </div>
+            </div>
+          </div>
+          <div class="order-phone-group" :class="{ error: !validatorPhonePass }">
+            <label for="order_phone">手机号码</label>
+            <input id="order_phone" v-model="userInfo.phone" autocomplete='off' placeholder='请输入手机号码' maxlength='11' type='tel' />
+            <p class="error-message">手机号码输入错误</p>
+          </div>
+          <div class="notes-to-buy">
+            <p class="notes-title pre-line">省份订阅包说明</p>
+            <section class="notes-section">
+              <p class="notes-section-title">权益说明</p>
+              <div class="notes-section-content">
+                1、支持免费订阅用户增加订阅区域时使用,订阅每增加1个省份,均可获取该省的招标采购信息。<br />
+                2、订阅的省份共享10组关键词,获取商机信息更全面。<br />
+                3、针对增购的省份,在使用有效期内享有免费订阅省份全部权益。
+              </div>
+            </section>
+            <section class="notes-section">
+              <p class="notes-section-title">购买须知</p>
+              <div class="notes-section-content" v-if="buyType === 'buy' || buyType === 'renew'">
+                1、省份订阅包是按时间(月/季/年)、订阅省份个数计算费用,其中${ priceInfo.provinceFreeCount }个省份免费,超过${ priceInfo.provinceMaxCount }个省则按照全国计价。<br />
+                2、订购后立即生效,产品自购买之日起计算周期。<br />
+                3、订阅区域每月可修改次数为可订阅省份数量,购买全国不限制修改次数。
+              </div>
+              <div class="notes-section-content" v-if="buyType === 'upgrade'">
+                1、省份订阅包升级不改变您原有订阅周期,只增加省份数量。<br />
+                2、省份订阅包是按时间、订阅省份个数计算费用,其中${ priceInfo.provinceFreeCount }个省份免费,超过${ priceInfo.provinceMaxCount }个省则按照全国计价;从升级之日起到原订阅周期结束之日,计算升级价格,不足月价格将按照整月计费。<br />
+                3、订阅区域每月可修改次数为可订阅省份数量,购买全国不限制修改次数。
+              </div>
+            </section>
+          </div>
+        </div>
+        <div class="j-footer">
+          <pay-order-template ref="couponRef" :config="bottomConf" @update="updateS" @save="savePageState" @update-coupon="afterUpdateCoupon"></pay-order-template>
+        </div>
+      </div>
+      <van-popup v-model="dialog.backTip" get-container="body" class="back-tip-wrapper" :close-on-click-overlay="false">
+        <div class="b-t-title">
+          <img src="/common-module/area-pack/images/messageTitle@3x.png" alt="">
+        </div>
+        <div class="b-t-content">
+          <div class="b-t-content-item">
+            多订阅1个省份,获取商机概率<br />增加一倍,邀您体验!
+          </div>
+          <div class="b-t-content-item bg-f-orange">
+            支持用户增加订阅区域时使用,每增购1个省可获取该省的招标采购信息
+          </div>
+          <div class="b-t-content-item bg-f-orange">
+            按时间(月/季/年)、订阅省份个数计价,${perMonthArea}元省/月起。
+          </div>
+        </div>
+        <div class="b-t-footer">
+          <button class="button cancel" @click="dialog.backTip = false;history.back()">取消</button>
+          <button class="button confirm" @click="dialog.backTip = false">去购买</button>
+        </div>
+      </van-popup>
+    </div>
+  </div>
+  <!--S-当前页面的资源-->
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+  {{include "/big-member/commonjs.html"}}
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/coupon/js/pay-order-template.js?v={{Msg "seo" "version"}}'></script>
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/area-pack/js/buy.js?v={{Msg "seo" "version"}}'></script>
+  <!--E-当前页面的资源-->
+</body>
+
+</html>

+ 54 - 0
src/jfw/modules/app/src/web/templates/areaPack/page_buy_area.html

@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html lang="zh-CN" style="font-size: 50px;">
+<head>
+    <title>选择省份</title>
+
+    <!--引入公共资源头部-->
+    {{include "/big-member/meta.html"}}
+</head>
+<body>
+    <script>
+        window.__page_config = {
+            onlyProvince: true
+        }
+    </script>
+    <!-- 设置区域主要内容 -->
+    {{include "/big-member/component_set_area.html"}}
+    <!-- 自定义set-header内容 -->
+    <script>
+        var buyAreaFn = {
+            conf: {
+                sKey: '$data-area-pack-buy'
+            },
+            buyPageInfo: {},
+            init: function () {
+                // 恢复页面状态
+                var pageInfo = sessionStorage.getItem(this.conf.sKey)
+                if (pageInfo) {
+                    this.buyPageInfo = JSON.parse(pageInfo)
+                    var areaInfo = this.buyPageInfo.areaInfo
+                    if (this.buyPageInfo && areaInfo && Object.keys(areaInfo).length !== 0) {
+                        vNode.data.initCityMap = areaInfo
+                        vueComponent.setCitySelected(areaInfo)
+                    }
+                }
+            },
+            saveToSessionStorage: function (data) {
+                sessionStorage.setItem(this.conf.sKey, JSON.stringify(data))
+            }
+        }
+        buyAreaFn.init()
+        // 以下均为示例:具体使用时候请删除
+        // 定义重置方法:方法名必须为onReset/onConfirm
+        // 参数,是被初始化的数据
+        function onReset (initData) {}
+        // 被选中的数据
+        function onConfirm (selectedData) {
+            var buyPageInfo = buyAreaFn.buyPageInfo
+            buyPageInfo.areaInfo = selectedData
+            buyAreaFn.saveToSessionStorage(buyPageInfo)
+            history.back()
+        }
+    </script>
+</body>
+</html>

+ 350 - 0
src/jfw/modules/app/src/web/templates/areaPack/page_set_area.html

@@ -0,0 +1,350 @@
+<!DOCTYPE html>
+<html lang="zh-CN" style="font-size: 50px;">
+<head>
+    <title>选择省份</title>
+    <!--引入公共资源头部-->
+    {{include "/big-member/meta.html"}}
+
+    <style>
+        .wrapper-header > .content {
+            width: 100%;
+            height: 2.2rem;
+            padding: 0 0.32rem;
+            background: #FFFFFF;
+            box-shadow: 0rem 0.04rem 0.16rem 0.02rem rgba(54, 147, 179, 0.05);
+        }
+        .wrapper-header .selectNumMax {
+            height: 0.84rem;
+            line-height: 0.84rem;
+            font-size: 0.26rem;
+            font-weight: 500;
+            color: #161826;
+        }
+        .wrapper-header .selectNumList {
+            line-height: 0.84rem;
+            font-size: 0.26rem;
+            font-weight: 500;
+            color: #161826;
+        }
+        .moreTips {
+            width: 4.72rem;
+            height: 0.4rem;
+            background: rgba(250,72,60,0.1);
+            border-radius: 0.2rem 0.2rem 0.2rem 0.2rem;
+            padding: 0.02rem 0.16rem;
+            font-size: 0.22rem;
+            font-weight: 500;
+            color: #FA483C;
+            box-sizing: border-box;
+        }
+        .selectChange {
+            font-size: 0.24rem;
+            font-weight: 500;
+            color: #2ABDD1;
+            margin-left: 1.02rem;
+        }
+        .numColor {
+            color: #5E5E64;
+            padding-left: 0.24rem;
+        }
+        .string {
+            width: 100%;
+            height: 0.01rem;
+            background: rgba(0, 0, 0, 0.05);
+        }
+        .popup-wrap {
+            position: fixed;
+            top: 0;
+            left: 0;
+            right: 0;
+            bottom: 0;
+            z-index: 99999;
+            background-color:rgba(0, 0, 0, 0.7);
+        }
+        .popup-content {
+            width: 6.06rem;
+            height: 2.8rem;
+            background: #FFFFFF;
+            border-radius: 0.16rem 0.16rem 0.16rem 0.16rem;
+            position: fixed;
+            top: 50%;
+            left: 50%;
+            transform: translateX(-50%) translateY(-50%);
+            z-index: 100;
+        }
+        .popup-text{
+            text-align: left;
+            padding: 0.48rem 0.6rem 0.42rem;
+            line-height: 0.48rem;
+            font-size: 0.32rem;
+            font-weight: 500;
+            color: #161826;
+        }
+        .popup-btnWrap{
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            border-top:0.02rem solid rgba(0, 0, 0, 0.1) ;
+        }
+        .popup-btn{
+            font-size: 0.36rem;
+            font-weight: 500;
+            color: #161826;
+            width: 50%;
+            height: 0.92rem;
+            line-height: 0.92rem;
+            text-align: center;
+            cursor: pointer;
+        }
+        .popup-line{
+            height: 0.92rem;
+            width: 0.02rem;
+            background-color: rgba(0, 0, 0, 0.1);
+        }
+        .levelUp {
+            color: #2ABDD1;
+        }
+    </style>
+</head>
+<body>
+    <script>
+        window.__page_config = {
+            onlyProvince: true
+        }
+    </script>
+    <!-- 设置区域主要内容 -->
+    {{include "/big-member/component_set_area.html"}}
+    <!-- 自定义set-header内容 -->
+    <div id="set-header-template" v-cloak>
+        <div class="wrapper-header" id="thisAreaTips">
+            <div class="content">
+                <div class="selectNumMax">可选择<span class="numColor" id="canSelect">${ maxSelectText }</span></div>
+                <div class="string"></div>
+                <div class="selectNumList">
+                    <span>已选择<span class="numColor" id="thisSelect">${ selectedAreaText }</span></span>
+                    <span class="moreTips" v-show="moreThanSubCount" @click="toPay">超出可订阅省份数量,前往${ buyType }省份订阅包 &gt;</span>
+                </div>
+                <div class="selectChange"></div>
+            </div>
+            <div class="popup-wrap" v-show="popupTip">
+                <div class="popup-content">
+                    <div class="popup-text" id="tips-text">您当前仅可订阅${ maxSelectText },如需增加请${ buyType }【省份订阅包】</div>
+                    <div class="popup-btnWrap">
+                        <div class="popup-btn" id="cancel" @click="hideTips">取消</div>
+                        <div class="popup-line"></div>
+                        <div class="popup-btn levelUp" id="btn-text" @click="toPay">去${ buyType }</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <script>
+        var vm = new Vue({
+            delimiters: ['${', '}'],
+            el: '#set-header',
+            template: '#set-header-template',
+            data: {
+                sessKey: 'sub_free_set_area',
+                selectedArea: '',
+                userSubInfo: {
+                    area: '',
+                    areanum: 0, // 可修改次数
+                    basenum: 1,
+                    provincenum: 0, // 购买的省份数量
+                },
+                popupTip: false
+            },
+            computed: {
+                moreThanSubCount: function () {
+                    var max = this.maxSelectCount
+                    var sel = this.selectedAreaCount
+                    if (max === -1) return false
+                    if (sel === -1) return true
+                    if (sel > max) return true
+                },
+                maxSelectCount: function () {
+                    var baseNum = this.userSubInfo.basenum || 1
+                    var provincenum = this.userSubInfo.provincenum
+                    if (provincenum === -1) {
+                        return provincenum
+                    } else {
+                        return provincenum + baseNum
+                    }
+                },
+                maxSelectText: function () {
+                    if (this.maxSelectCount === -1) {
+                        return '全国'
+                    } else {
+                        return this.maxSelectCount + '个省'
+                    }
+                },
+                selectedAreaCount: function () {
+                    var area = this.selectedArea
+                    if (area) {
+                        var keys = Object.keys(area)
+                        if (keys.length === 0) {
+                            return -1
+                        } else {
+                            return keys.length
+                        }
+                    } else {
+                        return 0
+                    }
+                },
+                selectedAreaText: function () {
+                    if (this.selectedAreaCount === -1) {
+                        return '全国'
+                    } else {
+                        return this.selectedAreaCount + '个省'
+                    }
+                },
+                // 是否购买了省份订阅包
+                userType: function () {
+                    if (this.userSubInfo.provincenum === -1) return true
+                    return this.userSubInfo.provincenum !== 0
+                },
+                buyType: function () {
+                    return this.userType ? '升级' : '购买'
+                },
+            },
+            mounted: function () {
+                var type = utils.getParam('type')
+                var restore = this.restoreState()
+
+                if (restore) {
+                    this.initPageInfo()
+                } else {
+                    if (type === 'new') {
+                        this.setAreaAllNotSelected()
+                    } else {
+                        this.getUserSubscribe()
+                    } 
+                }
+            },
+            methods: {
+                initPageInfo: function () {
+                    var area = this.selectedArea
+                    this.setComponentState(area)
+                },
+                setAreaSelected: function (area) {
+                    this.$set(this, 'selectedArea', area)
+                },
+                setComponentState: function (area) {
+                    vNode.data.initCityMap = area
+                    vueComponent.setCitySelected(area)
+                },
+                setAreaAllNotSelected: function () {
+                    vueComponent.setCitySelected()
+                    vueComponent.provinceListMap['#'][0].selectedState = ''
+                    $('#set-area .j-button-confirm').prop('disabled', true)
+                },
+                // 获取用户订阅信息
+                getUserSubscribe: function () {
+                    var _this = this
+                    $.ajax({
+                        url: '/publicapply/free/subscribe',
+                        type: 'POST',
+                        success: function (res) {
+                            if (res && res.error_code === 0) {
+                                if (res.data) {
+                                    if (res.data.area === null || res.data.area === undefined) {
+                                        _this.setAreaAllNotSelected()
+                                    } else {
+                                        if (res.data.area) {
+                                            // 赋值默认已选
+                                            _this.setAreaSelected(res.data.area)
+                                        }
+                                        for (var key in res.data) {
+                                            _this.$set(_this.userSubInfo, key, res.data[key])
+                                        }
+                                        _this.initPageInfo()
+                                    }
+                                }
+                            } else {
+                                if (res.error_msg) {
+                                    _this.$toast(res.error_msg)
+                                }
+                            }
+                        }
+                    })
+                },
+                userUpdate: function (area) {
+                    var _this = this
+                    $.ajax({
+                        url: '/publicapply/subscribe/update',
+                        type: 'POST',
+                        data: {
+                            vSwitch: 'f',
+                            area: JSON.stringify(area)
+                        },
+                        success: function (res) {
+                            if (res && res.success) {
+                                history.back()           
+                            } else {
+                                if (res.errMsg) {
+                                    _this.$toast(res.errMsg)
+                                }
+                            }
+                        }
+                    })
+                },
+                confirmed: function (area) {
+                    this.setAreaSelected(area)
+                    if (this.moreThanSubCount) {
+                        this.popupTip = true
+                    } else {
+                        this.userUpdate(area)
+                    }
+                },
+                hideTips: function () {
+                    this.popupTip = false
+                },
+                toPay: function () {
+                    this.popupTip = false
+                    var area = this.selectedArea
+                    var urlBase = '/jyapp/areaPack/page/buy'
+                    var areaJSON = encodeURIComponent(JSON.stringify(area))
+                    this.savePageState()
+                    if (this.userType) {
+                        location.href = urlBase + '?type=upgrade&area=' +  areaJSON
+                    } else {
+                        location.href = urlBase +  '?type=buy&area=' +  areaJSON
+                    }
+                },
+                restoreState: function () {
+                    var $data = sessionStorage.getItem(this.sessKey)
+                    if ($data) {
+                        $data = JSON.parse($data)
+
+                        this.selectedArea = $data.selectedArea
+                        Object.assign(this.userSubInfo, $data.userSubInfo)
+
+                        sessionStorage.removeItem(this.sessKey)
+                    }
+                    return !!$data
+                },
+                savePageState: function () {
+                    var data = {
+                        selectedArea: this.selectedArea,
+                        userSubInfo: this.userSubInfo
+                    }
+                    sessionStorage.setItem(this.sessKey, JSON.stringify(data))
+                },
+            }
+        })
+
+        function onReset (initData) {
+            vm.setAreaSelected(initData)
+        }
+        // 被选中的数据
+        function onConfirm (selectedData) {
+            vm.confirmed(selectedData)
+        }
+        // 页面选中状态改变时触发
+        function onChange (selectedData) {
+            vm.setAreaSelected(selectedData)
+            $('#set-area .j-button-confirm').prop('disabled', false)
+        }
+    </script>
+</body>
+</html>

+ 6 - 3
src/jfw/modules/app/src/web/templates/big-member/component_set_area.html

@@ -18,6 +18,7 @@
         }
     </style>
     {{include "/big-member/header.html"}}
+    <div id="set-header" v-cloak></div>
     <div id="set-area" class="j-main" v-cloak>
         <div class="j-container">
             <div class="j-header"></div>
@@ -29,7 +30,9 @@
                             <div class="province-item bg-white tab_content" v-if="province.name == '全国'">
                                 <button
                                     class="j-button-item"
-                                    :class="province.selectedState ? 'active': ''"
+                                    :class="{
+                                        active: province.selectedState
+                                    }"
                                     @click="changeCityState(province, '#')">${province.name}</button>
                             </div>
                             <div class="province-item bg-white" v-else>
@@ -40,14 +43,14 @@
                                     </div>
                                     <span style="flex: 1; height: .3rem;" @click="changeExpandState($event, province)"></span>
                                     <span
-                                        v-if="province.canExpanded"
+                                        v-if="province.canExpanded && !config.onlyProvince"
                                         :class="province.expanded ? '' : 'rotate180'"
                                         @click="changeExpandState($event, province)">
                                         <i class="j-icon base-icon icon-arrow-up"></i>
                                     </span>
                                 </div>
                                 <transition name="fade" @after-leave="onTransitionEnd" @after-enter="onTransitionEnd">
-                                    <div v-show="province.expanded" class="tab_content">
+                                    <div v-show="province.expanded && !config.onlyProvince" class="tab_content">
                                         <div class="content">
                                             <button v-for="(city, iii) in province.children" :key="iii*3"
                                                 class="j-button-item"

+ 2 - 2
src/jfw/modules/app/src/web/templates/big-member/component_set_cate.html

@@ -5,8 +5,8 @@
 <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
 <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
 <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+<link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/weui/2.0.1/weui.min.css />
 <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/vant-reset.css?v={{Msg "seo" "version"}}' />
-<link rel="stylesheet" href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.css">
 <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/set_area_industry_cate.css?v={{Msg "seo" "version"}}' />
 
 <div class="j-container">
@@ -91,6 +91,6 @@
 <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
 <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
 <script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
-<script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.js"></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/weui.js/1.2.1/weui.min.js></script>
 {{include "/big-member/commonjs.html"}}
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/set_cate.js?v={{Msg "seo" "version"}}'></script>

+ 1 - 0
src/jfw/modules/app/src/web/templates/big-member/component_set_infotype.html

@@ -11,6 +11,7 @@
 <!-- 采购单位行业 -->
 <div class="j-container">
     {{include "/big-member/header.html"}}
+    <div id="set-header" v-cloak></div>
     <div id="set-info-type" class="j-main" v-cloak>
         <div class="j-container">
             <div class="j-header"></div>

+ 42 - 16
src/jfw/modules/app/src/web/templates/big-member/page_analysis_result.html

@@ -22,7 +22,7 @@
 <body>
 <div class="j-container">
     {{include "/big-member/header.html"}}
-    <div class="j-main" id="analysis-result" v-cloak>
+    <div class="j-main" id="analysis-result" v-cloak ref="wrapper">
         <!-- 骨架屏 -->
         <div class="skeleton" v-if="skeletonShow">
             <img class="working" src="/jyapp/big-member/image/working.gif" alt="">
@@ -71,7 +71,7 @@
             </div>
             <div class="contents">
                 <div class="tabs" ref="backTop">
-                    <van-tabs v-model="active" background="#fff" title-active-color="#2ABED1" line-width="24" sticky :offset-top="stickyTop">
+                    <van-tabs v-model="active" background="#fff" title-active-color="#2ABED1" line-width="24" sticky offset-top="21.33333vw" @click="onTabClick">
                         <van-tab title="类似项目分析">
                             <div class="tab-item">
                                 <div class="summary">
@@ -133,25 +133,40 @@
                                                 <span v-else class="index">${i + 1}</span>
                                                 <span class="title" @click="goEntImg(hs.entId)">${hs.key}</span>
                                             </div>
-                                            <div class="company-info">
-                                                <span>项目数量:${hs.doc_count}个</span>
-                                                <span>项目金额:${formatterMoney(hs.total_project)}</span>
-                                                <span>注册资本:${formatterMoney(hs.capital)}</span>
+                                            <div class="win-capital">注册资本:${formatterMoney(hs.capital)}</div>
+                                            <div class="win-info" @click="goDetail(hs.key)">
+                                              <div class="w-title">
+                                                <span class="w-title-label">类似项目明细</span>
+                                                <van-icon class="win-arrow" name="arrow"></van-icon>
+                                              </div>
+                                              <div class="company-info">
+                                                <span>项目数量:${hs.doc_count}个</span>
+                                                <span>项目金额:${formatterMoney(hs.total_project)}</span>
+                                                <!-- <span>注册资本:${formatterMoney(hs.capital)}</span> -->
+                                                <span>最近中标:${formatterTime(hs.max_jytime)}</span>
+                                              </div>
                                             </div>
-                                            <div class="same-history" v-if="hs.buyer_similar_list.doc_count > 0 || hs.buyer_similar_list.total_project > 0">
-                                                <div class="same-title">与${hs.buyer_similar_list.buyer}有类似项目合作历史</div>
+                                            
+                                            <div class="same-history" v-if="hs.buyer_similar_list.doc_count > 0 || hs.buyer_similar_list.total_project > 0" @click="goDetail(hs.key, hs.buyer_similar_list.buyer)">
+                                                <div class="same-title">
+                                                  <span>与${hs.buyer_similar_list.buyer}有<em class="highLight">类似项目</em>合作历史</span>
+                                                  <van-icon class="win-arrow" name="arrow"></van-icon>
+                                                </div>
                                                 <div class="same-info">
                                                     <span>项目数量:${hs.buyer_similar_list.doc_count}个</span>
                                                     <span>项目金额:${formatterMoney(hs.buyer_similar_list.total_project)}</span>
-                                                    <span>最近中标时间:${hs.buyer_similar_list.bid_winner_time || '--'}</span>
+                                                    <span>最近中标:${hs.buyer_similar_list.bid_winner_time || '--'}</span>
                                                 </div>
                                             </div>
-                                            <div class="other-history" v-if="hs.buyer_other_list.doc_count > 0 || hs.buyer_other_list.total_project > 0">
-                                                <div class="other-title">与${hs.buyer_other_list.buyer}有其他项目合作历史</div>
+                                            <div class="other-history" v-if="hs.buyer_other_list.doc_count > 0 || hs.buyer_other_list.total_project > 0" @click="goOtherDetail(hs.key, hs.buyer_similar_list.buyer)">
+                                                <div class="other-title">
+                                                  <span>与${hs.buyer_other_list.buyer}有<em class="highLight">其他项目</em>合作历史</span>
+                                                  <van-icon class="win-arrow" name="arrow"></van-icon>
+                                                </div>
                                                 <div class="other-info">
                                                     <span>项目数量:${hs.buyer_other_list.doc_count}个</span>
                                                     <span>项目金额:${formatterMoney(hs.buyer_other_list.total_project)}</span>
-                                                    <span>最近中标时间:${hs.buyer_other_list.bid_winner_time || '--'}</span>
+                                                    <span>最近中标:${hs.buyer_other_list.bid_winner_time || '--'}</span>
                                                 </div>
                                             </div>
                                         </div>
@@ -217,6 +232,17 @@
                             </div>
                         </van-tab>
                         <van-tab title="类似项目明细">
+                            <div class="detail-filter" ref="detailFilter">
+                              <van-collapse v-model="activeNames">
+                                <van-collapse-item title="筛选条件" name="1">
+                                  <van-field class="filter-input" v-model="winnerVal" label="中标企业" placeholder="输入中标企业名称" maxlength="50"></van-field>
+                                  <van-field class="filter-input" v-model="buyerVal" label="采购单位" placeholder="输入采购单位名称" maxlength="50"></van-field>
+                                  <div class="d-f-search">
+                                    <span @click="onSearch">搜索</span>
+                                  </div>
+                                </van-collapse-item>
+                              </van-collapse>
+                            </div>
                             <div class="tab-item">
                                 <div class="projects" v-if="projectListDetail.length && projectListDetail.length > 0">
                                     <div v-for="item in projectListDetail" :key="item._id" class="project-list" @click="goProjectDetail(item.infoid)">
@@ -251,7 +277,7 @@
                                                 <span>${item.project_rate || '--'}</span>
                                             </div>
                                         </div>
-                                        <div class="bid-company">
+                                        <div class="bid-company" v-if="item.winnerorder">
                                             <p>中标候选人:</p>
                                             <p v-for="sItem in item.winnerorder">
                                                 ${sItem || '--'}
@@ -259,9 +285,9 @@
                                         </div>
                                     </div>
                                 </div>
-                                <div class="empty" v-else>
-                                    <div class="j-img img-empty empty-img"></div>
-                                    <p class="empty-text">暂无明细</p>
+                                <div class="jy-empty" v-else>
+                                    <div class="jy-empty-img"></div>
+                                    <p class="jy-empty-text" style="padding-bottom: 0.32rem;">暂无明细</p>
                                 </div>
                             </div>
                         </van-tab>

+ 42 - 25
src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait.html

@@ -208,37 +208,63 @@
             <span v-if="isMember && (hasOnePower && surplus && isVip)" class="bid_surplus">剩余:${entvisit.total -
               entvisit.usage}</span>
           </template>
+          <div v-if="!showContacts" style="margin-top: .24rem;">
+            <div style="background: #fff;padding: .24rem .32rem 0;">
+              <span class="win-bid-title">企业通讯录</span>
+            </div>
+            <div class="vip_component"
+            style="height:11.04rem;background:url('/common-module/collection/image/bg/vip_bg_9.png') no-repeat;background-size:100% 100%">
+            <vip-component @tabactive="tabActive" :power="conf" type="item_9" :entvisit="entvisit" :newvip="isVip"
+            imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/image/bg/vip_ex_9.png'></vip-component>
+            </div>
+          </div>
+          <div class="bg-white tab-card cell-list history-list" v-else>
+            <hispro-component type="winner" :id="entInfo.id"></hispro-component>
+          </div>
+          <!-- 高级分析 -->
+          <div class="win-analyse">
+            <span class="win-bid-title">中标分析</span>
+            <div class="high-link" @click="goHighSet">
+              <span>高级分析设置</span>
+              <van-icon name="arrow"></van-icon>
+            </div>
+          </div>
           <div class="bg-white tab-card" v-if="conf._4 && !getStatus">
+            <div class="tab-card-title" style="padding: 0.16rem .32rem .12rem;">中标信息统计结果</div>
             <div class="card-row zb-info">
               <div class="card-column">
                 <div class="ent-info-label">项目数量</div>
-                <div class="ent-info-text">${entPortraitInfo.project_count ? entPortraitInfo.project_count + '个' : '0'}
+                <div class="ent-info-text">${entPortraitInfo.project_count ? entPortraitInfo.project_count + '个' : '--'}
                 </div>
               </div>
               <div class="card-column">
                 <div class="ent-info-label">项目金额</div>
                 <div class="ent-info-text">${entPortraitInfo.bidamount_count ?
-                  utils.moneyUnit(entPortraitInfo.bidamount_count) : '0'}</div>
+                  utils.moneyUnit(entPortraitInfo.bidamount_count) : '--'}</div>
               </div>
               <div class="card-column">
                 <div class="ent-info-label">项目省份</div>
-                <div class="ent-info-text">${entPortraitInfo.area_count ? entPortraitInfo.area_count + '个' : '-'}</div>
+                <div class="ent-info-text">${entPortraitInfo.area_count ? entPortraitInfo.area_count + '个' : '--'}</div>
               </div>
               <div class="card-column">
                 <div class="ent-info-label">项目客户</div>
-                <div class="ent-info-text">${entPortraitInfo.buyer_count ? entPortraitInfo.buyer_count + '个' : '-'}
+                <div class="ent-info-text">${entPortraitInfo.buyer_count ? entPortraitInfo.buyer_count + '个' : '--'}
                 </div>
               </div>
             </div>
             <div class="zb-time-frame border-line-t">
               <span>数据统计范围:</span>
               <span>${entPortraitInfo.timeRangeStart ? new Date(entPortraitInfo.timeRangeStart *
-                1000).pattern('yyyy/MM/dd') : '2016'}</span>
+                1000).pattern('yyyy/MM/dd') : ''}</span>
               <span>-</span>
               <span>${entPortraitInfo.timeRangeEnd ? new Date(entPortraitInfo.timeRangeEnd * 1000).pattern('yyyy/MM/dd')
                 : '至今'}</span>
             </div>
           </div>
+          <div class="jy-empty" v-show="allNot">
+            <div class="jy-empty-img"></div>
+            <p class="jy-empty-text">对不起,没有匹配到相关信息, <br>修改时间范围或换个搜索词试试吧</p>
+          </div>
           <div class="vip_component" v-if="getStatus"
             style="height:2.12rem;background:url('/common-module/collection/image/bg/vip_bg_0.png') no-repeat;background-size:100% 100%">
           </div>
@@ -257,11 +283,11 @@
             <div class="bg-white tab-card cell-list project-news" v-show="conf._13 && topProject.list.length !== 0">
               <div class="tab-card-title">
                 <span class="t-c-t-l">项目动态</span>
-                <span class="t-c-t-r" v-if="isMemberAndSvip" @click="goToFilterProjectNews">
+                <!-- <span class="t-c-t-r" v-if="isMemberAndSvip" @click="goToFilterProjectNews">
                   <div class="link">高级搜索</div>
                   <div class="preferential-tag">New</div>
                 </span>
-                <span v-else></span>
+                <span v-else></span> -->
               </div>
               <div class="tab-card-content">
                 <ul class="project-info-list">
@@ -283,15 +309,6 @@
               </div>
             </div>
           </div>
-          <div class="vip_component" v-if="!showContacts"
-            style="height:11.36rem;background:url('/common-module/collection/image/bg/vip_bg_9.png') no-repeat;background-size:100% 100%">
-            <vip-component @tabactive="tabActive" :power="conf" type="item_9" :entvisit="entvisit" :newvip="isVip"
-              imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/image/bg/vip_ex_9.png'>
-            </vip-component>
-          </div>
-          <div class="bg-white tab-card cell-list history-list" v-else>
-            <hispro-component type="winner" :id="entInfo.id"></hispro-component>
-          </div>
           <div class="bg-white tab-card charts"
             v-if="conf._4 && annualData.rows.length !== 0 && !getStatus">
             <div class="tab-card-title">年度项目统计</div>
@@ -437,22 +454,22 @@
   </div>
 
   <!--S-当前页面的资源-->
-  <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js> </script> <script
-    src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js> </script> <script
-    src=//cdn.jsdelivr.net/npm/echarts@4.8.0/dist/echarts.min.js> </script> <script
-    src=//cdn.jsdelivr.net/npm/v-charts@1.19.0/lib/index.min.js> </script> {{include "/big-member/commonjs.html"}}
-    <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/antiRes/js/mainHook.js?v={{Msg "seo" "version"}}'></script>
-    <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "version"}}'></script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js> </script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js> </script>
+  <script src=//cdn.jsdelivr.net/npm/echarts@4.8.0/dist/echarts.min.js> </script>
+  <script src=//cdn.jsdelivr.net/npm/v-charts@1.19.0/lib/index.min.js> </script> 
+  {{include "/big-member/commonjs.html"}}
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/antiRes/js/mainHook.js?v={{Msg "seo" "version"}}'></script>
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "version"}}'></script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/vip-dialog.js?v={{Msg "seo" "version"}}'>
   </script>
-  <script
-    src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/history-project.js?v={{Msg "seo" "version"}}'>
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/history-project.js?v={{Msg "seo" "version"}}'>
   </script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/echarts_option.js?v={{Msg "seo" "version"}}'>
   </script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/chart_options.js?v={{Msg "seo" "version"}}'>
   </script>
-  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/ent_portrait.js?v={{Msg "seo" "version"}}'>
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/ent_portrait.js?v=0000{{Msg "seo" "version"}}'>
   </script>
 </body>
 

+ 2 - 2
src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait_change.html

@@ -179,8 +179,8 @@ var vNode = {
                 },
                 success: function (res) {
                     if (res.error_code == 0) {
-                        if (res.data && $.isArray(res.data)) {
-                            _this.changeList = _this.sortChangeList(res.data)
+                        if (res.data && $.isArray(res.data.list)) {
+                            _this.changeList = _this.sortChangeList(res.data.list)
                         }
                     } else {
                         // _this.$toast(res.error_msg)

+ 1 - 2
src/jfw/modules/app/src/web/templates/big-member/page_forecast_detail.html

@@ -266,8 +266,7 @@
                     type:'POST',
                     url:'/bigmember/forecast/forPContent',
                     data:{
-                        id: utils.getParam('id'),
-                        keys: that.keys
+                        id: utils.getParam('id')
                     },
                     success:function(res) {
                         console.log(res)

+ 7 - 5
src/jfw/modules/app/src/web/templates/big-member/page_forecast_list.html

@@ -190,7 +190,7 @@
                         <div @click="goDetail(item)">
                             <p class="custom-title">预测采购内容</p>
                             <a href="javascript:;" class="custom-info">
-                                <span v-for="keys in item.results">${keys.keys ? keys.keys.join('、') : ''}</span>
+                                <span v-if="item.purchasing">${item.purchasing.join('、')}</span>
                             </a>
                         </div>
                     </van-step>
@@ -310,7 +310,9 @@
                             if(res.data.list) {
                                 that.loading = false;
                                 res.data.list.forEach(function(v,i){
-                                    v.createtime = v.createtime.replace(/-/g, '/')
+                                    if (v.createtime) {
+                                      v.createtime = new Date(Number(v.createtime + '000')).pattern('yyyy/MM/dd')
+                                    }
                                 })
                                 that.list = that.list.concat(res.data.list);
                                 that.page++;
@@ -342,9 +344,9 @@
             goDetail: function(item) {
                 // console.log(item)
                 var arr = [];
-                item.results.forEach(function(v){
-                    if(v.keys){
-                        arr.push(v.keys.toString())
+                item.purchasing.forEach(function(v){
+                    if(v){
+                        arr.push(v.toString())
                     }
                 })
                 console.log(arr)

+ 144 - 0
src/jfw/modules/app/src/web/templates/big-member/page_free_buyer_project_news.html

@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html lang="zh-CN" style="font-size: 50px;">
+<head>
+    <title>招标动态</title>
+
+    <!--引入公共资源头部-->
+    {{include "/big-member/meta.html"}}
+
+    <!--S-当前页面的css资源-->
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/css/ent_project_news.css?v={{Msg "seo" "version"}}' />
+    <!--E-当前页面的css资源-->
+    <!--临时处理区域选择仅有一个时展示问题-->
+    <style>
+        .select-area-box.j-container.hide-all .van-index-bar__sidebar + .key-card-box {
+            display: none;
+        }
+        .select-area-box.j-container.hide-all .van-index-bar__sidebar + .key-card-box + .key-card-box .area-card-item:after {
+            content: "";
+            position: absolute;
+            right: 0;
+            bottom: 0;
+            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAHHSURBVHgB7ZS/TsJQFMa/tkpIVEIMCRodIMQEZYGBB8An8AWMuOqgbm46uqFPIImzCS9gqrMDYhxYNAwODiQi/iMEe72nUkJJbe/FwuQ33Z57en49t+d+wL98VEovp1WMSUm9sgGm6grGIIKpDEVaj7zDFb1yYMFII+2QYGA47I+NDJjSbwuMsd3BuO/AtF4Ot6EVwFjead9XoAnjk0jL33J8A3JYrAuLueX5AhSF+QKUgf0ZSFZF7sGAsOg7Q198y6pkYEMDl/XKDrmHG2x9MYLz7BKS00FbXIOkyD0UhiO3nO1YFHuJeUQCk6i3O7huvPf2pDp0sion2FY8aq6rb584e6zb9oU7JKvisP1seMqctNeO4QnLlx943pctx3NK+62KYMVMwiySL9/zoi0pGEn1hNEd6/oiAZq8yMyEZoKtgRCF8e5uFBeY44UmyCmHhTiUil7UX7A2N+sJIzGGE0UG5gS15AUjGYoRV2VhP8Vb2OT/sNktLgKDohSruUzN1qGsVS0EA1iNhFB6enaHATXeXc4GJKvSGI5lrUpAPRg9mEcqYlVDiR/jh2JkLJgZEnEP4fpAg390jU/jlaYapbtc5nIw5xuaNAINUmtJBQAAAABJRU5ErkJggg==);
+            width: 14px;
+            height: 14px;
+            background-size: 100% 100%;
+        }
+        .select-area-box.j-container.hide-all .van-index-bar__sidebar + .key-card-box + .key-card-box .area-card-item {
+            position: relative;
+            background: #E8FAFD;
+            color: #2ABED1;
+        }
+    </style>
+</head>
+<body>
+<div class="j-container">
+    {{include "/big-member/header.html"}}
+    <div id="ent-project-news" class="j-main" v-cloak>
+        <div class="j-container search-container">
+            <div class="search-header">
+                <div class="header-ent-name border-line-b clickable">
+                    <span class="j-icon icon-company"></span>
+                    <span class="ent-title">${ entInfo.buyerName }</span>
+                    <!-- <div class="ent-follow">
+                        <span class="j-icon"
+                            :class="!!entInfo.follow ? 'icon-favorite' : 'icon-add-favorite'"
+                            @click="changeFollowState"
+                            v-if="entInfo.followSearchFinish && entInfo.entExist">
+                        </span>
+                        <van-loading v-if="!entInfo.followSearchFinish" size="24px"></van-loading>
+                    </div> -->
+                </div>
+                <!-- <div class="search-input">
+                    <van-search
+                        v-model.trim="searchInfo.content"
+                        @search="doSearch"
+                        maxlength="50"
+                        placeholder="输入关键词">
+                        <template #left-icon>
+                            <span class="j-icon base-icon icon-search"></span>
+                        </template>
+                    </van-search>
+                    <div class="action-text clickable" @click="doSearch">搜索</div>
+                </div>
+                <div class="search-filters">
+                    <van-dropdown-menu :close-on-click-outside="false">
+                        <van-dropdown-item get-container="body" :lazy-render="false" title="搜索范围" ref="matchTypeMenu">
+                            <popup-select-component :data-list="matchTypeList" multiple show-all-button @confirm="pConfirm($event, 'matchType')" ref="matchTypeSelector"></popup-select-component>
+                        </van-dropdown-item>
+                        <van-dropdown-item get-container="body" :lazy-render="false" title="信息类型" class="collection" ref="infoTypeMenu">
+                            <notice-component class="collection" @cancel="cancel" @confirm="confirm" :selectnoticelist="searchFilters.infoType"  ref="infoTypeSelector"></notice-component>
+                        </van-dropdown-item>
+                        <van-dropdown-item get-container="body" :lazy-render="false" title="项目地区" ref="projectAreaMenu">
+                            <area-component :class="{'hide-all': filterInitData.areaArr.length == 2}" ref="projectAreaSelector" @cancel="cancel" @confirm="confirm"></area-component>
+                        </van-dropdown-item>
+                        <van-dropdown-item get-container="body" :lazy-render="false" title="发布时间" ref="publishTimeMenu">
+                            <popup-select-component ref="publishTimeSelector" button-type="button" :data-list="publishTimeList" @confirm="pConfirm($event, 'publishTime')"></popup-select-component>
+                        </van-dropdown-item>
+                    </van-dropdown-menu>
+                </div> -->
+            </div>
+            <div class="j-main" ref="jList">
+                <div class="list-wrapper">
+                    <van-list
+                        v-model="listState.loading"
+                        :finished="listState.finished"
+                        :immediate-check="false"
+                        finished-text=""
+                        @load="onLoad"
+                        class="project-info-list">
+                        <div
+                            v-for="(item, index) in listState.list"
+                            class="project-info-item bg-white border-line-b clickable"
+                            :immediate-check="false"
+                            @click="goToDetail(item)"
+                            :key="item.id">
+                            <div class="project-name">${ item.title }</div>
+                            <div class="project-info">
+                                <span class="tags">
+                                    <span class="tag tag-success" v-if="item.area">${item.area}</span>
+                                    <span class="tag tag-success" v-if="item.bidstatus">${item.bidstatus}</span>
+                                    <span class="tag tag-success" v-if="item.bidamount">${utils.moneyUnit(item.bidamount)}</span>
+                                </span>
+                                <span class="project-time">
+                                    ${item.firsttime ? new Date(item.firsttime * 1000).pattern('yyyy-MM-dd') : '-'}
+                                </span>
+                            </div>
+                        </div>
+                    </van-list>
+                    <div class="empty-container" v-show="listState.list.length === 0 && listState.loaded && !listState.loading">
+                        <div class="empty-content-position">
+                            <div class="image">
+                                <img src="/jyapp/big-member/image/img-empty.png">
+                            </div>
+                            <div class="empty-main tip-text">暂无数据</div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!--S-当前页面的资源-->
+<script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+{{include "/big-member/commonjs.html"}}
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "version"}}'></script>
+<script>
+    var pageInfo = {
+        version: {{Msg "seo" "version"}},
+        platform: 'app'
+    }
+</script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/popup-select-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/notice-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/area-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/js/buyer_project_news.js?v={{Msg "seo" "version"}}'></script>
+</body>
+</html>

+ 2 - 2
src/jfw/modules/app/src/web/templates/big-member/page_free_ent_project_news.html

@@ -53,7 +53,7 @@
                         <van-loading v-if="!entInfo.followSearchFinish" size="24px"></van-loading>
                     </div>
                 </div>
-                <div class="search-input">
+                <!-- <div class="search-input">
                     <van-search
                         v-model.trim="searchInfo.content"
                         @search="doSearch"
@@ -80,7 +80,7 @@
                             <popup-select-component ref="publishTimeSelector" button-type="button" :data-list="publishTimeList" @confirm="pConfirm($event, 'publishTime')"></popup-select-component>
                         </van-dropdown-item>
                     </van-dropdown-menu>
-                </div>
+                </div> -->
             </div>
             <div class="j-main" ref="jList">
                 <div class="list-wrapper">

+ 142 - 0
src/jfw/modules/app/src/web/templates/big-member/page_free_high_set.html

@@ -0,0 +1,142 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+  <!--引入公共资源头部-->
+  {{include "/big-member/meta.html"}}
+  <title></title>
+  <!--S-当前页必定需要预加载的资源-->
+  <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+  <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+  <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+  <!--S-当前页面的css资源-->
+  <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+  <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+  <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+  <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}' />
+  <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/css/high_set.css?v={{Msg "seo" "version"}}' />
+  <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/css/pop_group.css?v={{Msg "seo" "version"}}' />
+  <!--E-当前页面的css资源-->
+  <style>
+    /* 修复微信ios滚动不到最底部的问题,可在微信开发者工具ios下复现 */
+    .fix-ios-scroll {
+      height: unset;
+    }
+    .fix-ios-scroll > .j-main {
+      display: flex;
+      flex-direction: column;
+    }
+    .fix-ios-scroll > .j-main .area-list,
+    .fix-ios-scroll > .j-main .unitTab {
+      height: unset;
+      flex: 1;
+      overflow: auto;
+    }
+  </style>
+</head>
+
+<body>
+  <div class="j-container">
+    {{include "/big-member/header.html"}}
+    <div class="j-main" id="high-set" v-cloak>
+      <div class="j-container">
+        <div class="j-main">
+          <div class="key-container">
+            <p class="key-title">关键词</p>
+            <van-field
+              v-model="conf.keywords"
+              rows="2"
+              autosize
+              type="textarea"
+              maxlength="50"
+              placeholder="多个关键词,用空格隔开"
+              @input="onKeywords"
+              show-word-limit
+            ></van-field>
+            <div class="match-container" v-show="hasSpace">
+              <p class="match-title">分析方式</p>
+              <div class="match-content">
+                <div class="match-item" :class="conf.match == 0 ? 'active' : ''" @click="checkMatch(0)">
+                  <div class="match-value">模糊分析</div>
+                  <div class="match-label">包含其中1个关键词即可</div>
+                </div>
+                <div class="match-item" :class="conf.match == 1 ? 'active' : ''" @click="checkMatch(1)">
+                  <div class="match-value">精准分析</div>
+                  <div class="match-label">同时包含所有关键词</div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="data-container">
+            <van-cell title="项目搜索范围" is-link :value="conf.scope" @click="popClick('scope')"></van-cell>
+            <van-cell title="项目地区" is-link :value="conf.area" @click="popClick('area')"></van-cell>
+            <van-cell title="行业" is-link :value="conf.industry" @click="popClick('industry')"></van-cell>
+          </div>
+          <div class="years-container">
+            <span class="year-label">分析年份</span>
+            <van-field class="year-input" :class="conf.start ? 'border-active' : ''" v-model="conf.start" readonly @click="popClick('start')"></van-field>
+            <em style="color: #ccc;">—</em>
+            <van-field class="year-input"  :class="conf.end ? 'border-active' : ''" v-model="conf.end" readonly @click="popClick('end')"></van-field>
+          </div>
+        </div>
+        <div class="j-footer">
+          <div class="j-button-group">
+            <button class="j-button-cancel" @click="onReset">重置</button>
+            <button class="j-button-confirm" :disabled="disabledConfirm" @click="startStatistic">开始分析</button>
+          </div>
+        </div>
+        <van-popup 
+          class="j-popup collection"
+          v-model="popInfo.show" 
+          round position="bottom" 
+          closeable
+          close-icon="clear"
+          get-container="body"
+        >
+          <div class="j-container">
+            <div class="popup-header header-title">${popInfo.title}</div>
+            <div v-show="popInfo.type == 'scope'">
+              <popup-select-component class="j-main fix-ios-scroll" :data-list="matchTypeList" multiple ref="matchTypeSelector" @reset="onCancel" @confirm="onConfirm"></popup-select-component>
+            </div>
+            <div v-show="popInfo.type == 'area'">
+              <area-component class="j-main fix-ios-scroll" :class="{'hide-all': filterInitData.areaArr.length == 2}" ref="projectAreaSelector" :selectarealist="selectAreaList" @cancel="onCancel" @confirm="onConfirm"></area-component>
+            </div>
+            <div v-show="popInfo.type == 'industry'">
+              <industry-component class="j-main fix-ios-scroll" ref="industryCom" :selectindustrylist="selectIndustryList" onlyshowsome= "true" @cancel="onCancel" @confirm="onConfirm"></industry-component>
+            </div>
+            <div v-show="popInfo.type == 'start'">
+              <years-component ref="yearsItem" type="start" :cur-year="conf.start" :years="startRange" @cancel="onCancel" @confirm="onConfirm"></years-component>
+            </div>
+            <div v-show="popInfo.type == 'end'">
+              <years-component ref="yearsItem" type="end" :cur-year="conf.end" :years="endRange" @cancel="onCancel" @confirm="onConfirm"></years-component>
+            </div>
+          </div>
+        </van-popup>
+      </div>
+    </div>
+  </div>
+
+  <!--S-必定需要预加载的资源-->
+  <link rel="preload" as="script" href=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js />
+  <link rel="preload" as="script" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js />
+  <link rel="preload" as="script" href=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js />
+  <!--E-必定需要预加载的资源-->
+
+  <!--S-有可能需要提前预加载的资源-->
+  <!--E-有可能需要提前预加载的资源-->
+
+  <!--S-当前页面的资源-->
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js> </script> 
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+  <!--E-当前页面的资源-->
+  {{include "/big-member/commonjs.html"}}
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/popup-select-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/date-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/area-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/industry-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/years-picker-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/js/high_set.js?v={{Msg "seo" "version"}}'></script>
+</body>
+
+</html>

+ 210 - 0
src/jfw/modules/app/src/web/templates/big-member/page_free_other_project.html

@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+  <!--引入公共资源头部-->
+  {{include "/big-member/meta.html"}}
+  <title>其他项目明细</title>
+  <!--S-当前页必定需要预加载的资源-->
+  <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+  <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+  <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+  <!--S-当前页面的css资源-->
+  <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+  <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+  <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+  <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/analysis_result.css?v={{Msg "seo" "version"}}' />
+  <!--E-当前页面的css资源-->
+  <style>
+    .other-params{
+      background: #fff;
+    }
+    .params-list{
+      display: flex;
+      align-items: center;
+      padding: .24rem .32rem;
+    }
+    .p-l-label{
+      width: 1.6rem;
+      color: #5F5E64;
+      font-size: .3rem;
+    }
+    .p-l-value{
+      flex: 1;
+      color: #171826;
+      font-size: .32rem;
+      line-height: .48rem;
+    }
+    .params-list.van-hairline--bottom::after{
+      margin-left: 0.48rem;
+    }
+  </style>
+</head>
+
+<body>
+  <div class="j-container">
+    {{include "/big-member/header.html"}}
+    <div class="j-main" id="analysis-result" v-cloak>
+      <div>
+        <div class="tabs">
+          <div class="other-params">
+            <div class="params-list van-hairline--bottom" v-if="winner">
+              <span class="p-l-label">中标企业</span>
+              <span class="p-l-value">${winner}</span>
+            </div>
+            <div class="params-list" v-if="buyer">
+              <span class="p-l-label">采购单位</span>
+              <span class="p-l-value">${buyer}</span>
+            </div>
+          </div>
+          <div class="tab-item">
+            <div class="projects">
+              <div v-for="item in lists" :key="item._id" class="project-list"
+                @click="goProjectDetail(item.infoid)">
+                <div class="pl-title">${item.projectname}</div>
+                <div class="pl-info">
+                  <span>采购方式:</span>
+                  <span>${item.bidtype || '--'}</span>
+                </div>
+                <div class="pl-info">
+                  <span>中标企业:</span>
+                  <span>${item.s_winner || '--'}</span>
+                </div>
+                <div class="pl-info" v-if="item.review_experts">
+                  <span>评审专家:</span>
+                  <span>${item.review_experts.join(',') || '--'}</span>
+                </div>
+                <div class="pl-info">
+                  <span>项目时间:</span>
+                  <span>${item.firsttime || '--'}</span>
+                </div>
+                <div class="pl-price">
+                  <div class="price-item">
+                    <span>预算 (万元)</span>
+                    <span>${item.budget || '--'}</span>
+                  </div>
+                  <div class="price-item">
+                    <span>中标价 (万元)</span>
+                    <span>${item.bidamount || '--'}</span>
+                  </div>
+                  <div class="price-item">
+                    <span>折扣率</span>
+                    <span>${item.project_rate || '--'}</span>
+                  </div>
+                </div>
+                <div class="bid-company">
+                  <p v-if="item.winnerorder">中标候选人:</p>
+                  <p v-for="sItem in item.winnerorder">
+                    ${sItem || '--'}
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!--S-必定需要预加载的资源-->
+  <link rel="preload" as="script" href=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js />
+  <link rel="preload" as="script" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js />
+  <link rel="preload" as="script" href=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js />
+  <!--E-必定需要预加载的资源-->
+
+  <!--S-有可能需要提前预加载的资源-->
+  <!--E-有可能需要提前预加载的资源-->
+
+  <!--S-当前页面的资源-->
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js> </script> 
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+  <!--E-当前页面的资源-->
+  {{include "/big-member/commonjs.html"}}
+  <!--小于100行同css,减少请求数-->
+  <script>
+    var resultOther = new Vue({
+      delimiters: ['${', '}'],
+      el: '#analysis-result',
+      data () {
+        return {
+          lists: [],
+          winner: '',
+          buyer: ''
+        }
+      },
+      created () {
+        this.winner = decodeURIComponent(utils.getParam('winner'))
+        this.buyer = decodeURIComponent(utils.getParam('buyer'))
+        this.getList()
+      },
+      methods: {
+        getList: function () {
+          var _this = this
+          var data = sessionStorage.getItem('analysis_other_project')
+          $.ajax({
+            type:'POST',
+            url:'/bigmember/decision/projectInfoByBW',
+            data: data,
+            contentType: 'application/json;charset=utf-8' ,
+            success:function(res) {
+              if(res.error_code == 0) {
+                res.data.forEach(function (item,i) {
+                  if (item.budget && item.budget !== '') {
+                    item.budget = (item.budget / 10000).fixed(2)
+                  } else {
+                    item.budget = '-'
+                  }
+                  if (item.bidamount && item.bidamount !== '') {
+                    item.bidamount = (item.bidamount / 10000).fixed(2)
+                  } else {
+                    item.bidamount = '--'
+                  }
+                  if(item.project_rate){
+                    item.project_rate = (item.project_rate*100).fixed(2) + '%'
+                  }
+                  if(item.firsttime){
+                    item.firsttime = new Date(Number(item.firsttime + '000')).pattern('yyyy/MM/dd')
+                  }
+                })
+                _this.lists = res.data
+              } else {
+                console.log(res.error_code)
+              }
+            },
+            error:function(err) {
+              console.log(err)
+            }
+          })
+        },
+        goProjectDetail: function (id) {
+          var that = this
+          $.ajax({
+            type:'POST',
+            url:'/bigmember/follow/project/check',
+            data:{
+              sid: id
+            },
+            success:function(res) {
+              if(res.error_code == 0) {
+                var obj = {
+                  fid: res.data.fig ? res.data.fig : '',
+                  sid: id
+                }
+                sessionStorage.setItem('bigvip-fid', JSON.stringify(obj))
+                location.href = "./pro_follow_detail"
+              }else{
+                console.log(res.error_code)
+              }
+            },
+            error:function(err) {
+              console.log(err)
+            }
+          })
+        },
+      },
+    })
+  </script>
+</body>
+
+</html>

+ 48 - 36
src/jfw/modules/app/src/web/templates/big-member/page_unit_portrayal.html

@@ -78,33 +78,54 @@
                 </div>
                 <p class="region">所在地:${statistics.province || '--'} ${statistics.city}</p>
                 <p class="buyer-type">采购单位类型:${statistics.buyerClass || '--'}</p>
-                <div class="buyer-info">
-                    <div class="bi-item">
-                        <span>采购项目数量</span>
-                        <span>${statistics.buyerCount || '--'}</span>
-                    </div>
-                    <div class="bi-item">
-                        <span>采购规模</span>
-                        <span>${statistics.buyerScale || '--'}</span>
-                    </div>
-                    <div class="bi-item">
-                        <span>中标企业数量</span>
-                        <span>${statistics.winnerCount || '--'}</span>
-                    </div>
-                    <div class="bi-item">
-                        <span>外省中标企业</span>
-                        <span>${statistics.otherWinner || '--'}</span>
-                    </div>
-                    <div class="bi-item">
-                        <span>流标记录数</span>
-                        <span>${statistics.fail_count || '--'}</span>
-                    </div>
-                </div>
-                <div class="static-scope">数据统计范围:${statistics.start || '-'}-${statistics.end}</div>
             </div>
-            <div class="empty" v-show="allNot">
-                <div class="j-img img-empty empty-img"></div>
-                <p class="empty-text">暂无画像信息</p>
+            <!-- 采购单位通讯录 -->
+            <div v-if="getStatus" style="margin-top: .24rem;">
+              <div class="vip_component" style="height:10.8rem;background:url('/common-module/collection/image/buyer/01-bg.png') no-repeat;background-size:100% 100%">
+                <p class="example-title win-bid-title">采购单位通讯录</p>
+                <buyer-example :status="bigStatus" :power="power" type="item_1" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/image/buyer/01.png'></buyer-example>
+              </div>
+            </div>
+            <!-- 采购单位通讯录 -->
+            <hispro-component v-else class="history-list" type="buyer" :buyer="buyer.name"></hispro-component>
+            <!-- 高级分析设置 -->
+            <!-- 高级分析 -->
+            <div class="win-analyse">
+              <span class="win-bid-title">采购单位分析</span>
+              <div class="high-link" @click="goHighSet">
+                <span>高级分析设置</span>
+                <van-icon name="arrow"></van-icon>
+              </div>
+            </div>
+            <div class="buyer-statistic">
+              <div class="statistic-title">统计信息</div>
+              <div class="buyer-info">
+                  <div class="bi-item">
+                      <span>采购项目数量</span>
+                      <span>${statistics.buyerCount || '--'}</span>
+                  </div>
+                  <div class="bi-item">
+                      <span>采购规模</span>
+                      <span>${statistics.buyerScale || '--'}</span>
+                  </div>
+                  <div class="bi-item">
+                      <span>中标企业数量</span>
+                      <span>${statistics.winnerCount || '--'}</span>
+                  </div>
+                  <div class="bi-item">
+                      <span>外省中标企业</span>
+                      <span>${statistics.otherWinner || '--'}</span>
+                  </div>
+                  <div class="bi-item">
+                      <span>流标记录数</span>
+                      <span>${statistics.fail_count || '--'}</span>
+                  </div>
+              </div>
+              <div class="static-scope">数据统计范围:${statistics.start || '-'}-${statistics.end}</div>
+            </div>
+            <div class="jy-empty" v-show="allNot">
+                <div class="jy-empty-img"></div>
+                <p class="jy-empty-text">对不起,没有匹配到相关信息, <br>修改时间范围或换个搜索词试试吧</p>
             </div>
             <!-- 招标动态 -->
             <div class="dynamic" v-if="isShow.showDynamic">
@@ -123,22 +144,13 @@
                     </div>
                     <div v-show="dt.isNext">
                         <div class="more">
-                            <span @click.stop="getNewMsg">查看更多</span>
+                            <span @click.stop="goProjectPage">查看更多</span>
                         </div>
                     </div>
                 </div>
             </div>
-            <!-- 历史项目联系人 -->
-            <div v-if="getStatus">
-              <div class="vip_component" style="height:10.8rem;background:url('/common-module/collection/image/buyer/01-bg.png') no-repeat;background-size:100% 100%">
-                <p class="example-title">历史项目联系方式</p>
-                <buyer-example :status="bigStatus" :power="power" type="item_1" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/image/buyer/01.png'></buyer-example>
-              </div>
-            </div>
             <!-- 数据部分 -->
             <div>
-              <!-- 历史项目联系人 -->
-              <hispro-component class="history-list" type="buyer" :buyer="buyer.name"></hispro-component>
               <!-- 年度项目统计 -->
               <div class="years" v-if="isShow.showYearData">
                   <div class="chart_title">年度项目统计</div>

+ 117 - 0
src/jfw/modules/app/src/web/templates/commonPay/areaPack/orderDetail.html

@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+    <!--引入公共资源头部-->
+    {{include "/big-member/meta.html"}}
+    <title>订单详情</title>
+    <!--S-当前页面的css资源-->
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/j-icons.css?v={{Msg "seo" "version"}}'>
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/order-list/css/order-detail.css?v={{Msg "seo" "version"}}' />
+</head>
+
+<body>
+    <div class="j-container transparent-header">
+        <div class="j-header jy-app-header border-line-b transparent-header">
+            <span class="header-left">
+                <span class="van-icon van-icon-arrow-left"></span>
+            </span>
+            <span class="header-title title-left">订单详情</span>
+            <span class="header-right"></span>
+        </div>
+        <div class="j-main order-detail" id="app" v-cloak>
+            <div class="j-container">
+                <div class="j-main no-scrollbar">
+                    <div class="wrapper">
+                        <div class="header-pic arc-container" :class="orderStateMap[orderInfo.state].bgcClassName">
+                            <div class="order-state">${ orderStateMap[orderInfo.state].text }</div>
+                            <div class="surplus-time" v-if="orderStateMap[orderInfo.state].surplusTimeShow && orderInfo.surplusTime > 0">
+                                <span>剩余支付时间:</span>
+                                <van-count-down @finish="onCountdownFinish" :time="orderInfo.surplusTime"></van-count-down>
+                            </div>
+                        </div>
+                        <div class="card-list">
+                            <div class="j-card report-p">
+                                <span class="rp-left" :class="'badge-' + (orderInfoFilter.badge || '')">
+                                    <img class="card-l-pic" :src="orderInfo.headerImg">
+                                </span>
+                                <span class="rp-right">
+                                    <span class="product-type">${ orderInfo.productType }</span>
+                                    <span class="pay-money">&yen; ${ orderInfo.payMoney }</span>
+                                </span>
+                            </div>
+                            <div class="j-card product-info">
+                                <div class="j-card-title">购买信息</div>
+                                <div class="j-card-items">
+                                    <div
+                                        class="j-card-item"
+                                        :class="item.className"
+                                        v-for="(item, index) in orderInfo.productInfoList"
+                                        :key="index"
+                                        v-show="item.text"
+                                    >
+                                        <span class="card-item-l">${ item.label + item.split }</span>
+                                        <span class="card-item-r" v-html="item.text"></span>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="j-card report-info">
+                                <div class="j-card-title">订单信息</div>
+                                <div class="j-card-items">
+                                    <div
+                                        class="j-card-item"
+                                        :class="item.className"
+                                        v-for="(item, index) in orderInfo.orderInfoList"
+                                        :key="index"
+                                        v-show="item.text"
+                                    >
+                                        <span class="card-item-l">${ item.label + item.split }</span>
+                                        <span class="card-item-r" v-html="item.text"></span>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="j-button-group j-footer" v-show="buttonGroupShow">
+                    <button
+                        class="j-button-confirm pay"
+                        v-if="orderStateMap[orderInfo.state].bottomButtonShow.pay"
+                        @click="onConfirmPay">立即支付</button>
+                    <button
+                        class="j-button-cancel invoke"
+                        v-if="orderStateMap[orderInfo.state].bottomButtonShow.invoke"
+                        @click="lookInvoke">${ invokeButtonText }</button>
+                    <button
+                        class="j-button-confirm buy-again"
+                        v-if="orderStateMap[orderInfo.state].bottomButtonShow.buyAgain"
+                        @click="buyAgain">再次购买</button>
+                    <button
+                            class="j-button-confirm renew"
+                            v-if="orderStateMap[orderInfo.state].bottomButtonShow.renew"
+                            @click="renew">续费</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--S-当前页面的资源-->
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+    {{include "/big-member/commonjs.html"}}
+    <script>
+        var pageInfo = {
+            platform: 'app',
+            version: {{Msg "seo" "version"}},
+        }
+    </script>
+    <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/order-list/js/order-list-config.js?v={{Msg "seo" "version"}}'></script>
+    <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/order-list/js/order-detail.js?v={{Msg "seo" "version"}}'></script>
+    <!--E-当前页面的资源-->
+    {{include "/common/baiducc.html"}}
+</body>
+
+</html>

+ 6 - 2
src/jfw/modules/app/src/web/templates/commonPay/checkout.html

@@ -317,11 +317,15 @@
                                         if (bigmemberBid==="1"){
                                            href = "/jyapp/aiForecastPack/paySuccess?orderCode=" + res.orderCode + "&email=" + res.email + "&payTime=" + res.payTime + "&pay_way=" + res.pay_way + "&price=" + res.price + "&t={{.T.t}}"
                                         }
+
+                                        if (res.filter) {
+                                            href += ('&filter=' + encodeURIComponent(res.filter))
+                                        }
+
                                         // 数据流量包定制
                                         if (productType === 'dataPack') {
-                                            href = href + '&header=充值数据流量包&filter=' + res.filter
+                                            href = href + '&header=充值数据流量包'
                                         }
-
                                         var docsId=checkout.getUrlParam("docId");
                                         if (docsId!=null){
                                           href +="&docsId="+docsId

+ 1 - 1
src/jfw/modules/app/src/web/templates/commonPay/myOrder.html

@@ -109,7 +109,7 @@
                         <div class="empty-container" v-show="tabStateMap[tab.name].list.length === 0 && tabStateMap[tab.name].loaded && !tabStateMap[tab.name].loading">
                             <div class="empty-content-position">
                                 <div class="image">
-                                    <img src="/jyapp/big-member/image/img-empty.png">
+                                    <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/image/jy-sleep.png?v={{Msg "seo" "version"}}'>
                                 </div>
                                 <div class="empty-main tip-text">暂无数据</div>
                             </div>

+ 46 - 5
src/jfw/modules/app/src/web/templates/commonPay/paySuccess.html

@@ -95,9 +95,9 @@
                     继续浏览
                 </button>
             </div>
-        {{else if eq .T.doType "dataPack"}}
+        {{else if or (eq .T.doType "dataPack") (eq .T.doType "areaPack")}}
             <div class="bottom_button j-button-group">
-                <button id ="order" class="j-button-confirm" onclick="window.location.href = '/jyapp/common/dataPack/orderDetail?order_code={{.T.orderCode}}'">
+                <button id ="order" class="j-button-confirm" onclick="window.location.href = '/jyapp/common/{{.T.doType}}/orderDetail?order_code={{.T.orderCode}}'">
                     查看订单
                 </button>
             </div>
@@ -108,6 +108,7 @@
 <script src="https://cdn-common.jianyu360.com/cdn/lib/jquery/3.6.0/jquery.min.js"></script>
 <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/commonPay/js/common.js?v={{Msg "seo" "version"}}"></script>
 <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.js"></script>
+<script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/utils.js?v={{Msg "seo" "version"}}"></script>
 <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "mod_version"}}"></script>
 <script>
     $(function () {
@@ -136,6 +137,8 @@
                     allTotal = Number(allTotal) + Number(orderFilter.give_cycle)
                 }
                 $('.info-box .info-item').text('数据流量包:+' + allTotal)
+            } else if (productType === 'areaPack') {
+                setAreaPackInfo(orderFilter)
             }
         }
 
@@ -145,8 +148,7 @@
         } else {
             payData = new Date();
         }
-        $(".paytime").text(payData.getFullYear() + "年" + (payData.getMonth() + 1) + "月" + payData.getDate() + "日");
-
+        $(".paytime").text(new Date(payData).pattern('yyyy年MM月dd日 HH:mm:ss'));
 
         if (!price) {
             $(".pay_mode").hide();
@@ -168,6 +170,45 @@
         }
     })
 
+    function setAreaPackInfo (orderFilter) {
+        // https://showdoc.jydev.jianyu360.com/web/#/67?page_id=891
+        // {
+        //     num: 0, // 购买的数量 -1全国
+        //     ordertype: 1, // 1正常购买 2升级 3续费
+        //     cycleunit: 0, // 日期单位 1月 2季 3年
+        //     OldNum: 0, // 升级前购买的省份数量
+        // }
+        var titleMap = {
+            1: '购买',
+            2: '升级',
+            3: '续费'
+        }
+        setHeaderTitle(titleMap[orderFilter.ordertype] + $('.header-title').text())
+        var cycleType = ' 个月'
+        if (orderFilter.cycleunit == 2) {
+            cycleType = ' 季'
+        } else if (orderFilter.cycleunit == 3) {
+            cycleType = ' 年'
+        }
+
+        var buyText = orderFilter.num === -1 ? '全国' : (orderFilter.num - (orderFilter.OldNum || 0))
+        var html = `${titleMap[orderFilter.ordertype]}省份数量:<span class="highlight-text">${buyText}</span>${orderFilter.num === -1 ? '' : ' 个省'}`
+        html += `&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;`
+        html += `订阅周期:`
+        if (orderFilter.ordertype == 2) {
+            html += `不延期`
+        } else {
+            html += `<span class="highlight-text">1</span>${ cycleType }`
+        }
+        $('.info-box .info-item').html(html)
+    }
+
+    function setHeaderTitle (title) {
+        if (!title) return
+        document.title = title
+        $('.header-title').text(title)
+    }
+
     function formatMoney(s, n) {
         s = s / 100
         if (n === undefined) {
@@ -207,7 +248,7 @@
         var money = t.split('').reverse().join('') + point + right;
         return money;
     }
-      //获取url参数
+    //获取url参数
     function getParam(name) {
         var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
         var r = window.location.search.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配

+ 3 - 3
src/jfw/modules/app/src/web/templates/vipsubscribe/commonRules.html

@@ -129,7 +129,7 @@
         <div class="grid-content">
           <div class="g-c-list">
             <span class="rights-icon r-icon-22"></span>
-            <span>中标信息统计</span>
+            <span>中标/采购信息统计</span>
           </div>
           <div class="g-c-list">
             <span class="rights-icon r-icon-23"></span>
@@ -141,7 +141,7 @@
           </div>
           <div class="g-c-list">
             <span class="rights-icon r-icon-5"></span>
-            <span>月度中标金额统计</span>
+            <span>月度中标/采购规模统计</span>
           </div>
           <div class="g-c-list">
             <span class="rights-icon r-icon-6"></span>
@@ -153,7 +153,7 @@
           </div>
           <div class="g-c-list">
             <span class="rights-icon r-icon-2"></span>
-            <span>重点客户分析</span>
+            <span>重点客户/或企业代理机构</span>
           </div>
           <div class="g-c-list">
             <span class="rights-icon r-icon-3"></span>

+ 3 - 2
src/jfw/modules/app/src/web/templates/vipsubscribe/infoWord.html

@@ -42,7 +42,8 @@
                     maxlength="200"
                     autosize
                     type="textarea"
-                    placeholder="请输入关键词,多个关键词用空格隔开,例如:税务局 软件"
+                    :placeholder="keywordPlaceHolder"
+                    @input="keywordInput"
                 ></van-field>
             </div>
             <div class="module-rec pd">
@@ -61,7 +62,7 @@
                     </div>
                 </div>
             </div>
-            <div class="module-match-way pd">
+            <div class="module-match-way pd" v-if="vSwitch !== 'f'">
                 <div class="m-header">
                     <div class="m-h-left batch-delete">匹配模式</div>
                     <div></div>

+ 8 - 5
src/jfw/modules/app/src/web/templates/vipsubscribe/keyWord.html

@@ -40,10 +40,13 @@
         <div class="m-header">
             <div class="group-filter-container">
                 <div class="filter-text">关键词组分类</div>
-                <div class="filter-button" @click="showFilterPicker(true)">
+                <div class="filter-button" :class="{ 'grey-bg': this.vSwitch === 'f' }" @click="showFilterPicker(true)">
                     <span class="group-name ellipsis">${ filter.groupName ? filter.groupName : '全部' }</span>
                     <van-icon name="play"></van-icon>
                 </div>
+                <div class="filter-action" v-if="vSwitch === 'f'">
+                    <span class="key-tag red clickable" @click="toBuyVIPService">开通</span>
+                </div>
             </div>
             <div class="batch-delete h100" v-show="listShow" @click="batchDeleteStateChange">
                 ${ batchDeleteState ? '取消' : '批量删除' }
@@ -68,7 +71,7 @@
                         :before-close="beforeKeySwipeCellClose">
                         <div class="j-key-card" @click="clickKeyCard(item)">
                             <div class="j-key-card-top">
-                                <div class="k-c-t-l j-tag" :class="item.calcInfo.matchWayClass">${ item.calcInfo.matchWay }</div>
+                                <div class="k-c-t-l j-tag" :class="item.calcInfo.matchWayClass" v-if="vSwitch !== 'f'">${ item.calcInfo.matchWay }</div>
                                 <div class="k-c-t-c text-container">${ item.calcInfo.key }</div>
                                 <van-icon class="k-c-t-r" name="arrow"></van-icon>
                             </div>
@@ -85,7 +88,7 @@
             </div>
             <div class="key-empty" v-show="emptyShow">
                 <div class="empty-img-container">
-                    <img class="empty-img" src="/jyapp/images/wxkeyset/nopush.png">
+                    <img class="empty-img" src="/common-module/public/image/jy-back.png">
                 </div>
                 <div class="empty-text">暂无关键词组</div>
                 <button class="add-keyword-button" @click="addKeyWord" :disabled="filter.allKeywordsList.length >= conf.keywordMax">
@@ -113,8 +116,8 @@
                 </button>
             </div>
             <div class="j-button-group" v-else>
-                <button class="j-button-confirm" @click="addKeyWord" :disabled="filter.allKeywordsList.length >= conf.keywordMax">
-                    <span class="info-text">新增关键词组</span>
+                <button class="j-button-confirm" @click="clickAddKeyWordButton" :disabled="fullKeys && vSwitch !== 'f'">
+                    <span class="info-text">${ addNewKeyButtonText }</span>
                     <span class="sub-text">(${ totalKeywordsCount } / ${ conf.keywordMax })</span>
                 </button>
             </div>

+ 129 - 11
src/jfw/modules/app/src/web/templates/vipsubscribe/vip_index_new.html

@@ -116,13 +116,121 @@
     .j-button-confirm:nth-child(1){
       margin-right: .16rem;
     }
-    .switchicon{
+    .switchicon {
       display: flex;
       width: .48rem;
       height: .48rem;
       background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACrSURBVHgB7dfRCcIwEIDhixPoBm5mV3AEJz03aDc4rxjQhzRgEXtn/w9CC6GQvy+9igDArpjZxdfoS+d7yaYe/F2uiPr2LW2EH3awNiJ+iogoiIji6xH2+mJGsBhROgHql7PEMJVSTq2NQ+eho8QxLW30Aq6+7rK9+fA3AQDgExZnFlJjFtre6lkogvWzkPGnFAQRURARxT9HjJJJI0Ilmxqh9hz8BgGAXXkA6eITzq1YSq8AAAAASUVORK5CYII=) no-repeat;
       background-size: contain;
     }
+    .go_to_levelup {
+      background: url('image/gotolevelup.png') no-repeat;
+      background-size: cover;
+      border: 0;
+    }
+    .amendmentNum {
+      font-size: 0.2rem;
+      font-weight: 500;
+      color: #9B9BA3;
+      margin-left: 0.75rem;
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+    }
+    .numColor {
+      color: #2ABDD1;
+    }
+    .amendmentNum .icon-bangzhu {
+      margin-left: 0.18rem;
+      color: #2cb7ca;
+      font-size: 0.36rem;
+    }
+    .area-alert .weui-dialog__bd {
+      font-size: 0.29rem;
+      line-height: 0.43rem;
+      font-weight: 500;
+      color: #161826;
+      text-align: left;
+      margin: 0.43rem 0.54rem 0.39rem;
+    }
+    .openVip {
+      border-radius: 0.14rem 0.14rem 0.14rem 0.14rem;
+      border: 0.02rem solid #FA483C;
+      font-size: 0.18rem;
+      font-weight: 500;
+      color: #FA483C;
+      width: 0.57rem;
+      text-align: center;
+      height: 0.29rem;
+      line-height: 0.29rem;
+      margin-left: 0.29rem;
+    }
+    .matching {
+      display: flex;
+      align-items: center;
+    }
+    .area-noNum .weui-dialog__bd {
+      text-align: left;
+      font-size: 0.29rem;
+      font-weight: 500;
+      color: #161826;
+      line-height: 0.43rem;
+      margin: 0.43rem 0.54rem 0.39rem;
+    }
+    .provincePayWarp {
+      padding: 0 0.21rem;
+      margin-top: 0.11rem;
+    }
+    .provincePayTips {
+      font-size: 0.21rem;
+      font-weight: 500;
+      color: #9B9BA3;
+    }
+    .provincePay {
+      margin-top: 0.14rem;
+      width: 100%;
+      height: 2.5rem;
+      background: #FFFFFF;
+      box-shadow: 0rem 0.04rem 0.14rem 0.02rem rgba(54, 147, 179, 0.050999999046325684);
+      border-radius: 0.14rem 0.14rem 0.14rem 0.14rem;
+      padding: 0.28rem 0;
+    }
+    .provincePay-text {
+      font-size: 0.2rem;
+      font-weight: 500;
+      color: #9B9BA3;
+      text-align: center;
+    }
+    .provincePay-num {
+      font-size: 0.32rem;
+      font-weight: bold;
+      color: #2ABDD1;
+    }
+    .provincePay-numText {
+      padding-top: 0.14rem;
+      padding-bottom: 0.2rem;
+    }
+    .provincePay-btnWrap {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .privincePay-btn {
+      width: 2.14rem;
+      height: 0.71rem;
+      background: #EDEEF2;
+      border-radius: 0.07rem 0.07rem 0.07rem 0.07rem;
+      font-size: 0.29rem;
+      font-weight: 500;
+      color: #161826;
+      text-align: center;
+      line-height: 0.71rem;
+    }
+    .updateColor {
+      background: #2ABDD1;
+      color: #fff;
+      margin-left: 0.36rem;
+    }
   </style>
 </head>
 
@@ -139,13 +247,13 @@
     <!-- <a href="/jyapp/vipsubscribe/vipsubscribe_renew" class="custom-header-right go_renew" style="display: none;">续费</a> -->
     <!-- <a href="/jyapp/vipsubscribe/vipsubscribe_new" class="custom-header-right go_buy" style="display: none;">去购买</a> -->
   </div>
-  <div class="app-layout-content-b">
+  <div class="app-layout-content-b"  v-cloak>
     {{if not .T.isLiveActive}}
     <div class="vip-upgrade">
       {{else}}
       <div class="vip-upgrade live-20200707">
         {{end}}
-        <ul class="vip-body" id="vip-body">
+        <ul class="vip-body" id="vip-body" v-cloak>
           <li class="sub-box">
             <a data-href="/jyapp/vipsubscribe/introducePage?type=renew" class="banner-ad-box update"
               style="display: none">
@@ -158,8 +266,8 @@
                 <i class="iconfont icon-arrow"></i>
               </div>
             </a>
-            <ul class="sub-info">
-              <li class="cycle">
+            <ul class="sub-info" :class="vSwitch !== 'm' && vSwitch !== 'v' ? 'go_to_levelup' : ''" @click="toPaySupSub" style="min-height: 1.48rem">
+              <li class="cycle" v-show="vSwitch == 'm' || vSwitch == 'v'">
                 <a class="item-container" :href="vipLink">
                   <div class="item">
                     <span class="item-l">
@@ -174,7 +282,6 @@
                     <span class="buy-cycle text ellipsis">0</span>
                   </div>
                   <div class="sub-item">
-                    <!-- 此处空span占位 -->
                     <span class="sub-l"></span>
                     <span class="sub-r">
                       <span class=""></span>
@@ -184,7 +291,20 @@
               </li>
             </ul>
           </li>
-          <sub-component :linkobj="linkObj" :initdata="initData"></sub-component>
+          <sub-component ref="subComponent" :linkobj="linkObj" :initdata="initData" :v-switch="vSwitch"></sub-component>
+          <div class="provincePayWarp" v-show="userType">
+            <span class="provincePayTips">省份订阅包</span>
+            <div class="provincePay">
+              <div class="provincePay-text">订阅周期:${subscribeTime}</div>
+              <div class="provincePay-text provincePay-numText">
+                省份数量:<span class="provincePay-num">&nbsp;<span v-html="userAreaAllNum"></span>&nbsp;</span>${userAreaAllNum !== '全国' ? '个' : ''}
+              </div>
+              <div class="provincePay-btnWrap">
+                <div class="privincePay-btn" @click="renewBtn">续费</div>
+                <div class="privincePay-btn updateColor" v-if="userAreaAllNum !== '全国'" @click="updateBtn">升级</div>
+              </div>
+            </div>
+          </div>
           <li class="body-item" id="giveTimeBox" style="display: none;margin-top: 0.16rem;">
             <div class="item-container" href="javascript:;">
               <div class="item">
@@ -212,7 +332,7 @@
           </li>
         </ul>
         <!-- 升级 -->
-        <div class="update_renew">
+        <div class="update_renew" style="display: none">
           <div class="update-tips" data-update-tips>因系统升级,已购买用户可选择原套餐续费,或升级到新版本享受更多权益。</div>
           <div class="footer-button-group j-button-group">
             <button class="j-button-confirm" data-bind-renew>续费</button>
@@ -243,8 +363,6 @@
     <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/js/common.js?v={{Msg "seo" "version"}}'></script>
     <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "mod_version"}}'></script>
     <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/utils.js?v={{Msg "seo" "mod_version"}}'></script>
-    <!--<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/check-bind-phone.js?v={{Msg "seo" "version"}}'></script>-->
-    <!-- <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/coupon/js/pay-order-template.js?v={{Msg "seo" "version"}}'></script> -->
     <script>
       $(window).on("pageshow", function (event) {
         if (event.originalEvent.persisted) {
@@ -271,7 +389,7 @@
       sessionStorage.removeItem('vip-cur-select-size')
     </script>
     <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/js/UpgradePrice.js?v={{Msg "seo" "version"}}'></script>
-    <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/js/vip_index_new.js?v={{Msg "seo" "version"}}'></script>
+    <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/js/vip_index_new.js?v=11{{Msg "seo" "version"}}'></script>
 </body>
 {{include "/common/baiducc.html"}}
 

+ 1 - 1
src/jfw/modules/app/src/web/templates/vipsubscribe/vip_introduce.html

@@ -212,7 +212,7 @@
                     industry: '/jyapp/vipsubscribe/toChangeIndustry?header=save&subvip=free',
                     keyword: '/jyapp/vipsubscribe/toSetKeyWordPage',
                     infotype: '/jyapp/vipsubscribe/toSetInfoTypePage',
-                    resultview: '/jyapp/vipsubscribe/toVIPViewPage',
+                    resultview: '/jyapp/vipsubscribe/toVIPViewPage?vSwitch=v',
                     pushsetting: '/jyapp/big/page/push_settings'
                 },
                 initData: {},

+ 83 - 1
src/jfw/modules/app/src/web/templates/vipsubscribe/vip_purchase.html

@@ -10,6 +10,7 @@
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.css'>
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/iconfont/iconfont.css?v={{Msg "seo" "version"}}'>
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/css/public_.css?v={{Msg "seo" "version"}}'/>
+  <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/appbutton.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/css/vip_purchase.css?v={{Msg "seo" "version"}}'>
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/layout.css'/>
@@ -285,6 +286,26 @@
       <!-- vue组件 -->
       <div class="vip-footer fixed-bottom-box p15" id="goods-order-vue">
         <pay-order-template ref="couponRef" :config="$data" @update="updateS"></pay-order-template>
+        <van-popup v-model="dialog.backTip" get-container="body" class="back-tip-wrapper" :close-on-click-overlay="false">
+          <div class="b-t-title">
+            <img src="/common-module/area-pack/images/messageTitle@3x.png" alt="">
+          </div>
+          <div class="b-t-content">
+            <div class="b-t-content-item">
+              多订阅1个省份,获取商机概率<br />增加一倍,邀您体验!
+            </div>
+            <div class="b-t-content-item bg-f-orange">
+              支持用户增加订阅区域时使用,每增购1个省可获取该省的招标采购信息
+            </div>
+            <div class="b-t-content-item bg-f-orange">
+              按时间(月/季/年)、订阅省份个数计价,19.9元省/月起。
+            </div>
+          </div>
+          <div class="b-t-footer">
+            <button class="button cancel" @click="dialog.backTip = false;history.back()">取消</button>
+            <button class="button confirm" @click="toBuyAreaPack">去购买</button>
+          </div>
+        </van-popup>
       </div>
       <div class="fixed-bottom-box p15" style="display: none;">
         {{if not .T.isTrial }}
@@ -503,9 +524,9 @@
   <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.js"></script>
   <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/js/common.js?v={{Msg "seo" "version"}}"></script>
   <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "mod_version"}}"></script>
-  <!--<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/check-bind-phone.js?v={{Msg "seo" "version"}}'></script>-->
   <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/js/price.js?v={{Msg "seo" "version"}}"></script>
   <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+  <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/vipsubscribe/js/vip-size-template.js?v={{Msg "seo" "version"}}'></script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/vipsubscribe/js/vip-coupon-template.js?v={{Msg "seo" "version"}}'></script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/coupon/js/pay-order-template.js?v={{Msg "seo" "version"}}'></script>
@@ -761,6 +782,13 @@
       el: '#goods-order-vue',
       data: function () {
         return {
+          sessKey: '$data-vipsubscribe_new_goods_order',
+          // 返回提示标志,为true则返回时不弹出提示
+          iDoNotNeedConfirmed: true,
+          dialog: {
+            backTip: false,
+            backTipShowCount: 0
+          },
           type: 'vip',
           initPrice: 0, // 原价
           realPrice: 0, // 实付价
@@ -784,8 +812,62 @@
       },
       mounted () {
         this.init(this.$data)
+        this.restoreState()
+        this.getBuyInfo()
+        // 解决ios从上个页面返回触发popstate的问题
+        // 基本逻辑:刚进入页面100ms内不允许触发popstate请求
+        setTimeout(function () {
+          this.iDoNotNeedConfirmed = false
+        }.bind(this), 100)
       },
       methods: {
+        // 获取已购买信息
+        getBuyInfo: function () {
+          var _this = this
+          $.ajax({
+            url: '/publicapply/free/subscribe',
+            type: 'POST',
+            success: function (res) {
+              if (res && res.error_code === 0) {
+                if (res.data && !res.data.provincenum) {
+                  _this.addBackTip()
+                }
+              }
+            }
+          })
+        },
+        toBuyAreaPack: function () {
+          this.dialog.backTip = false
+          this.saveState()
+          location.href = '/jyapp/areaPack/page/buy'
+        },
+        restoreState: function () {
+          var k = sessionStorage.getItem(this.sessKey)
+          if (k) {
+            Object.assign(this.dialog, JSON.parse(k))
+
+            sessionStorage.removeItem(this.sessKey)
+          }
+          return !!k
+        },
+        saveState: function () {
+          sessionStorage.setItem(this.sessKey, JSON.stringify(this.dialog))
+        },
+        addBackTip: function () {
+          var _this = this
+          var pushContent = {
+            info: 'back',
+            url: '#tip'
+          }
+          if (!history.state && this.dialog.backTipShowCount < 1) {
+            history.pushState(pushContent, null, pushContent.url);
+          }
+          $(window).on('popstate', function () {
+            if (_this.iDoNotNeedConfirmed) return
+            _this.dialog.backTip = true
+            _this.dialog.backTipShowCount++
+          })
+        },
         // 更新价格相关
         updatePrice: function (before) {
           var curCoupon = JSON.parse(sessionStorage.getItem('vip-cur-select-coupon'))

+ 12 - 4
src/jfw/modules/app/src/web/templates/vipsubscribe/vip_viewPage.html

@@ -1,7 +1,7 @@
 <html>
 <head>
 	{{include "/common/meta.html"}}
-	<title>超级订阅结果预览</title>
+	<title>订阅结果预览</title>
 	{{include "/common/nnc.html"}}
 	<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/dropload.css?v={{Msg "seo" "version"}}" rel="stylesheet">
 	<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/wxlist.css?v={{Msg "seo" "version"}}" rel="stylesheet">
@@ -125,9 +125,13 @@
 			var reqParam = {
 				"pageNum": pageNum++
 			};
+			var tempURL = '/publicapply/free/pushview'
+			if (getParam('vSwitch') == 'v') {
+				tempURL = '/subscribepay/afterPay/getPushView'
+			}
 			$.ajax({
 				type: 'post',
-				url: '/subscribepay/afterPay/getPushView',
+				url: tempURL,
 				data: reqParam,
 				dataType: 'json',
 				success: function(data){
@@ -166,9 +170,13 @@
 						var reqParam = {
 							"pageNum": pageNum++
 						};
+						var tempURL = '/publicapply/free/pushview'
+						if (getParam('vSwitch') == 'v') {
+							tempURL = '/subscribepay/afterPay/getPushView'
+						}
 						$.ajax({
 							type: 'post',
-							url: '/subscribepay/afterPay/getPushView',
+							url: tempURL,
 							data: reqParam,
 							dataType: 'json',
 							success: function(data){
@@ -491,7 +499,7 @@
 			<span style="color:#1d1d1d;font-size:16px">没有找到和你订阅设置内容有关的信息</span>
 			<br><br>
       <div id="back" class="text-center">
-  			返回修改超级订阅设置
+  			返回修改订阅设置
   		</div>
 		</span>
 	</div>

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

@@ -98,6 +98,71 @@
             padding-top: .34rem;
         }
     </style>
+    <style>
+        .oldUserTips{
+            position: fixed;
+            top: 0;
+            left: 0;
+            right: 0;
+            bottom: 0;
+            z-index: 99999;
+            background-color:rgba(0, 0, 0, 0.7);
+            display: none;
+        }
+        .updateTips-wrap{
+            width: 6.06rem;
+            height: 4.58rem;
+            background: #FFFFFF;
+            border-radius: 0.16rem 0.16rem 0.16rem 0.16rem;
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translateX(-50%) translateY(-50%);
+        }
+        .updateTips-title{
+            text-align: center;
+            padding-top: 0.48rem;
+            font-size: 0.36rem;
+            font-weight: 500;
+            color: #161826;
+        }
+        .updateTips-text{
+            text-align: left;
+            padding: 0.16rem 0.6rem 0.1rem;
+            font-size: 0.3rem;
+            font-weight: 500;
+            color: #5E5E64;
+            line-height: 0.44rem;
+        }
+        .updateTips-btnWrap{
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-top: 0.32rem;
+            border-top:0.02rem solid rgba(0, 0, 0, 0.1) ;
+        }
+        .updateTips-btn{
+            font-size: 0.36rem;
+            font-weight: 500;
+            color: #161826;
+            width: 50%;
+            height: 0.92rem;
+            line-height: 0.92rem;
+            text-align: center;
+            cursor: pointer;
+        }
+        .updateTips-line{
+            height: 0.92rem;
+            width: 0.02rem;
+            background-color: rgba(0, 0, 0, 0.1);
+        }
+        .levelUp{
+            color: #2ABDD1;
+        }
+        #freeArea{
+            color: #2ABDD1;
+        }
+    </style>
 </head>
 <body class="p13" id="viperSuper" style="background: #fff;overflow: hidden;">
 <!-- 加载数据-->
@@ -108,7 +173,7 @@
     <keep-component ref="vKeepComponent" @on-change-keep="changeKeepStatus"  :bid="nowOpenBid" :first="false"></keep-component>
 </div>
 
-<div class="j-container" id="select-meau">
+<div class="j-container" id="select-meau" style="display: none;">
     <van-popover v-model="showPopover" placement="top" trigger="click" class="housePover">
         <van-grid
         class="fixedPover"
@@ -147,6 +212,28 @@
     <li id="sub_manager" data-need-bind-phone>订阅管理</li>
   </ul>
 </div>
+<div class="oldUserTips" id="UserTips">
+    <div class="updateTips-wrap">
+        <div class="updateTips-title">省份订阅包到期提醒</div>
+        <div class="updateTips-text">由于您的省份订阅包已到期,免费用户仅限订阅1个省份。<br>订阅区域已恢复为您免费订阅时选择的区域"<span id="freeArea"></span>",如需订阅更多省份,请前往购买省份订阅包。</div>
+        <div class="updateTips-btnWrap">
+            <div class="updateTips-btn" id="cancel" onclick="hiddenTips()">取消</div>
+            <div class="updateTips-line"></div>
+            <div class="updateTips-btn levelUp" id="gotoPay"  onclick="gotoPay()">去购买</div>
+        </div>
+    </div>
+</div>
+<div class="oldUserTips" id="tipsType">
+	<div class="updateTips-wrap" style="height: 3.3rem;">
+		<div class="updateTips-title">版本更新</div>
+		<div class="updateTips-text" style="text-align: center;">免费订阅新版来了,请前往订阅设置更新功能后使用。</div>
+		<div class="updateTips-btnWrap">
+			<div class="updateTips-btn" id="cancel2" onclick="hiddenTips2()">取消</div>
+			<div class="updateTips-line"></div>
+			<div class="updateTips-btn levelUp" id="newLevelUp"  onclick="updateJump2()">立即更新</div>
+		</div>
+	</div>
+</div>
 <van-popup v-model="bigSubShow" class="product-switch" position="top" get-container="body" :style="{ height: '188px' }">
     <div class="typeswitch" @click="proClick('big')">
         <div class="type-left">
@@ -315,7 +402,7 @@
             </div>
         </div>
         <span class="empty findnull-no-key">
-            <div><img class="empty-img" src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wxkeyset/nopush.png?v={{Msg "seo" "version"}}"></div>
+            <div><img class="empty-img" src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/image/jy-smile.png?v={{Msg "seo" "version"}}'></div>
             <div class="empty-text">订阅关键词,接收最新招投标信息</div>
             <div class="button-box" id="toKeySet" data-need-bind-phone>
                 <span class="j-icon icon-chahao"></span>
@@ -327,7 +414,7 @@
             <span class="empty-text">近期没有你想要的信息,再等等吧!<br>你也可以进入设置页面、调整一下关键词再回来看看。</span>
         </span>
         <span class="empty findnull_">
-            <div><img class="empty-img" src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wxkeyset/nopush.png?v={{Msg "seo" "version"}}"></div>
+            <div><img class="empty-img" src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/image/jy-sleep.png?v={{Msg "seo" "version"}}'></div>
             <span class="empty-text">暂时无历史推送记录<br></span>
         </span>
         <!-- 推送消息--设置关键词 -->
@@ -497,48 +584,6 @@
         })
     </script>
     <script type="text/javascript">
-    $.ajax({
-        type: 'POST',
-        url: '/publicapply/bidcoll/power',
-        success: function(res) {
-                console.log(res)
-                if(res.error_code == 0) {
-                    if(!res.data.entniche && !res.data.member && res.data.vip <= 0) {
-                        sessionStorage.removeItem('switch-product')
-                        setTimeout(function() {
-                            (window.slotbydup = window.slotbydup || []).push({
-                                id: "u6603902",
-                                container: "_36y1d8lbx9n",
-                                async: true
-                            });
-                            (window.slotbydup = window.slotbydup || []).push({
-                                id: "u6603902",
-                                container: "_061vbh43quq3",
-                                async: true
-                            });
-                        },1000)
-                        getAjaxAdv()
-                    }
-                }
-        },
-        error: function(err) {
-                console.log(err)
-        }
-    })
-    function getAjaxAdv () {
-        $.ajax({
-            type: 'POST',
-            url: '/publicapply/adLeague/exposure',
-            data: {
-                client: 'APP',
-                id: 'ad6',
-                position: '订阅推送列表页'
-            },
-            success: function(res) {
-                console.log(res)
-            }
-        })
-    }
     addEventListener('focus', function() {
         if(document.activeElement = document.getElementById('iframeu6603902_0')) {
             $.ajax({
@@ -557,6 +602,41 @@
     });
     </script>
 <script>
+        function hiddenTips() {
+            $('#UserTips').hide()
+        }
+        function gotoPay() {
+            $('#UserTips').hide()
+            location.href = '/jyapp/areaPack/page/buy?type=buy'
+        }
+        // 得到用户是否需要提醒省份订阅包过期
+        function getUserSubscribe() {
+            $.ajax({
+                url: '/publicapply/free/areapack/tip',
+                type: 'POST',
+                success: function (res) {
+                    console.info(res)
+                    console.info($('#UserTips'))
+                    if (res.data.tip) {
+                        $('#UserTips').show()
+                        $('#freeArea').text(res.data.area)
+                        tipsClose()
+                    } else {
+                        $('#UserTips').hide()
+                    }
+                }
+            })
+        }
+        getUserSubscribe()
+        function tipsClose() {
+            $.ajax({
+                url: '/publicapply/free/areapack/update',
+                type: 'POST',
+                success: function (res) {
+                    
+                }
+            })
+        }
   // @手机号绑定及账号合并 2021/1/25
   $("#toKeySet").on('click', tokeyset)
   function receivePushMessageHandle(type,url){
@@ -710,7 +790,6 @@
             }
         }
     })
-
   function initpage() {
       afterJyObjInit();
       var thisClass=this;
@@ -725,11 +804,17 @@
       this.InitPersonal=function(r){
         $("#sub_manager").click(function() {
             sessionStorage.setItem(vm.sessStorageKey, JSON.stringify(vm.$data))
-            if(vm.rootInfo.memberStatus > 0) {
-                location.href = '/jyapp/vipsubscribe/toSubVipSetPage?vSwitch=m'
+            let thisType = sessionStorage.getItem('userIsNew')
+            if (window.userNewType || thisType) {
+                location.href = '/jyapp/vipsubscribe/toSubVipSetPage'
             } else {
-                tokeyset()
+                if(vm.rootInfo.memberStatus > 0) {
+                    location.href = '/jyapp/vipsubscribe/toSubVipSetPage'
+                } else {
+                    tokeyset()
+                }
             }
+            
         });
         $(".tab_left .area").hide();
         if (r.isPassCount) {
@@ -750,11 +835,17 @@
         $("#sub_manager").click(function() {
             console.log(vm.rootInfo, 'vmrootInfo')
             sessionStorage.setItem(vm.sessStorageKey, JSON.stringify(vm.$data))
-            if(vm.selectPro) {
-                location.href = '/jyapp/vipsubscribe/toSubVipSetPage?vSwitch=m'
+            let thisType = sessionStorage.getItem('userIsNew')
+            if (window.userNewType || thisType) {
+                location.href = '/jyapp/vipsubscribe/toSubVipSetPage'
             } else {
-                tosetpage()
+                if(vm.selectPro) {
+                    location.href = '/jyapp/vipsubscribe/toSubVipSetPage'
+                } else {
+                    tosetpage()
+                }
             }
+            
         });
         if(productType == 0) {
             $(".vip_report").show();
@@ -931,6 +1022,9 @@
                 $(".listcontent").scrollTop(0);
             }, 300);
         }
+        setTimeout(() => {
+            $('#select-meau').css({'display':'flex'})
+        }, 500)
         if (hasNextPage) {
             setTimeout(function () {
                 wxflag = $('.listcontent').dropload({
@@ -1191,6 +1285,7 @@ function hasNoData() {
     var NoDataShow = $('.findnull-no-key').is(':hidden')
     $(".listcontent").hide()
     $("#loading").hide()
+    $('#select-meau').css({'display': 'flex'})
     $(".color_top").hide()
     // 如果no-key-no-data 不显示,才会显示no-data
     if (!nokeyNoDataShow || !NoDataShow) {
@@ -1500,26 +1595,44 @@ function hasNoData() {
           return year + "<br>" + month + "" + date;
       }
   }
-
+    function hiddenTips2() {
+        $('#tipsType').hide()
+    }
+    function updateJump2() {
+        $('#tipsType').hide()
+        // location.replace('/jyapp/vipsubscribe/toSubVipSetPage?vSwitch=v')
+        $.ajax({
+            url: '/publicapply/free/oneProvinceSet',
+            type: 'POST',
+            success: function (res) {
+                location.href = '/jyapp/vipsubscribe/toSubVipSetPage'
+            }
+        })
+    }
   //
   function appendList(content) {
       content.children(".tslist").on("click", function (event) {
-          var isv = $(this).find("a.bt").hasClass("visited");//是否为已读
-          setVisitedIndex($(this), "");
-          var sds = $(this).attr("words");
-          var h = $(this).find("a.bt").attr("s");
-          var eid = $(this).find("a.bt").attr("eid");
-          var index = $(this).find("a.bt").attr("projectm");
-          var pdate = $(this).find("a.bt").attr("push_date");
-          beforeJump(eid, h, sds, index, pdate, isv);
-          sessionStorage.setItem(vm.sessStorageKey, JSON.stringify(vm.$data))
-      });
-      $("#list").append(content);
-      $(".findnull").hide();
-      $(".listcontent").show();
-      setTimeout(function () {
-          $("#loading").hide();
-      }, 500)
+        if (!window.userNewType&&!(vm.rootInfo.vipStatus>0||vm.rootInfo.memberStatus>0)) {
+            $('#tipsType').show()
+          } else {
+            $('#tipsType').hide()
+            var isv = $(this).find("a.bt").hasClass("visited");//是否为已读
+            setVisitedIndex($(this), "");
+            var sds = $(this).attr("words");
+            var h = $(this).find("a.bt").attr("s");
+            var eid = $(this).find("a.bt").attr("eid");
+            var index = $(this).find("a.bt").attr("projectm");
+            var pdate = $(this).find("a.bt").attr("push_date");
+            beforeJump(eid, h, sds, index, pdate, isv);
+            sessionStorage.setItem(vm.sessStorageKey, JSON.stringify(vm.$data))
+          }
+        })
+        $("#list").append(content);
+        $(".findnull").hide();
+        $(".listcontent").show();
+        setTimeout(function () {
+            $("#loading").hide();
+        }, 500)
   }
 
   function beforeJump(eid, h, sds, index, pd, vis) {

+ 97 - 15
src/jfw/modules/app/src/web/templates/weixin/search/mainSearch.html

@@ -125,9 +125,96 @@
     }
 
 </style>
+<style>
+    .oldUserTips{
+        position: fixed;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        z-index: 99999;
+        background-color:rgba(0, 0, 0, 0.7);
+        display: none;
+    }
+    .updateTips-wrap{
+        width: 6.06rem;
+        height: 3.74rem;
+        background: #FFFFFF;
+        border-radius: 0.16rem 0.16rem 0.16rem 0.16rem;
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translateX(-50%) translateY(-50%);
+    }
+    .updateTips-title{
+        text-align: center;
+        padding-top: 0.48rem;
+        font-size: 0.36rem;
+        font-weight: 500;
+        color: #161826;
+    }
+    .updateTips-text{
+        text-align: left;
+        padding: 0.16rem 0.6rem 0.1rem;
+        font-size: 0.3rem;
+        font-weight: 500;
+        color: #5E5E64;
+        line-height: 0.44rem;
+    }
+    .updateTips-btnWrap{
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        margin-top: 0.32rem;
+        border-top:0.02rem solid rgba(0, 0, 0, 0.1) ;
+    }
+    .updateTips-btn{
+        font-size: 0.36rem;
+        font-weight: 500;
+        color: #161826;
+        width: 50%;
+        height: 0.92rem;
+        line-height: 0.92rem;
+        text-align: center;
+        cursor: pointer;
+    }
+    .updateTips-line{
+        height: 0.92rem;
+        width: 0.02rem;
+        background-color: rgba(0, 0, 0, 0.1);
+    }
+    .levelUp{
+        color: #2ABDD1;
+    }
+    #freeArea{
+        color: #2ABDD1;
+    }
+</style>
 <div id="jyKeepComponent">
     <keep-component ref="vKeepComponent" @on-change-keep="changeKeepStatus" :bid="nowOpenBid" :first="false"></keep-component>
 </div>
+<!-- <div class="oldUserTips" id="UserTips">
+    <div class="updateTips-wrap">
+        <div class="updateTips-title">开通超级订阅</div>
+        <div class="updateTips-text">免费用户最多可查看500条招标搜索结果,可前往购买超级订阅解锁查看更多信息</div>
+        <div class="updateTips-btnWrap">
+            <div class="updateTips-btn" id="cancel" onclick="hiddenTips()">取消</div>
+            <div class="updateTips-line"></div>
+            <div class="updateTips-btn levelUp" id="gotoPay"  onclick="gotoPay()">去开通</div>
+        </div>
+    </div>
+</div> -->
+<div class="oldUserTips" id="tipsType" >
+	<div class="updateTips-wrap" style="height: 3.3rem;">
+		<div class="updateTips-title">版本更新</div>
+		<div class="updateTips-text" style="text-align: center;">免费订阅新版来了,请前往订阅设置更新功能后使用。</div>
+		<div class="updateTips-btnWrap">
+			<div class="updateTips-btn" id="cancel2" onclick="hiddenTips2()">取消</div>
+			<div class="updateTips-line"></div>
+			<div class="updateTips-btn levelUp" id="newLevelUp"  onclick="updateJump2()">立即升级</div>
+		</div>
+	</div>
+</div>
 <div class="loading_Top" style="display: none;">
     <p><span></span></p>
 </div>
@@ -642,7 +729,7 @@
     var distance = {{Msg "seo" "distance"}};
     var member_status;
     var isMember = false;
-    var vSwitch = 'v'
+    var vSwitch = 'f'
     // 消息总数
     try {
         checkMsgCount(true, 0)
@@ -650,25 +737,20 @@
         console.log(e)
     }
     // 子账户判断
+    window.jyAddInfo = {
+        isUpgrade: false
+    }
     $.ajax({
         type:'POST',
         url:'/bigmember/use/isAdd?t' + new Date().getTime(),
         success: function (r) {
             if (r && r.data) {
-                $.ajax({
-                    url: '/publicapply/subscribe/vipSwitch',
-                    type: 'POST',
-                    success: function(res) {
-                        if(res.error_code == 0) {
-                            vSwitch = res.data.vt
-                            if(vSwitch == 'm' && r.data.isSubCount) {
-                                $('#resbm').hide()
-                            } else {
-                                $('#resbm').show()
-                            }
-                        }
-                    }
-                })
+                window.jyAddInfo = r.data
+                if(res.data.memberStatus > 0 && r.data.isSubCount) {
+                    $('#resbm').hide()
+                } else {
+                    $('#resbm').show()
+                }
                 if (r.data.isSubCount) {
                     $("#mainSearch-tab4").attr('data-sub','true')
                 }

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

@@ -1461,7 +1461,7 @@
     </div>
     <div class="nullcontent text-center  hidden">
         <div>
-            <div class="jy_sprite_main sprite_jysorry_1_wx" style="width:3.2rem;margin:60px 0px 50px 0px;"></div>
+            <div class="jy_sprite_main sprite_jysorry_1_wx" style="width:4rem;margin:60px 0px 0 0px;"></div>
             <!--				<img style="width:163px;margin:60px 0px 50px 0px;" src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/jysorry_1.png?v={{Msg "seo" "version"}}">-->
         </div>
         <div style="font-size:16px;color:#1d1d1d;">

+ 78 - 3
src/jfw/modules/app/src/web/templates/weixin/wxkeyset/index.html

@@ -11,7 +11,7 @@
     <link rel="stylesheet" href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/animate.css?v={{Msg "seo" "version"}}">
     <link rel="stylesheet" href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/css/keyset-list.css?v={{Msg "seo" "mod_version"}}">
 
-    <script src="https://cdn-common.jianyu360.com/cdn/lib/jquery/3.6.0/jquery.min.js"></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/jquery/3.6.0/jquery.min.js></script>
     {{include "/common/js.html"}}
 </head>
 
@@ -21,7 +21,7 @@
         <span>订阅关键词</span>
         <span></span>
     </div>
-    <div class="app-layout-content-b" v-cloak>
+    <div class="app-layout-content-b " v-cloak>
         {{if and (not .T.isIosExam) (not .T.isIosExamPhone)}}
         <div class="vip_banner">
             <div class="banner-box">
@@ -87,6 +87,17 @@
                 <a class="remind-right" href="/jyapp/vipsubscribe/introducePage" id="app-keyset-footer-banner">了解详情</a>
             </div>
         </div>
+        <div class="oldUserTips" v-show="tipsType">
+            <div class="updateTips-wrap">
+                <div class="updateTips-title">版本更新</div>
+                <div class="updateTips-text">免费订阅新版来了,请前往订阅设置更新功能后使用。</div>
+                <div class="updateTips-btnWrap">
+                    <div class="updateTips-btn" id="cancel" @click="hiddenTips">取消</div>
+                    <div class="updateTips-line"></div>
+                    <div class="updateTips-btn levelUp" id="newLevelUp"  @click="updateJump">立即更新</div>
+                </div>
+            </div>
+        </div>
     </div>
     <script>
         // 双11活动文案修改
@@ -100,12 +111,76 @@
         })
     </script>
 
-    <script src="https://cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js"></script>
+
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+    <!-- <script src=//cdn-common.jianyu360.com/cdn/lib/weui.js/1.2.1/weui.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/swiper/5.4.2/swiper.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/fastclick/1.0.6/fastclick.min.js></script> -->
     <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/swiper.min.js"></script>
     <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.js"></script>
     <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/fastclick.min.js"></script>
     <script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/js/keyset-list.js?v={{Msg "seo" "mod_version"}}"></script>
     {{include "/common/baiducc.html"}}
+    <style>
+        .oldUserTips{
+            position: fixed;
+            top: 0;
+            left: 0;
+            right: 0;
+            bottom: 0;
+            z-index: 99999;
+            background-color:rgba(0, 0, 0, 0.7);
+        }
+        .updateTips-wrap{
+            width: 6.06rem;
+            height: 3.4rem;
+            background: #FFFFFF;
+            border-radius: 0.16rem 0.16rem 0.16rem 0.16rem;
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translateX(-50%) translateY(-50%);
+        }
+        .updateTips-title{
+            text-align: center;
+            padding-top: 0.48rem;
+            font-size: 0.36rem;
+            font-weight: 500;
+            color: #161826;
+        }
+        .updateTips-text{
+            text-align: center;
+            padding: 0.16rem 0.6rem 0;
+            font-size: 0.3rem;
+            font-weight: 500;
+            color: #5E5E64;
+        }
+        .updateTips-btnWrap{
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-top: 0.32rem;
+            border-top:0.02rem solid rgba(0, 0, 0, 0.1) ;
+        }
+        .updateTips-btn{
+            font-size: 0.36rem;
+            font-weight: 500;
+            color: #161826;
+            width: 50%;
+            height: 0.92rem;
+            line-height: 0.92rem;
+            text-align: center;
+            cursor: pointer;
+        }
+        .updateTips-line{
+            height: 0.92rem;
+            width: 0.02rem;
+            background-color: rgba(0, 0, 0, 0.1);
+        }
+        .levelUp{
+            color: #2ABDD1;
+        }
+    </style>
 </body>
 
 </html>

+ 4 - 4
src/jfw/modules/app/src/web/templates/weixin/wxtsguide.html

@@ -290,7 +290,7 @@ if(localStorage && localStorage.tsGuide_status == "1"){
 					比如您输入“绿化工程”以后,当某招标人发布了《某某县中心敬老院一期观景<font class="keyword">绿化工程</font>施工》,剑鱼标讯就会把这条信息推送给您。
 				</div>
 				<div class="btnarea">
-					<button type="button" class="btn" onclick="Guide.skip()">跳过向导</button>
+					<button type="button" class="btn" onclick="Guide.skip(2)">跳过向导</button>
 					<span>
 						<button type="button" class="btn btn-normal prevStep" onclick="Guide.prevStep(2)">上一步</button>
 						<button type="button" class="btn nextStep" onclick="Guide.nextStep(2)">下一步</button>
@@ -314,7 +314,7 @@ if(localStorage && localStorage.tsGuide_status == "1"){
 					</div>
 				</div>
 				<div class="btnarea">
-					<button type="button" class="btn" onclick="Guide.skip()">跳过向导</button>
+					<button type="button" class="btn" onclick="Guide.skip(3)">跳过向导</button>
 					<span>
 						<button type="button" class="btn btn-normal prevStep" onclick="Guide.prevStep(3)">上一步</button>
 						<button type="button" class="btn nextStep" onclick="Guide.nextStep(3)">下一步</button>
@@ -339,7 +339,7 @@ if(localStorage && localStorage.tsGuide_status == "1"){
 			<div class="btnarea">
 				<span>
 					<button type="button" class="btn btn-normal prevStep" onclick="Guide.prevStep(4)">上一步</button>
-					<button type="button" class="btn nextStep" onclick="Guide.skip()">开始使用</button>
+					<button type="button" class="btn nextStep" onclick="Guide.skip(4)">开始使用</button>
 				</span>
 				<font>点击开始使用后,剑鱼标讯会为您打开订阅设置页面</font>
 			</div>
@@ -400,7 +400,7 @@ if(localStorage && localStorage.tsGuide_status == "1"){
 		}
 	})
 	$("#skipOver").on('click', function () {
-	  Guide.skip()
+	  Guide.skip(1)
 	})
 </script>
 {{include "/common/baiducc.html"}}

+ 4 - 3
src/jfw/modules/bigmember/src/config.json

@@ -15,8 +15,8 @@
         }
     ],
     "portraitPool": 5,
-    "portraitCacheDay": 30,
-    "portraitTestData":1574524800,
+    "portraitCacheDay": 1,
+    "portraitScreenPool":5,
     "rdProLimit":10,
     "followPushRpc": "127.0.0.1:8759",
     "followEnt": {
@@ -56,5 +56,6 @@
 			"name":"赵秀臻",
 			"wxer":"/big-member/image/customer/customer-wx.png"
 		}
-    ]
+    ],
+    "newFreeUser":1637647199
 }

+ 2 - 1
src/jfw/modules/bigmember/src/config/config.go

@@ -15,7 +15,7 @@ type config struct {
 	}
 	PortraitPool        int
 	PortraitCacheDay    int
-	PortraitTestData    int64
+	PortraitScreenPool  int64
 	RdProLimit          int
 	FollowPushRpc       string
 	FollowEnt           followConfig
@@ -32,6 +32,7 @@ type config struct {
 	RegWinner           string
 	OldSubscribeMoveTip int64
 	Customers           []customerInfo
+	NewFreeUser         int64 //免费用户 -- 订阅升级新用户
 }
 type customerInfo struct {
 	Name string `json:"name"`

+ 348 - 0
src/jfw/modules/bigmember/src/entity/analysis.go

@@ -0,0 +1,348 @@
+package entity
+
+import (
+	"fmt"
+	qutil "qfw/util"
+	"regexp"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+	"util"
+)
+
+var (
+	query = `{"query":{"filtered":{"filter":{"bool":{"should":[%s],"must":[%s]}},"query":{"bool":{"should":[%s],"minimum_should_match":%d}}}},"_source":[%s],"sort":[%s],"from":0,"size":%d,"aggs":{%s}}`
+	//关键词匹配
+	multi_match_public = `{"multi_match":{"query":%s,"type":"phrase","fields":[%s]}}`
+	//filter 基础匹配
+	query_bool_must = `{"terms": {%s}}`
+	//query must
+	query_bool_must_and = `{"bool": {"must": [%s]%s}}`
+	//采购单位和中标企业所有合作项目明细
+	query_allmsg_buyer_winner = `{"query":{"filtered":{"filter":{"bool":{"must":[{"term":{"buyer":"%s"}},{"term":{"s_winner":"%s"}}]}}}},"_source":[%s],"from":0,"size":%d,"sort":[{"jgtime":"desc"}],"aggs":{"sum_project":{"sum":{"field":"sortprice"}}}}`
+)
+
+const (
+	PSearch_DecField    = `"projectname","_id","buyer","firsttime","area","city","s_winner","review_experts","budget","bidamount","project_rate","bidtype","ids","winnerorder","bidtype","bidcycle"`
+	PSearch_DecMust     = `"bidstatus": ["中标","成交","合同"]`
+	PSearch_DecSimCount = 100                    //决策分析类似项目明细数据量
+	PSearch_DecSort     = `{"firsttime":"desc"}` //决策分析类似项目明细排序
+)
+
+var RegExperts = regexp.MustCompile("^[\\p{Han}]{2,4}$")
+
+//查询此中标企业 和 此采购单位 所有合作的项目
+func (this *AnalysisDec) GetAllBWQueryByBW() string {
+	return fmt.Sprintf(query_allmsg_buyer_winner, this.Buyer, this.Winner, PSearch_DecField, PSearch_DecSimCount)
+}
+
+////投标决策分析查询语句-中标企业和采购单位 类似项目明细
+func (this *AnalysisDec) DecQueryNewSimilarMsgByBW() (qstr string) {
+	//基础查询
+	bools := []string{}
+	musts := []string{}
+	shoulds := []string{}
+	var BWExists = 0
+	//中标单位 类似项目合作历史||采购单位类似项目
+	if this.Winner != "" {
+		BWExists += 1
+		winnerterms := `{"terms":{"s_winner":[`
+		for k, v := range strings.Split(this.Winner, ",") {
+			if k > 0 {
+				winnerterms += `,`
+			}
+			winnerterms += `"` + v + `"`
+		}
+		winnerterms += `]}}`
+		musts = append(musts, winnerterms)
+	}
+	//中标单位 类似项目合作历史||采购单位类似项目
+	if this.Buyer != "" {
+		BWExists += 1
+		buyerterms := `{"terms":{"buyer":[`
+		for k, v := range strings.Split(this.Buyer, ",") {
+			if k > 0 {
+				buyerterms += `,`
+			}
+			buyerterms += `"` + v + `"`
+		}
+		buyerterms += `]}}`
+		musts = append(musts, buyerterms)
+	}
+	//searchType ==1; buyer & winner 不能为空
+	if BWExists < 2 && this.SearchType == 1 {
+		this.SearchType = 0
+	}
+	//省份
+	areaCity := []string{}
+	citys := []string{}
+	if len(this.Area) > 0 {
+		areaquery := `{"terms":{"area":[`
+		var i = 0
+		for k, v := range this.Area {
+			if len(qutil.ObjArrToStringArr(v.([]interface{}))) == 0 {
+				if i > 0 {
+					areaquery += `,`
+				}
+				areaquery += `"` + k + `"`
+				i += 1
+			} else {
+				citys = append(citys, qutil.ObjArrToStringArr(v.([]interface{}))...)
+			}
+		}
+		areaquery += `]}}`
+		if i > 0 {
+			areaCity = append(areaCity, areaquery)
+		}
+	}
+	//城市
+	if len(citys) > 0 {
+		//城市对应前三十个
+		if len(citys) > 30 {
+			citys = citys[:30]
+		}
+		areaquery := `{"terms":{"city":[`
+		for k, v := range citys {
+			if k > 0 {
+				areaquery += `,`
+			}
+			areaquery += `"` + v + `"`
+		}
+		areaquery += `]}}`
+		areaCity = append(areaCity, areaquery)
+	}
+	if len(areaCity) > 0 {
+		shoulds = append(shoulds, strings.Join(areaCity, ","))
+	}
+
+	//金额区间
+	if this.MinPrice > 0 || this.MaxPrice > 0 {
+		pricequery := `{"range":{"sortprice":{`
+		if this.MinPrice > 0 {
+			pricequery += `"gte":` + strconv.Itoa(this.MinPrice*10000)
+		}
+		if this.MinPrice > 0 && this.MaxPrice > 0 {
+			pricequery += `,`
+		}
+		if this.MaxPrice > 0 {
+			pricequery += `"lt":` + strconv.Itoa(this.MaxPrice*10000)
+		}
+		pricequery += `}}}`
+		musts = append(musts, pricequery)
+	}
+	//检索日期
+	if P_Starttime != "" {
+		now := time.Now()
+		endtime := now.Unix()
+		timequery := `{"range":{"firsttime":{`
+		timequery += `"gte":` + P_Starttime
+		timequery += `,`
+		timequery += `"lt":` + strconv.FormatInt(endtime, 10)
+		timequery += `}}}`
+		musts = append(musts, timequery)
+	}
+	//中标项目
+	if PSearch_DecMust != "" {
+		musts = append(musts, fmt.Sprintf(query_bool_must, PSearch_DecMust))
+	}
+	//招标行业
+	if this.Industry != "" {
+		subscopeclass := `{"terms":{"s_subscopeclass":[`
+		for k, v := range strings.Split(this.Industry, ",") {
+			if k > 0 {
+				subscopeclass += `,`
+			}
+			subscopeclass += `"` + v + `"`
+		}
+		subscopeclass += `]}}`
+		musts = append(musts, subscopeclass)
+	}
+	//采购单位类型
+	if len(this.BuyerClass) > 0 {
+		Buyerclass := `{"terms":{"buyerclass":[`
+		for k, v := range this.BuyerClass {
+			if k > 0 {
+				Buyerclass += `,`
+			}
+			Buyerclass += `"` + v + `"`
+		}
+		Buyerclass += `]}}`
+		musts = append(musts, Buyerclass)
+	}
+	boolsNum := 0
+	//should
+	if len(this.BuyerContent) > 0 {
+		boolsNum = 1
+		findfields := `"projectname.pname","purchasing"`
+		multi_match := fmt.Sprintf(multi_match_public, "%s", findfields)
+		for _, kv := range this.BuyerContent {
+			shoulds := []string{}
+			must_not := []string{}
+			//关键词
+			for _, v := range kv.Keyword {
+				shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+v+"\""))
+			}
+			//附加词
+			if len(kv.Appended) > 0 {
+				for _, vv := range kv.Appended {
+					shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
+				}
+			}
+			if len(kv.Exclude) > 0 {
+				//排除词
+				for _, vv := range kv.Exclude {
+					must_not = append(must_not, fmt.Sprintf(multi_match, "\""+vv+"\""))
+				}
+			}
+			//添加
+			if len(shoulds) > 0 {
+				notStr := ""
+				if len(must_not) > 0 {
+					notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
+				}
+				bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
+			}
+		}
+	}
+	qstr = fmt.Sprintf(query, strings.Join(shoulds, ","), strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, PSearch_DecField, PSearch_DecSort, PSearch_DecSimCount, "")
+	return qstr
+}
+
+//
+func ThisLock(userId string) *sync.Mutex {
+	UIL.Lock()
+	if UIL.DecLock[userId] == nil {
+		UIL.DecLock[userId] = &sync.Mutex{}
+	}
+	UIL.Unlock()
+	return UIL.DecLock[userId]
+}
+
+//
+//采购内容 精准or模糊匹配处理
+func BuyerContentStruct(BC []ViewKeyWord) (arr []ViewKeyWord) {
+	if len(BC) > 0 {
+		for _, kw := range BC {
+			if kw.MatchWay == 1 {
+				for _, kk := range kw.Keyword {
+					arr = append(arr, ViewKeyWord{
+						Keyword: []string{kk},
+						Exclude: kw.Exclude,
+					})
+				}
+				for _, kk := range kw.Appended {
+					arr = append(arr, ViewKeyWord{
+						Keyword: []string{kk},
+						Exclude: kw.Exclude,
+					})
+				}
+			} else {
+				arr = append(arr, kw)
+			}
+		}
+	}
+	return arr
+}
+
+//决策分析 根据字段权重排序 中标企业和中标价格
+var (
+	bidtype_score        = 1 //采购方式
+	review_experts_score = 1 //评审专家
+	zbtime_score         = 1 //招标时间
+	bidamount_score      = 2 //中标价格
+	budget_score         = 2 //预算
+	project_rate_score   = 1 //折扣率
+	winnerorder_score    = 1 //中标候选人
+)
+
+func Sequence(seqData []map[string]interface{}) []map[string]interface{} {
+	var sequenceArr3 = []map[string]interface{}{}
+	var sequenceArr4 = []map[string]interface{}{}
+	var sequenceArr5 = []map[string]interface{}{}
+	var sequenceArr6 = []map[string]interface{}{}
+	var sequenceArr7 = []map[string]interface{}{}
+	var sequenceArr8 = []map[string]interface{}{}
+	var sequenceArr9 = []map[string]interface{}{}
+	for k, v := range seqData {
+		var score = 0
+		if v["s_winner"] == nil {
+			var s_winner = qutil.ObjToString(v["s_winner"])
+			var s_length = 0
+			for _, v := range strings.Split(s_winner, ",") {
+				if RegWinner.MatchString(v) {
+					s_length += 1
+				}
+			}
+			if s_length == 0 {
+				continue
+			}
+		}
+		//评审专家
+		review_experts := []string{}
+		if v["review_experts"] != nil {
+			for _, v := range qutil.ObjArrToStringArr(v["review_experts"].([]interface{})) {
+				if RegExperts.MatchString(v) {
+					review_experts = append(review_experts, v)
+				}
+			}
+			v["review_experts"] = review_experts
+		}
+		if len(review_experts) > 0 {
+			score += review_experts_score
+		}
+		//采购方式
+		if v["bidtype"] != nil && qutil.ObjToString(v["bidtype"].(string)) != "" {
+			score += bidtype_score
+		}
+		//招标时间
+		if v["firsttime"] != nil && qutil.Float64All(v["firsttime"].(float64)) > 0 {
+			score += zbtime_score
+		}
+		//预算
+		if v["budget"] != nil && qutil.Float64All(v["budget"].(float64)) > 0 {
+			score += budget_score
+		}
+		//中标价格
+		if v["bidamount"] != nil && qutil.Float64All(v["bidamount"].(float64)) > 0 {
+			score += bidamount_score
+		}
+		//折扣率
+		if v["project_rate"] != nil && qutil.Float64All(v["project_rate"].(float64)) > 0 {
+			score += project_rate_score
+		}
+		//中标候选人
+		if v["winnerorder"] != nil && len(qutil.ObjArrToStringArr(v["winnerorder"].([]interface{}))) > 0 {
+			score += winnerorder_score
+		}
+		//低于三分排除
+		if score < 4 {
+			// continue
+		}
+		if v["ids"] != nil {
+			ids := qutil.ObjArrToStringArr(v["ids"].([]interface{}))
+			if len(ids) > 0 {
+				v["infoid"] = util.EncodeId(ids[0])
+				delete(v, "ids")
+			}
+		}
+		v["_id"] = util.EncodeId(v["_id"].(string))
+		switch score {
+		case 4:
+			sequenceArr4 = append(sequenceArr4, seqData[k])
+		case 5:
+			sequenceArr5 = append(sequenceArr5, seqData[k])
+		case 6:
+			sequenceArr6 = append(sequenceArr6, seqData[k])
+		case 7:
+			sequenceArr7 = append(sequenceArr7, seqData[k])
+		case 8:
+			sequenceArr8 = append(sequenceArr8, seqData[k])
+		case 9:
+			sequenceArr9 = append(sequenceArr9, seqData[k])
+		default:
+			sequenceArr3 = append(sequenceArr3, seqData[k])
+		}
+	}
+	return append(append(append(append(append(append(sequenceArr9, sequenceArr8...), sequenceArr7...), sequenceArr6...), sequenceArr5...), sequenceArr4...), sequenceArr3...)
+}

+ 131 - 0
src/jfw/modules/bigmember/src/entity/analysisEntName.go

@@ -3,11 +3,15 @@ package entity
 
 import (
 	"db"
+	"encoding/json"
 	"fmt"
 	"log"
 	qutil "qfw/util"
 	"qfw/util/elastic"
+	"regexp"
 	"strings"
+	"sync"
+	"util"
 )
 
 /**即时获取项目名称列表
@@ -149,3 +153,130 @@ func GetWinnerCapitals(entName []string) map[string]int64 {
 	}
 	return entName_capitals
 }
+
+var P_Starttime = "1514736000" //2018.01.01
+
+var RegWinner = regexp.MustCompile(".+[司院厂所心处普]$")
+
+type UserInfoLock struct {
+	sync.Mutex
+	DecLock  map[string]*sync.Mutex
+	ForWLock map[string]*sync.Mutex
+}
+
+var UIL *UserInfoLock
+
+func NewUserInfoLock() *UserInfoLock {
+	return &UserInfoLock{
+		DecLock:  make(map[string]*sync.Mutex),
+		ForWLock: make(map[string]*sync.Mutex),
+	}
+}
+
+//决策分析-中标企业和采购单位 其他项目明细
+type AnalysisDec struct {
+	Area             map[string]interface{} //地区
+	BuyerContent     []ViewKeyWord          //采购内容
+	BuyerClass       []string               //采购单位类型
+	Sid              string                 //项目招标信息id
+	Pname            string                 //项目名称
+	Industry         string                 //招标行业
+	MinPrice         int                    //最小价格
+	MaxPrice         int                    //最大价格
+	Buyer            string                 //采购单位
+	ServiceId        int                    //大会员服务id
+	MobileModel      string                 //手机型号
+	AppVersion       string                 //app版本号
+	Winner           string                 //中标企业
+	SearchType       int                    //默认0:中标企业||采购单位||(中标企业&&采购单位)-类似项目明细;1:中标企业和采购单位其他项目明细
+	UserId           string                 //用户id
+	IsPower          bool                   //是否有权限
+	UserLock         sync.Mutex             //用户锁
+	Buyer_BuyerClass string                 //当前采购单位的采购单位类型
+}
+
+/*已选条件--关键词*/
+type ViewKeyWord struct {
+	Keyword  []string `json:"key"`       //关键词
+	Appended []string `json:"appendkey"` //附加词
+	Exclude  []string `json:"notkey"`    //排除词
+	MatchWay int      `json:"matchway"`  //匹配模式
+}
+
+func CheckPower(userId string) (string, bool) {
+	main_userId, _, member_status := util.MainUserId(userId, "", 0)
+	return main_userId, member_status > 0
+}
+
+//
+func (this *AnalysisDec) GetProjectInfoByBW() (res []map[string]interface{}) {
+	this.UserLock.Lock()
+	defer this.UserLock.Unlock()
+	//采购单位的采购类型
+	if this.Buyer != "" {
+		buyerData := GetEntPC(strings.Split(this.Buyer, ","))
+		if buyerData != nil && len(buyerData) > 0 {
+			buyer_one := *qutil.ObjToMap(buyerData[0])
+			if buyer_one["buyerclass"] != nil {
+				this.Buyer_BuyerClass = buyer_one["buyerclass"].(string)
+			}
+		}
+	}
+	this.BuyerContent = BuyerContentStruct(this.BuyerContent)
+	//中标企业和采购单位类似项目明细
+	decQuery := this.DecQueryNewSimilarMsgByBW()
+	// log.Println("decQuery:", decQuery)
+	similarMsg, _idMap := this.GetAllMsgByBW(decQuery)
+	// log.Println(len(similarMsg), _idMap, "ti--:", this.SearchType)
+	//其他项目明细
+	switch this.SearchType {
+	case 0:
+		res = similarMsg
+	case 1:
+		//中标企业和采购单位 所有项目明细
+		allQuery := this.GetAllBWQueryByBW()
+		allMsg, _ := this.GetAllMsgByBW(allQuery)
+		// log.Println(allQuery, "----", len(allMsg))
+		if len(allMsg) > 0 {
+			for _, v := range allMsg {
+				id := qutil.ObjToString(v["_id"])
+				if _idMap[id] {
+					continue
+				}
+				res = append(res, v)
+			}
+		}
+	}
+	return Sequence(res)
+}
+
+//获取数据
+func (this *AnalysisDec) GetAllMsgByBW(decQuery string) (res []map[string]interface{}, idMap map[string]bool) {
+	//查询列表数据
+	client := elastic.GetEsConn()
+	defer elastic.DestoryEsConn(client)
+	if client == nil {
+		return nil, nil
+	}
+	searchResult, err := client.Search().Index("projectset").Type("projectset").Source(decQuery).Do()
+	if err != nil {
+		return nil, nil
+	}
+	if searchResult.Hits != nil {
+		resNum := len(searchResult.Hits.Hits)
+		res = make([]map[string]interface{}, resNum)
+		idMap = map[string]bool{}
+		for i, hit := range searchResult.Hits.Hits {
+			json.Unmarshal(*hit.Source, &res[i])
+			//查询结果数据加工处理
+			for k, v := range hit.Highlight {
+				res[i][k] = v[0]
+			}
+			_id, _ := res[i]["_id"].(string)
+			if _id != "" {
+				idMap[_id] = true
+			}
+		}
+	}
+	return res, idMap
+}

+ 14 - 5
src/jfw/modules/bigmember/src/entity/followEnterprise.go

@@ -515,6 +515,7 @@ func (this *EntFollow) DelFollowEnt(entId, fid string) error {
 }
 
 //企业情报====================================================================
+
 func (this *EntFollow) GetEntIdByName(entName string) (string, error) {
 	if entName == "" {
 		return "", errors.New("企业名称异常")
@@ -526,10 +527,10 @@ func (this *EntFollow) GetEntIdByName(entName string) (string, error) {
 	return entId, nil
 }
 
-//获取企业变更信息
-func (this *EntFollow) GetEntChangeList(entId string) ([]map[string][]EntChangeSort, error) {
+//GetEntChangeList 获取企业变更信息
+func (this *EntFollow) GetEntChangeList(entId string, showPart int) ([]map[string][]EntChangeSort, int, error) {
 	if entId == "" {
-		return nil, errors.New("企业名称异常")
+		return nil, -1, errors.New("企业名称异常")
 	}
 	entinfo, _ := db.Mgo_Ent.FindOneByField("qyxy_change", map[string]interface{}{
 		"company_id": entId,
@@ -537,7 +538,7 @@ func (this *EntFollow) GetEntChangeList(entId string) ([]map[string][]EntChangeS
 		"changes": 1, //变更记录
 	})
 	if entinfo == nil || len(*entinfo) == 0 || (*entinfo)["changes"] == nil {
-		return nil, errors.New("未查询到企业相关信息")
+		return nil, -1, errors.New("未查询到企业相关信息")
 	}
 	var _rData = []map[string][]EntChangeSort{}
 	rData := qutil.ObjArrToMapArr((*entinfo)["changes"].([]interface{}))
@@ -545,7 +546,15 @@ func (this *EntFollow) GetEntChangeList(entId string) ([]map[string][]EntChangeS
 		//初始化排序
 		_rData = InitializeSort(rData)
 	}
-	return _rData, nil
+	total := len(_rData)
+	if showPart != 0 && total != 0 {
+		max := total - 1
+		if showPart < max {
+			max = showPart
+		}
+		_rData = _rData[:max]
+	}
+	return _rData, total, nil
 }
 
 type EntChangeSort struct {

+ 3 - 30
src/jfw/modules/bigmember/src/entity/portrailUtil.go

@@ -1,7 +1,6 @@
 package entity
 
 import (
-	"config"
 	"db"
 	"encoding/json"
 	"fmt"
@@ -28,10 +27,7 @@ const (
 //redis存储月份键值
 func getPortraitRedisCatchKey(sType, name string) string {
 	timeFlag := time.Now()
-	if config.Config.PortraitTestData > 0 {
-		timeFlag = time.Unix(config.Config.PortraitTestData, 0)
-	}
-	timeStr := timeFlag.Format("200601")
+	timeStr := timeFlag.Format("20060102")
 	return fmt.Sprintf("portrait_%s_%s_%s", timeStr, name, sType)
 }
 
@@ -94,34 +90,11 @@ type SimpleStringKeyValue struct {
 	Key string `json:"key"`
 }
 
-//画像时间短
-func GetPortraitTimeRange() (start, end time.Time) {
-	now := time.Now()
-	if config.Config.PortraitTestData > 0 {
-		now = time.Unix(config.Config.PortraitTestData, 0)
-	}
-	local := now.Location()
-	currentYear, currentMonth, _ := now.Date()
-	end = time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, local)
-	if currentMonth == 1 {
-		start = time.Date(currentYear-3, 1, 1, 0, 0, 0, 0, local)
-		return
-	}
-	start = time.Date(currentYear-2, 1, 1, 0, 0, 0, 0, local)
-	return
-}
-
 //获取中标金额聚合查询语句(近三年统计月份,5-3年统计年份)
-func getBidamountStatistics(bTime, sTime, eTime time.Time) string {
+func getBidamountStatistics(sTime, eTime time.Time) string {
 	timeRange := ``
 	//三年外统计年份
-	tmpTime := bTime
-	for bTime.Before(sTime) {
-		bTime = bTime.AddDate(1, 0, 0)
-		timeRange += fmt.Sprintf(`{"key":"%d","from":%d,"to":%d},`, tmpTime.Year(), tmpTime.Unix(), bTime.Unix())
-		tmpTime = bTime
-	}
-
+	tmpTime := sTime
 	//近三年统计月份
 	for sTime.Before(eTime) {
 		sTime = sTime.AddDate(0, 1, 0)

+ 60 - 59
src/jfw/modules/bigmember/src/entity/portrait.go

@@ -126,7 +126,8 @@ func paseDateToint64(dateStr string) (timeStamp int64) {
 }
 
 //画像接口===============================================================================
-//获取企业id
+
+//GetEntIdByName 获取企业id
 func (this *Portrait) GetEntIdByName(entName string) (string, error) {
 	if entName == "" {
 		return "", errors.New("企业名称异常")
@@ -138,7 +139,7 @@ func (this *Portrait) GetEntIdByName(entName string) (string, error) {
 	return entId, nil
 }
 
-//企业画像-获取历史项目联系方式
+//GetWinnerContactsMsg 企业画像-获取历史项目联系方式
 func (this *Portrait) GetWinnerContactsMsg(entId string) ([]map[string]interface{}, error) {
 	if entId == "" {
 		return nil, errors.New("企业名称异常")
@@ -146,16 +147,20 @@ func (this *Portrait) GetWinnerContactsMsg(entId string) ([]map[string]interface
 	return GetProjectContactsMsg("", entId), nil
 }
 
-//企业画像-查询最新项目动态
+//GetWinnerNewMsg 企业画像-查询最新项目动态
 //增加 match 搜索词
 //	  matchType 搜索范围
 //    area 项目地区
 //    pushTime 发布时间
-func (this *Portrait) GetWinnerNewMsg(pwp *PortraitWinnerProject) ([]map[string]interface{}, int64, error) {
-	return pwp.GetList()
+func (this *Portrait) GetWinnerNewMsg(pwp *PortraitProjectScreen) ([]map[string]interface{}, int64, error) {
+	return pwp.GetWinnerList()
+}
+
+func (this *Portrait) GetBuyerNewMsg(pwp *PortraitProjectScreen) ([]map[string]interface{}, int64, error) {
+	return pwp.GetBuyerList()
 }
 
-//企业画像-查询最新项目数量(前端用于展示是否加载更多)
+//GetWinnerNewCount 企业画像-查询最新项目数量(前端用于展示是否加载更多)
 func (this *Portrait) GetWinnerNewCount(entId string) int64 {
 	if entId == "" {
 		return -1
@@ -164,20 +169,32 @@ func (this *Portrait) GetWinnerNewCount(entId string) int64 {
 	return count
 }
 
-//企业画像-查询
-func (this *Portrait) WinnerPortraitData(entId string, hasPower bool) (map[string]interface{}, error) {
-	if entId == "" {
+//WinnerPortraitData 企业画像-查询
+func (this *Portrait) WinnerPortraitData(screen *PortraitScreen) (map[string]interface{}, error) {
+	if screen.Ent == "" {
 		return nil, errors.New("企业名称异常")
 	}
-	winnerPortraitData := TryFunc(GetPortraitCache, entId, "winner", 2)
-	if !hasPower && winnerPortraitData != nil { //无权限 仅返回免费字段(市场区域分布字段)
+	resMap := map[string]interface{}{}
+	if !screen.HasPower || screen.IsEmptySearch() { //空查询读缓存
+		resMap = TryFunc(GetPortraitCache, screen.Ent, "winner", 2)
+	} else {
+		Screen_Thread <- true
+		winnerPortraitData, err := GetWinnerPortraitSearch(screen)
+		<-Screen_Thread
+		if err != nil {
+			return nil, fmt.Errorf("%s  检索异常 %v\n", screen.Ent, err)
+		}
+		resMap = winnerPortraitData
+	}
+
+	if !screen.HasPower && resMap != nil { //无权限 仅返回免费字段(市场区域分布字段)
 		freeReturnMap := map[string]interface{}{}
 		for _, key := range []string{"timeRange", "buyer_count", "bidamount_count", "project_count", "area_count"} {
-			freeReturnMap[key] = winnerPortraitData[key]
+			freeReturnMap[key] = resMap[key]
 		}
 		return freeReturnMap, nil
 	}
-	return winnerPortraitData, nil
+	return resMap, nil
 }
 
 //WinnerMiniPortraitData 三级页引流
@@ -186,9 +203,6 @@ func (this *Portrait) WinnerMiniPortraitData(entId string) (map[string]interface
 		return nil, errors.New("企业名称异常")
 	}
 	winnerPortraitData := TryFunc(GetPortraitCache, entId, "winner", 2)
-	if winnerPortraitData == nil {
-		return nil, nil
-	}
 	miniReturnMap := map[string]interface{}{}
 	for _, key := range []string{"bidamount_count", "project_count"} {
 		miniReturnMap[key] = winnerPortraitData[key]
@@ -196,18 +210,7 @@ func (this *Portrait) WinnerMiniPortraitData(entId string) (map[string]interface
 	return miniReturnMap, nil
 }
 
-//采购单位画像-查询最新项目动态
-func (this *Portrait) GetBuyerNewMsg(buyer string, start, limit int, hasPower bool) ([]map[string]interface{}, error) {
-	if buyer == "" {
-		return nil, errors.New("企业名称异常")
-	}
-	//if start > PortraitNewMegsLimit || start+limit > PortraitNewMegsLimit {
-	//	return nil, errors.New("超出检索限制")
-	//}
-	return GetBuyerNewProject(buyer, start, limit, hasPower), nil
-}
-
-//采购单位画像
+//GetBuyerContactsMsg 采购单位联系人
 func (this *Portrait) GetBuyerContactsMsg(buyerName string) ([]map[string]interface{}, error) {
 	if buyerName == "" {
 		return nil, errors.New("企业名称异常")
@@ -215,70 +218,68 @@ func (this *Portrait) GetBuyerContactsMsg(buyerName string) ([]map[string]interf
 	return GetProjectContactsMsg(buyerName, ""), nil
 }
 
-//采购单位画像-查询最新项目数量(前端用于展示是否加载更多)
+//GetBuyerNewCount 采购单位画像-查询最新项目数量(前端用于展示是否加载更多)
 func (this *Portrait) GetBuyerNewCount(buyer string) int64 {
 	if buyer == "" {
 		return -1
 	}
 	count := GetBuyerNewProjectCount(buyer)
-	//if count > PortraitNewMegsLimit {
-	//	count = PortraitNewMegsLimit
-	//}
 	return count
 }
 
-//采购单位画像-查询
+//BuyerPortraitData 采购单位画像-查询
 //flag 分段请求标识 a年度统计和节支率等 b重点合作企业 c合作企业注册资本、地区、年份分布
 //a段数据=timeRange、city、province、buyerclass、bidamount_count、fail_count、project_count、winner_count、otherProvincesWinnerCount、yearData、monthData、moneyRange、bidtypeData、rate、top12、topAgencyData
 //b段数据=topShow
 //c段数据=withCapitalData、withAreaData、withEstablishData
-func (this *Portrait) BuyerPortraitData(buyer string, flag string, hasPower bool) (map[string]interface{}, error) {
-	if buyer == "" {
+func (this *Portrait) BuyerPortraitData(screen *PortraitScreen, flag string) (map[string]interface{}, error) {
+	if screen.Ent == "" {
 		return nil, errors.New("企业名称异常")
 	}
-
-	if !(flag == "a" || flag == "b" || flag == "c" || flag == "") {
-		return nil, errors.New("参数异常")
+	buyerPortraitData := map[string]interface{}{}
+	if screen.IsEmptySearch() { //空查询读缓存
+		buyerPortraitData = TryFunc(GetPortraitCache, screen.Ent, "buyer", 5)
+	} else {
+		Screen_Thread <- true
+		res, err := GetBuyerPortraitData(screen)
+		<-Screen_Thread
+		if err != nil {
+			return nil, err
+		}
+		buyerPortraitData = res
 	}
-	if !hasPower { //免费返回字段
-		if buyerPortraitAllData := TryFunc(GetPortraitCacheByStep, buyer, fmt.Sprintf("buyer_%s", flag), 2); buyerPortraitAllData != nil {
+	if !screen.HasPower { //免费返回字段
+		if buyerPortraitData != nil {
 			freeReturnMap := map[string]interface{}{}
 			//第一阶段免费数据
-			for _, key := range []string{"timeRange", "city", "province", "buyerclass", "fail_count", "project_count", "winner_count", "otherProvincesWinnerCount"} {
-				freeReturnMap[key] = buyerPortraitAllData[key]
-			}
-			//第三阶段免费字段
-			if flag == "" || flag == "c" {
-				for _, key := range []string{"withCapitalData", "withAreaData", "withEstablishData"} {
-					freeReturnMap[key] = buyerPortraitAllData[key]
-				}
+			for _, key := range []string{"timeRange", "city", "province", "buyerclass", "fail_count", "project_count", "winner_count", "otherProvincesWinnerCount", "withCapitalData", "withAreaData", "withEstablishData"} {
+				freeReturnMap[key] = buyerPortraitData[key]
 			}
 			return freeReturnMap, nil
 		}
 		return nil, nil
 	}
-	buyerPortraitData := TryFunc(GetPortraitCacheByStep, buyer, fmt.Sprintf("buyer_%s", flag), 2)
-	if flag == "" || flag == "b" { //只有查询全部或者查询b分布画像时,返回内容有重点合作企业
-		if buyerPortraitData != nil {
-			//重点合作企业 展示读者行业
-			if topShow, ok := buyerPortraitData["topShow"]; ok {
-				buyerPortraitData["topShow"] = formatUserTopShowList(this.UserId, topShow)
-			}
-			//删除多余数据
-			delete(buyerPortraitData, "allWinnerList")
+	if buyerPortraitData != nil { //只有查询全部或者查询b分布画像时,返回内容有重点合作企业
+		//重点合作企业 展示读者行业
+		if topShow, ok := buyerPortraitData["topShow"]; ok {
+			buyerPortraitData["topShow"] = formatUserTopShowList(this.UserId, topShow)
 		}
+		//删除多余数据
+		delete(buyerPortraitData, "allWinnerList")
 	}
 	return buyerPortraitData, nil
 }
 
+//BuyerMiniPortraitData 采购单位引流接口
 func (this *Portrait) BuyerMiniPortraitData(buyer string) (map[string]interface{}, error) {
 	if buyer == "" {
 		return nil, errors.New("企业名称异常")
 	}
 	miniReturnMap := map[string]interface{}{}
-	if buyerPortraitAllData := TryFunc(GetPortraitCacheByStep, buyer, "buyer_a", 2); buyerPortraitAllData != nil {
+	buyerPortraitData := TryFunc(GetPortraitCache, buyer, "buyer", 2)
+	if buyerPortraitData != nil {
 		for _, key := range []string{"province", "city", "buyerclass", "bidamount_count", "project_count"} {
-			miniReturnMap[key] = buyerPortraitAllData[key]
+			miniReturnMap[key] = buyerPortraitData[key]
 		}
 		return miniReturnMap, nil
 	}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 2
src/jfw/modules/bigmember/src/entity/portraitBuyerSearch.go


+ 86 - 42
src/jfw/modules/bigmember/src/entity/portraitWinnerSearch.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"log"
 	qutil "qfw/util"
 	"qfw/util/elastic"
 	"sort"
@@ -13,11 +14,10 @@ import (
 )
 
 const (
-	winnerPortraitSearchSql = `{"query":{"filtered":{"filter":{"bool":{"must":[{"term":{"entidlist":"%s"}},{"range":{"firsttime":{"lt":%d}}}]}}}},"aggs":{"three_year_data":{"filter":{"bool":{"must":[{"range":{"firsttime":{"gte":%d}}}]}},"aggs":{"bidamount_count":{"sum":{"field":"bidamount"}},"area_count":{"cardinality":{"field":"area"}},"buyer_count":{"cardinality":{"field":"buyer"}},"group_area":{"terms":{"field":"area","size":40},"aggs":{"bidamount_count":{"sum":{"field":"bidamount"}}}},"all_buyerclass":` + YearRate + `,"top_buyerclass":{"terms":{"field":"buyerclass","size":11,"order":[{"buyerclass_count_bidamount":"desc"}]},"aggs":{"buyerclass_avg_rate":` + BaseRate + `,"buyerclass_count_bidamount":{"sum":{"field":"bidamount"}},"buyerclass_top_buyer":{"terms":{"field":"buyer","order":[{"count_top_buyer":"desc"},{"_count":"desc"},{"last_winner_time":"desc"}],"size":5},"aggs":{"count_top_buyer":{"sum":{"field":"bidamount"}},"avg_rate_top_buyer":` + BaseRate + `,"last_winner_time":{"max":{"field":"firsttime"}}}},"top_buyerclass_rate_time_avg":` + YearRate + `}}}},"five_year_data_bidamount":{"filter":{"bool":{"must":[{"range":{"firsttime":{"gte":%d}}}]}},"aggs":{"year_bidamount":{"range":{"field":"firsttime","ranges":[%s]},"aggs":{"count":{"sum":{"field":"bidamount"}}}}}}},"size":0}`
-	winnerContactsSearch    = `{"bool":{"must":[{"term":{"projectset.entidlist":"%s"}}],"must_not":[{"term":{"projectset.buyertel":""}}]}}`
+	winnerPortraitSearchSql = `{"query":{"bool":{"must":[%s]}},"aggs":{"bidamount_count":{"sum":{"field":"bidamount"}},"area_count":{"cardinality":{"field":"area"}},"buyer_count":{"cardinality":{"field":"buyer"}},"group_area":{"terms":{"field":"area","size":40},"aggs":{"bidamount_count":{"sum":{"field":"bidamount"}}}},"all_buyerclass":` + YearRate + `,"top_buyerclass":{"terms":{"field":"buyerclass","size":11,"order":[{"buyerclass_count_bidamount":"desc"}]},"aggs":{"buyerclass_avg_rate":` + BaseRate + `,"buyerclass_count_bidamount":{"sum":{"field":"bidamount"}},"buyerclass_top_buyer":{"terms":{"field":"buyer","order":[{"count_top_buyer":"desc"},{"_count":"desc"},{"last_winner_time":"desc"}],"size":5},"aggs":{"count_top_buyer":{"sum":{"field":"bidamount"}},"avg_rate_top_buyer":` + BaseRate + `,"last_winner_time":{"max":{"field":"firsttime"}}}},"top_buyerclass_rate_time_avg":` + YearRate + `}},"year_bidamount":{"range":{"field":"firsttime","ranges":[%s]},"aggs":{"count":{"sum":{"field":"bidamount"}}}}},"size":0}`
 )
 
-//根据名称获取企业id【精确匹配】
+//GetWinnerIdByName 根据名称获取企业id【精确匹配】
 func GetWinnerIdByName(entName string) (entId string) {
 	if entName == "" {
 		return
@@ -30,7 +30,8 @@ func GetWinnerIdByName(entName string) (entId string) {
 	return
 }
 
-//项目联系方式 查询最新200条记录 筛选获取联系方式
+//GetProjectContactsMsg 项目联系方式 查询最新200条记录 筛选获取联系方式
+//dev4.6.2.1 删除限制200个项目
 func GetProjectContactsMsg(buyerName, entId string) (list []map[string]interface{}) {
 	defer qutil.Catch()
 	list = make([]map[string]interface{}, 0, 0)
@@ -44,8 +45,7 @@ func GetProjectContactsMsg(buyerName, entId string) (list []map[string]interface
 	if musts == nil || len(musts) == 0 {
 		return list
 	}
-	searchSql := fmt.Sprintf(`{"query":{"bool":{"must":[%s]}},"_source":["_id","zbtime","projectname","list"],"sort":[{"zbtime":"desc"}],"size":200}`, strings.Join(musts, ","))
-	//fmt.Println("searchSql", searchSql)
+	searchSql := fmt.Sprintf(`{"query":{"bool":{"must":[%s]}},"_source":["_id","zbtime","projectname","list"],"sort":[{"zbtime":"desc"}]}`, strings.Join(musts, ","))
 	projectList := elastic.Get("projectset", "projectset", searchSql)
 	if projectList == nil || len(*projectList) == 0 {
 		return list
@@ -102,35 +102,82 @@ func GetProjectContactsMsg(buyerName, entId string) (list []map[string]interface
 	return
 }
 
-//中标企业-获取历史项目联系方式数量
-func GetWinnerContactsMsgCount(entId string) int64 {
+//GetWinnerPortraitSearch 中标企业画像
+func GetWinnerPortraitSearch(screen *PortraitScreen) (map[string]interface{}, error) {
 	defer qutil.Catch()
-	return elastic.Count("projectset", "projectset", fmt.Sprintf(`{"query":%s}`, fmt.Sprintf(winnerContactsSearch, entId)))
-}
 
-//中标企业画像
-func GetWinnerPortraitSearch(entId string) (map[string]interface{}, error) {
-	defer qutil.Catch()
-	startTime, endTime := GetPortraitTimeRange()
-	fiveYearTime := startTime.AddDate(-2, 0, 0) //需要中标金额统计开始年份之前两年
-	bidamountTimeRange := getBidamountStatistics(fiveYearTime, startTime, endTime)
+	startTime, endTime := screen.PareTimeSelect(true)
+
+	bidamountTimeRange := getBidamountStatistics(startTime, endTime)
 	comminTimeRange := getCommonYearStatistics(startTime, endTime)
+
+	//画像筛选
+	var mustQueryArr []string
+	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"entidlist":"%s"}}`, screen.Ent))
+
+	//按照当前年份,往前推4年,共5个年份可选
+	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"firsttime":{"gte":"%d","lt":"%d"}}}`, startTime.Unix(), endTime.Unix()))
+
+	if screen.HasPower {
+		//文本输入框,字数限制50个字,超过上限不再允许输入内容
+		if screen.Match != "" {
+			if pareWord := screen.PareMatchWord(); pareWord != "" {
+				findFields := fmt.Sprintf(`"%s"`, strings.Join(screen.PareMatchType(), "\",\""))
+				var keywordArr []string
+				for _, keyword := range strings.Split(pareWord, " ") {
+					if keyword == "" {
+						continue
+					}
+					keywordArr = append(keywordArr, fmt.Sprintf(multi_match, keyword, findFields))
+				}
+				if screen.ExactMatch { //精确匹配(必须包含每个关键词)
+					mustQueryArr = append(mustQueryArr, fmt.Sprintf(must_match, strings.Join(keywordArr, ",")))
+				} else { //模糊匹配(只需包含一个关键词)
+					mustQueryArr = append(mustQueryArr, fmt.Sprintf(should_match, strings.Join(keywordArr, ",")))
+				}
+			}
+		}
+
+		//地区多选,选项:全部(初始值)、项目地区(省、直辖市)
+		if screen.Area != "" {
+			mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"area":["%s"]}}`, strings.ReplaceAll(screen.Area, ",", "\",\"")))
+		}
+
+		//行业多选
+		if screen.ScopeClass != "" {
+			mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"subscopeclass":["%s"]}}`, strings.ReplaceAll(screen.ScopeClass, ",", "\",\"")))
+		}
+	}
+
+	//开始查询
 	tBegin := time.Now()
-	doSearchSql := fmt.Sprintf(winnerPortraitSearchSql, entId, endTime.Unix(), startTime.Unix(), comminTimeRange, comminTimeRange, fiveYearTime.Unix(), bidamountTimeRange)
-	res, _ := GetAggs("projectset", "projectset", doSearchSql)
+	doSearchSql := fmt.Sprintf(winnerPortraitSearchSql, strings.Join(mustQueryArr, ","), comminTimeRange, comminTimeRange, bidamountTimeRange)
+	res, docCount := GetAggs("projectset", "projectset", doSearchSql)
 	if res == nil {
-		return nil, errors.New(fmt.Sprintf("%s中标企业画像查询异常\n", entId))
+		return nil, errors.New(fmt.Sprintf("%s中标企业画像查询异常\n", screen.Ent))
 	}
 	returnData := map[string]interface{}{
+		//统计时间
 		"timeRange": map[string]int64{
 			"start": startTime.Unix(),
-			"end":   endTime.Unix() - 1,
+			"end":   endTime.Unix(),
 		},
+		//项目数
+		"project_count": docCount,
 	}
-	//五年数据 年度项目统计&近三年月度中标金额
-	if g, ok := res.Children("five_year_data_bidamount"); ok {
+	//中标总额 地区数量 客户数量
+	for _, dataType := range []string{"bidamount_count", "area_count", "buyer_count"} {
+		if data, ok := res[dataType]; ok {
+			if b, err := data.MarshalJSON(); err == nil {
+				thisData := qutil.ObjToMap(string(b))
+				returnData[dataType] = (*thisData)["value"]
+			}
+		}
+	}
+	//月度中标金额
+	if g, ok := res["year_bidamount"]; ok {
 		bidamountData := YearBidamount{}
-		bs, _ := g.Aggregations["year_bidamount"].MarshalJSON()
+		bs, _ := g.MarshalJSON()
 		if json.Unmarshal(bs, &bidamountData) == nil && len(bidamountData.Buckets) > 0 {
 			yearData := map[int]struct {
 				Count int
@@ -171,19 +218,10 @@ func GetWinnerPortraitSearch(entId string) (map[string]interface{}, error) {
 			returnData["monthData"] = monthData
 		}
 	}
-	//三年数据
-	if g, ok := res.Children("three_year_data"); ok {
-		//项目数
-		returnData["project_count"] = g.DocCount
-		//中标总额 地区数量 客户数量
-		for _, dataType := range []string{"bidamount_count", "area_count", "buyer_count"} {
-			if b, err := g.Aggregations[dataType].MarshalJSON(); err == nil {
-				thisData := qutil.ObjToMap(string(b))
-				returnData[dataType] = (*thisData)["value"]
-			}
-		}
-		//地区分布
-		if areaBytes, err := g.Aggregations["group_area"].MarshalJSON(); err == nil {
+
+	//地区分布
+	if g, ok := res["group_area"]; ok {
+		if areaBytes, err := g.MarshalJSON(); err == nil {
 			areaData := struct {
 				Buckets []struct {
 					AreaName       string    `json:"key"`
@@ -203,9 +241,12 @@ func GetWinnerPortraitSearch(entId string) (map[string]interface{}, error) {
 				returnData["areaData"] = areaReturn
 			}
 		}
-		//全部折扣率
-		rataMap := map[string]interface{}{}
-		if allRateBytes, err := g.Aggregations["all_buyerclass"].MarshalJSON(); err == nil {
+	}
+
+	//全部折扣率
+	rataMap := map[string]interface{}{}
+	if g, ok := res["group_area"]; ok {
+		if allRateBytes, err := g.MarshalJSON(); err == nil {
 			allRate := struct {
 				DocCount int `json:"doc_count"`
 				YearRate struct {
@@ -222,8 +263,11 @@ func GetWinnerPortraitSearch(entId string) (map[string]interface{}, error) {
 				}
 			}
 		}
-		//前11行业 数据
-		if topBuyerclassBytes, err := g.Aggregations["top_buyerclass"].MarshalJSON(); err == nil {
+	}
+
+	//前11行业 数据
+	if g, ok := res["top_buyerclass"]; ok {
+		if topBuyerclassBytes, err := g.MarshalJSON(); err == nil {
 			topBuyerclassObj := struct {
 				Buckets []struct {
 					BuyerClass     string       `json:"key"`                 //行业
@@ -376,7 +420,7 @@ func GetWinnerPortraitSearch(entId string) (map[string]interface{}, error) {
 		returnData["rate"] = rataMap
 	}
 	go func() {
-		fmt.Printf("WinnerPortraitSearch: %s spend time %fs\n	doSearchSql: %s\n", entId, time.Since(tBegin).Seconds(), doSearchSql)
+		log.Printf("WinnerPortraitSearch: %s spend time %fs\n", screen.Ent, time.Since(tBegin).Seconds())
 	}()
 	return returnData, nil
 }

+ 32 - 35
src/jfw/modules/bigmember/src/entity/portrait_manager.go

@@ -3,11 +3,8 @@ package entity
 import (
 	"config"
 	"encoding/json"
-	"fmt"
 	"log"
-	qutil "qfw/util"
 	"qfw/util/redis"
-	"strings"
 	"sync"
 	"time"
 )
@@ -17,22 +14,24 @@ const (
 )
 
 var (
-	Hx_Thread   chan bool
-	Prior_chan1 = make(chan *PortraitSearch)
-	Prior_chan2 = make(chan *PortraitSearch)
-	Prior_chan3 = make(chan *PortraitSearch)
+	Hx_Thread     chan bool
+	Screen_Thread chan bool
+	Prior_chan1   = make(chan *PortraitSearch)
+	Prior_chan2   = make(chan *PortraitSearch)
+	Prior_chan3   = make(chan *PortraitSearch)
 
 	DoSearchCheck *SearchRepeatCheck
 )
 
 func init() {
 	Hx_Thread = make(chan bool, config.Config.PortraitPool) //走配置文件 同时查询限制
+	Screen_Thread = make(chan bool, config.Config.PortraitScreenPool)
 	go Qyhx_search_chan()
 	//go redisToChan3()
 	DoSearchCheck = NewSearchCheck()
 }
 
-//防止重复查询
+//SearchRepeatCheck 防止重复查询
 type SearchRepeatCheck struct {
 	DoSearching map[string]bool //正在查询的
 	Check       sync.RWMutex    //锁
@@ -57,7 +56,6 @@ func (this *SearchRepeatCheck) Del(key string) {
 	delete(this.DoSearching, key)
 }
 
-//查询
 type PortraitSearch struct {
 	EntName  string //企业名称
 	DoType   string //画像类型
@@ -122,14 +120,14 @@ func Qyhx_search(obj *PortraitSearch) {
 	start := time.Now()
 	switch obj.DoType {
 	case "winner":
-		data, err := GetWinnerPortraitSearch(obj.EntName)
+		data, err := GetWinnerPortraitSearch(&PortraitScreen{Ent: obj.EntName, HasPower: false})
 		if err != nil {
 			log.Printf("%s %s 检索异常 %v\n", obj.EntName, obj.DoType, err)
 			return
 		}
 		go upDataQxhxRedis(obj.RedisKey, data)
 	case "buyer":
-		data, err := GetBuyerPortraitData(obj.EntName)
+		data, err := GetBuyerPortraitData(&PortraitScreen{Ent: obj.EntName, HasPower: false})
 		if err != nil {
 			log.Printf("%s %s 检索异常 %v\n", obj.EntName, obj.DoType, err)
 			return
@@ -139,13 +137,14 @@ func Qyhx_search(obj *PortraitSearch) {
 	log.Printf("%s %s 检索完成 耗时%v\n", obj.EntName, obj.DoType, time.Since(start))
 }
 
-//客户画像存储
+//upDataQxhxRedis 客户画像存储
 func upDataQxhxRedis(redisKey string, data interface{}) {
 	if data != nil {
 		redis.Put("other", redisKey, data, 60*60*24*config.Config.PortraitCacheDay) //走配置文件缓存时长
 	}
 }
 
+//TryFunc 画像查询,读存缓存
 func TryFunc(f func(string, string) map[string]interface{}, ent, do string, times int) map[string]interface{} {
 	for i := times; i > 0; i-- {
 		if r := f(ent, do); r != nil {
@@ -156,6 +155,7 @@ func TryFunc(f func(string, string) map[string]interface{}, ent, do string, time
 	return nil
 }
 
+//GetPortraitCache 空筛选读缓存数据
 func GetPortraitCache(winner, doType string) map[string]interface{} {
 	hxObj := getInitPortraitSearch(winner, doType)
 	if rBytes, err := redis.GetBytes("other", hxObj.RedisKey); err == nil && len(*rBytes) != 0 {
@@ -170,26 +170,23 @@ func GetPortraitCache(winner, doType string) map[string]interface{} {
 	return nil
 }
 
-//采购单位画像分阶段查询
-func GetPortraitCacheByStep(buyer, doType string) map[string]interface{} {
-	flag := ""
-	if arr := strings.Split(doType, "_"); len(arr) == 2 {
-		doType, flag = arr[0], arr[1]
-	}
-	hxObj := getInitPortraitSearch(buyer, doType)
-	if rBytes, err := redis.GetBytes("other", hxObj.RedisKey); err == nil && len(*rBytes) != 0 {
-		data := map[string]interface{}{}
-		err := json.Unmarshal(*rBytes, &data)
-		if err == nil {
-			if _, ok := data[fmt.Sprintf("step_%s", qutil.If(flag == "", "c", flag))]; ok { //传入空时 需要全部数据,必须等到所有值都用时才返回
-				log.Printf("%s分段请求%s 返回内容", buyer, flag)
-				return data
-			}
-		}
-		log.Printf("Get%sPortraitCacheByStep %s step:%s Unmarshal [e] %v \n", doType, buyer, flag, err)
-	}
-	if flag == "" || flag == "a" { //仅当查询画像全部 或第一部分画像时 开始查询画像
-		go Qyhx_search_prior(hxObj, 1)
-	}
-	return nil
-}
+//
+////GetPortraitCacheByStep 采购单位画像分阶段查询
+//func GetPortraitCacheByStep(screen *PortraitScreen, flag string) map[string]interface{} {
+//	hxObj := getInitPortraitSearch(buyer, doType)
+//	if rBytes, err := redis.GetBytes("other", hxObj.RedisKey); err == nil && len(*rBytes) != 0 {
+//		data := map[string]interface{}{}
+//		err := json.Unmarshal(*rBytes, &data)
+//		if err == nil {
+//			if _, ok := data[fmt.Sprintf("step_%s", qutil.If(flag == "", "c", flag))]; ok { //传入空时 需要全部数据,必须等到所有值都用时才返回
+//				log.Printf("%s分段请求%s 返回内容", screen.Ent, flag)
+//				return data
+//			}
+//		}
+//		log.Printf("Get%sPortraitCacheByStep %s step:%s Unmarshal [e] %v \n", flag, screen.Ent, flag, err)
+//	}
+//	if flag == "" || flag == "a" { //仅当查询画像全部 或第一部分画像时 开始查询画像
+//		go Qyhx_search_prior(hxObj, 1)
+//	}
+//	return nil
+//}

+ 0 - 224
src/jfw/modules/bigmember/src/entity/portrait_project.go

@@ -1,224 +0,0 @@
-package entity
-
-import (
-	"encoding/json"
-	"fmt"
-	"log"
-	qutil "qfw/util"
-	"qfw/util/elastic"
-	"strings"
-	"time"
-	"util"
-)
-
-//PortraitWinnerProject 中标企业画像中标信息查询
-type PortraitWinnerProject struct {
-	EntId     string //企业id
-	Match     string //检索词
-	MatchType string //匹配方式
-	Area      string //省份
-	InfoType  string //信息类型
-	PushTime  string //信息发布时间
-	PageNum   int    //页码
-	PageSize  int    //每页数量
-}
-
-const (
-	matchWordLenLimit         = 50
-	elasticIndex, elasticType = "bidding", "bidding"
-	multi_match               = `{"multi_match": {"query": "%s","type": "phrase", "fields": [%s]}}`
-	NewBiddingSearch          = `{"query":{"bool":{"must":[%s]}}%s}`
-	ListSearchLimit           = `,"_source":["_id","projectname","bidamount","title","publishtime","subtype","toptype","area"],"sort":[{"publishtime":{"order":"desc"}}],"from":%d,"size":%d`
-
-	newBiddingSearchShowSql = `{"query":{"filtered":{"filter":{"bool":{"must":[{"term":{"entidlist":"%s"}},{"range":{"publishtime":{"gte":"%d"}}}]}}}},"aggs":{"group_area":{"terms":{"field":"area","size":40}},"group_subtype":{"terms":{"field":"subtype","size":20}},"group_pushtime":{"range":{"field":"publishtime","ranges":[%s]}}}}`
-)
-
-// GetProjectSelectItems 获取可筛选列
-// 地区:省份
-// 信息类型
-// 信息发布时间:7天内 最近30天 1年内 3年内 5年内
-func (pwp *PortraitWinnerProject) GetProjectSelectItems() (map[string]interface{}, error) {
-	defer qutil.Catch()
-	doSearchSql := fmt.Sprintf(newBiddingSearchShowSql, pwp.EntId, time.Now().AddDate(-5, 0, 0).Unix(), getTimeRange())
-	//log.Println("GetProjectSelectItems doSearchSql", doSearchSql)
-	res, _ := GetAggs(elasticIndex, elasticType, doSearchSql)
-	if res == nil {
-		return nil, fmt.Errorf("此企业无信息或获取信息列表检索条件出错")
-	}
-	//地区
-	var areaArr []string
-	if g, ok := res.Children("group_area"); ok {
-		var sbn []SimpleStringKeyValue
-		bs, _ := g.Aggregations["buckets"].MarshalJSON()
-		if json.Unmarshal(bs, &sbn) == nil && len(sbn) > 0 {
-			for _, bk := range sbn {
-				areaArr = append(areaArr, bk.Key)
-			}
-		}
-	}
-	//信息类型
-	var infoType []string
-	if g, ok := res.Children("group_subtype"); ok {
-		var sbn []SimpleStringKeyValue
-		bs, _ := g.Aggregations["buckets"].MarshalJSON()
-		if json.Unmarshal(bs, &sbn) == nil && len(sbn) > 0 {
-			for _, bk := range sbn {
-				infoType = append(infoType, bk.Key)
-			}
-		}
-	}
-	//时间
-	var timeRange []string
-	if g, ok := res.Children("group_pushtime"); ok {
-		var sbn []SimpleStringKeyValue
-		bs, _ := g.Aggregations["buckets"].MarshalJSON()
-		if json.Unmarshal(bs, &sbn) == nil && len(sbn) > 0 {
-			for _, bk := range sbn {
-				timeRange = append(timeRange, bk.Key)
-			}
-		}
-	}
-	return map[string]interface{}{"areaArr": areaArr, "infoType": infoType, "timeRange": timeRange}, nil
-}
-
-func getTimeRange() string {
-	now := time.Now()
-	return fmt.Sprintf(`{"key":"7day","from":%d},{"key":"30day","from":%d},{"key":"1year","from":%d},{"key":"3year","from":%d},{"key":"5year","from":%d}`,
-		now.AddDate(0, 0, -7).Unix(), now.AddDate(0, 0, -30).Unix(), now.AddDate(-1, 0, 0).Unix(), now.AddDate(-3, 0, 0).Unix(), now.AddDate(-5, 0, 0).Unix())
-}
-
-// GetList 获取中标信息列表
-// 超级订阅50条,大会员5年内
-func (pwp *PortraitWinnerProject) GetList() (list []map[string]interface{}, total int64, err error) {
-	mustQueryArr := []string{}
-	if pwp.EntId == "" {
-		err = fmt.Errorf("企业名称异常")
-		return
-	}
-	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"entidlist":"%s"}}`, pwp.EntId))
-	//文本输入框,字数限制50个字,超过上限不再允许输入内容
-	if pwp.Match != "" {
-		if pareWord := pwp.pareMatchWord(); pareWord != "" {
-			findFields := fmt.Sprintf(`"%s"`, strings.Join(pwp.pareMatchType(), "\",\""))
-			mustQueryArr = append(mustQueryArr, fmt.Sprintf(multi_match, pareWord, findFields))
-		}
-	}
-	//超级订阅50条,大会员5年内,选项:7天内、30天内、1年内、3年内、5年内(初始值)
-	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"publishtime":{"gte":"%d"}}}`, pwp.pareTimeSelect()))
-
-	//地区多选,选项:全部(初始值)、该企业项目动态下存在的项目地区(省、直辖市)
-	if pwp.Area != "" {
-		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"area":["%s"]}}`, strings.ReplaceAll(pwp.Area, ",", "\",\"")))
-	}
-
-	//信息类型多选,选项:全部(初始值)、该企业项目动态下存在的信息类型,例如该企业有招标公告招标和邀标的动态,则展示全部、招标公告(全部、招标、邀标)
-	if pwp.InfoType != "" {
-		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"subtype":["%s"]}}`, strings.ReplaceAll(pwp.InfoType, ",", "\",\"")))
-	}
-
-	pwp.PageNum = qutil.If(pwp.PageNum == 0, 1, pwp.PageNum).(int)     //默认第一页
-	pwp.PageSize = qutil.If(pwp.PageSize == 0, 10, pwp.PageSize).(int) //默认每页10条
-	//仅第一页查询总量
-	if pwp.PageNum == 1 {
-		total = elastic.Count(elasticIndex, elasticType, fmt.Sprintf(NewBiddingSearch, strings.Join(mustQueryArr, ","), ""))
-		if total <= 0 {
-			log.Println(fmt.Sprintf(NewBiddingSearch, strings.Join(mustQueryArr, ","), ""))
-			return
-		}
-	} else {
-		total = -1
-	}
-	start, limit := (pwp.PageNum-1)*pwp.PageSize, pwp.PageSize
-	//列表查询
-	listQuery := fmt.Sprintf(NewBiddingSearch, strings.Join(mustQueryArr, ","), fmt.Sprintf(ListSearchLimit, start, limit))
-	log.Printf("PortraitWinnerProject GetList Sql %s\n", listQuery)
-	newData := elastic.Get(elasticIndex, elasticType, listQuery)
-
-	if newData == nil || len(*newData) == 0 {
-		return
-	}
-	for k, rowData := range *newData {
-		if rowData["subtype"] != nil {
-			(*newData)[k]["bidstatus"] = rowData["subtype"]
-		} else if rowData["toptype"] != nil {
-			(*newData)[k]["bidstatus"] = rowData["toptype"]
-		}
-		delete((*newData)[k], "subtype")
-		delete((*newData)[k], "toptype")
-
-		if rowData["_id"] != nil {
-			(*newData)[k]["id"] = qutil.CommonEncodeArticle("content", rowData["_id"].(string))
-			delete((*newData)[k], "_id")
-		}
-		title := qutil.ObjToString(rowData["title"])
-		if title == "" {
-			title = qutil.ObjToString(rowData["projectname"])
-		}
-		(*newData)[k]["title"] = util.ClearHtml.ReplaceAllString(title, "")
-
-		delete((*newData)[k], "projectname")
-
-		if rowData["publishtime"] != nil {
-			(*newData)[k]["firsttime"] = rowData["publishtime"]
-			delete((*newData)[k], "publishtime")
-		}
-	}
-	list = *newData
-	return
-}
-
-//pareMatchWord 格式文本输入框,字数限制50个字,超过上限不再允许输入内容
-func (pwp *PortraitWinnerProject) pareMatchWord() string {
-	allWord := []rune(pwp.Match)
-	if len(allWord) <= matchWordLenLimit {
-		return pwp.Match
-	}
-	return string(allWord[:matchWordLenLimit])
-}
-
-//PareMatchType 格式筛选搜索,默认筛选为标题和正文
-func (pwp *PortraitWinnerProject) pareMatchType() (items []string) {
-	for _, t := range strings.Split(pwp.MatchType, ",") {
-		if t == "title" {
-			items = append(items, "title")
-		} else if t == "content" {
-			items = append(items, "detail")
-		} else if t == "buyer" {
-			items = append(items, "mbuyer")
-		} else if t == "winner" {
-			items = append(items, "mwinner")
-		} else if t == "agency" {
-			items = append(items, "magency")
-		} else if t == "file" {
-			items = append(items, "filetext")
-		} else if t == "purchasing" {
-			items = append(items, []string{"purchasing", "projectname.pname"}...)
-		}
-	}
-	if len(items) == 0 { //默认查询标题和正文
-		items = append(items, []string{"title", "detail"}...)
-	}
-	return
-}
-
-//PareMatchType 格式筛选时间,默认5年
-func (pwp *PortraitWinnerProject) pareTimeSelect() int64 {
-	switch pwp.PushTime {
-	case "7day":
-		return time.Now().AddDate(0, 0, -7).Unix()
-	case "30day":
-		return time.Now().AddDate(0, 0, -30).Unix()
-	case "1year":
-		return time.Now().AddDate(-1, 0, 0).Unix()
-	case "3year":
-		return time.Now().AddDate(-3, 0, 0).Unix()
-	default:
-		return time.Now().AddDate(-5, 0, 0).Unix()
-	}
-}
-
-//GetWinnerNewProjectCount 企业中标-中标动态数量(近五年)
-func GetWinnerNewProjectCount(entId string) int64 {
-	defer qutil.Catch()
-	return elastic.Count(elasticIndex, elasticType, fmt.Sprintf(`{"query":{"bool":{"must":[{"term": {"entidlist": "%s"}},{"range":{"publishtime":{"gte":%d}}}]}}}`, entId, time.Now().AddDate(-5, 0, 0).Unix()))
-}

+ 340 - 0
src/jfw/modules/bigmember/src/entity/portrait_screen.go

@@ -0,0 +1,340 @@
+package entity
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	qutil "qfw/util"
+	"qfw/util/elastic"
+	"strings"
+	"time"
+	"util"
+)
+
+const (
+	matchWordLenLimit         = 50
+	biddingIndex, biddingType = "bidding", "bidding"
+	projectIndex, projectType = "projectset", "projectset"
+	multi_match               = `{"multi_match": {"query": "%s","type": "phrase", "fields": [%s]}}`
+	must_match                = `{"bool":{"must":[%s]}}`
+	should_match              = `{"bool":{"should":[%s],"minimum_should_match": 1}}`
+	NewMustSearch             = `{"query":{"bool":{"must":[%s]}}%s}`
+	ListSearchLimit           = `,"_source":[%s],"sort":[{"%s":{"order":"desc"}}],"from":%d,"size":%d`
+
+	newBiddingSearchShowSql = `{"query":{"filtered":{"filter":{"bool":{"must":[%s,{"range":{"firsttime":{"gte":"%d"}}}]}}}},"aggs":{"group_area":{"terms":{"field":"area","size":40}},"group_scopeArr":{"terms":{"field":"subscopeclass","size":20}}}}`
+)
+
+//PortraitScreen 画像筛选
+type PortraitScreen struct {
+	Ent        string //企业id
+	Match      string //检索词 50个字符
+	MatchRange string //搜索范围 项目名称/项目标的物、招标代理机构、采购单位、中标单位
+	ExactMatch bool   //匹配方式 true精确匹配、false模糊匹配
+	Area       string //省份
+	ScopeClass string //行业
+	TimeRange  string //信息发布时间 以年为单位,逗号分隔、结束时间不得超过当前时间
+	HasPower   bool   //是否有相应权限
+}
+
+//PortraitProjectScreen 动态翻页
+type PortraitProjectScreen struct {
+	Screen   *PortraitScreen
+	PageNum  int //页码
+	PageSize int //每页数量
+}
+
+//IsEmptySearch 是否是空搜索
+func (pwp *PortraitScreen) IsEmptySearch() bool {
+	if pwp.Match != "" {
+		return false
+	}
+	if pwp.Area != "" || pwp.ScopeClass != "" || pwp.TimeRange != "" {
+		return false
+	}
+	return true
+}
+
+//PareMatchWord 格式文本输入框,字数限制50个字,超过上限不再允许输入内容
+func (pwp *PortraitScreen) PareMatchWord() string {
+	allWord := []rune(pwp.Match)
+	if len(allWord) <= matchWordLenLimit {
+		return pwp.Match
+	}
+	return string(allWord[:matchWordLenLimit])
+}
+
+//PareMatchType 格式筛选搜索,默认筛选为标题和正文
+func (ps *PortraitScreen) PareMatchType() (items []string) {
+	for _, t := range strings.Split(ps.MatchRange, ",") {
+		if t == "buyer" {
+			items = append(items, "mbuyer")
+		} else if t == "winner" {
+			items = append(items, "mwinner")
+		} else if t == "agency" {
+			items = append(items, "magency")
+		} else if t == "purchasing" {
+			items = append(items, []string{"purchasing", "projectname.pname"}...)
+		}
+	}
+	if len(items) == 0 { //默认查询项目名称和标的物
+		items = append(items, []string{"purchasing", "projectname.pname"}...)
+	}
+	return
+}
+
+//PareTimeSelect 格式筛选时间,默认2年
+func (ps *PortraitScreen) PareTimeSelect(checkPower bool) (st, et time.Time) {
+	now := time.Now()
+	sYear := now.Year() - 4
+	eYear := now.Year()
+	//需要校验权限时 无权限默认查询两年
+	if yearArr := strings.Split(ps.TimeRange, "_"); (!checkPower || ps.HasPower) && len(yearArr) == 2 {
+		if tYear := qutil.IntAll(yearArr[0]); tYear > sYear { //选择开始时间不得早于4年
+			sYear = tYear
+		}
+		if tYear := qutil.IntAll(yearArr[1]); tYear < eYear { //选择结束时间不得晚于现在年份
+			eYear = tYear
+		}
+	} else { //默认两年
+		sYear = now.Year() - 2
+	}
+	//返回默认时间
+	sTimeStamp := time.Date(sYear, 1, 1, 0, 0, 0, 0, time.Local)
+	eTimeStamp := time.Date(eYear+1, 1, 1, 0, 0, -1, 0, time.Local)
+	if eYear == now.Year() {
+		eTimeStamp = time.Date(eYear, now.Month(), now.Day(), now.Hour(), now.Minute(), 0, 0, time.Local)
+	}
+	return sTimeStamp, eTimeStamp
+}
+
+//GetProjectSelectItems 查询企业 项目所在地和行业
+func (ps *PortraitScreen) GetProjectSelectItems(isWinner bool) (map[string]interface{}, error) {
+	defer qutil.Catch()
+	entMatch := ``
+	if isWinner {
+		entMatch = fmt.Sprintf(`{"term":{"entidlist":"%s"}}`, ps.Ent)
+	} else {
+		entMatch = fmt.Sprintf(`{"term":{"buyer":"%s"}}`, ps.Ent)
+	}
+	doSearchSql := fmt.Sprintf(newBiddingSearchShowSql, entMatch, time.Date(time.Now().Year()-4, 1, 1, 0, 0, 0, 0, time.Local).Unix())
+	//log.Println("GetProjectSelectItems doSearchSql", doSearchSql)
+	res, _ := GetAggs(projectIndex, projectType, doSearchSql)
+	if res == nil {
+		return nil, fmt.Errorf("此企业无信息或获取信息列表检索条件出错")
+	}
+	//地区
+	var areaArr []string
+	if g, ok := res.Children("group_area"); ok {
+		var sbn []SimpleStringKeyValue
+		bs, _ := g.Aggregations["buckets"].MarshalJSON()
+		if json.Unmarshal(bs, &sbn) == nil && len(sbn) > 0 {
+			for _, bk := range sbn {
+				areaArr = append(areaArr, bk.Key)
+			}
+		}
+	}
+	//行业类型
+	var scopeArr []string
+	if g, ok := res.Children("group_scopeArr"); ok {
+		var sbn []SimpleStringKeyValue
+		bs, _ := g.Aggregations["buckets"].MarshalJSON()
+		if json.Unmarshal(bs, &sbn) == nil && len(sbn) > 0 {
+			for _, bk := range sbn {
+				scopeArr = append(scopeArr, bk.Key)
+			}
+		}
+	}
+	return map[string]interface{}{"areaArr": areaArr, "scopeArr": scopeArr}, nil
+}
+
+// GetWinnerList 获取企业画像中标信息数据
+// 超级订阅50条,大会员5年内
+func (pwp *PortraitProjectScreen) GetWinnerList() (list []map[string]interface{}, total int64, err error) {
+	mustQueryArr := []string{}
+	if pwp.Screen.Ent == "" {
+		err = fmt.Errorf("企业名称异常")
+		return
+	}
+	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"entidlist":"%s"}}`, pwp.Screen.Ent))
+	//文本输入框,字数限制50个字,超过上限不再允许输入内容
+	if pwp.Screen.Match != "" {
+		if pareWord := pwp.Screen.PareMatchWord(); pareWord != "" {
+			findFields := fmt.Sprintf(`"%s"`, strings.Join(pwp.Screen.PareMatchType(), "\",\""))
+			var keywordArr []string
+			for _, keyword := range strings.Split(pareWord, " ") {
+				if keyword == "" {
+					continue
+				}
+				keywordArr = append(keywordArr, fmt.Sprintf(multi_match, keyword, findFields))
+			}
+			if pwp.Screen.ExactMatch { //精确匹配(必须包含每个关键词)
+				mustQueryArr = append(mustQueryArr, fmt.Sprintf(must_match, strings.Join(keywordArr, ",")))
+			} else { //模糊匹配(只需包含一个关键词)
+				mustQueryArr = append(mustQueryArr, fmt.Sprintf(should_match, strings.Join(keywordArr, ",")))
+			}
+		}
+	}
+	//按照当前年份,往前推4年,共5个年份可选
+	sTime, eTime := pwp.Screen.PareTimeSelect(true)
+	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"publishtime":{"gte":"%d","lte":"%d"}}}`, sTime.Unix(), eTime.Unix()))
+
+	//地区多选,选项:全部(初始值)、项目地区(省、直辖市)
+	if pwp.Screen.Area != "" {
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"area":["%s"]}}`, strings.ReplaceAll(pwp.Screen.Area, ",", "\",\"")))
+	}
+
+	//行业多选
+	if pwp.Screen.ScopeClass != "" {
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"s_subscopeclass":["%s"]}}`, strings.ReplaceAll(pwp.Screen.ScopeClass, ",", "\",\"")))
+	}
+
+	pwp.PageNum = qutil.If(pwp.PageNum == 0, 1, pwp.PageNum).(int)     //默认第一页
+	pwp.PageSize = qutil.If(pwp.PageSize == 0, 10, pwp.PageSize).(int) //默认每页10条
+	//仅第一页查询总量
+	if pwp.PageNum == 1 {
+		total = elastic.Count(biddingIndex, biddingType, fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), ""))
+		if total <= 0 {
+			log.Println(fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), ""))
+			return
+		}
+	} else {
+		total = -1
+	}
+	start, limit := (pwp.PageNum-1)*pwp.PageSize, pwp.PageSize
+	//列表查询
+	listQuery := fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), fmt.Sprintf(ListSearchLimit, `"_id","projectname","bidamount","title","publishtime","subtype","toptype","area"`, "publishtime", start, limit))
+	//log.Printf("PortraitWinnerProject GetList Sql %s\n", listQuery)
+	newData := elastic.Get(biddingIndex, biddingType, listQuery)
+
+	if newData == nil || len(*newData) == 0 {
+		return
+	}
+	for k, rowData := range *newData {
+		if rowData["subtype"] != nil {
+			(*newData)[k]["bidstatus"] = rowData["subtype"]
+		} else if rowData["toptype"] != nil {
+			(*newData)[k]["bidstatus"] = rowData["toptype"]
+		}
+		delete((*newData)[k], "subtype")
+		delete((*newData)[k], "toptype")
+
+		if rowData["_id"] != nil {
+			(*newData)[k]["id"] = qutil.CommonEncodeArticle("content", rowData["_id"].(string))
+			delete((*newData)[k], "_id")
+		}
+		title := qutil.ObjToString(rowData["title"])
+		if title == "" {
+			title = qutil.ObjToString(rowData["projectname"])
+		}
+		(*newData)[k]["title"] = util.ClearHtml.ReplaceAllString(title, "")
+
+		delete((*newData)[k], "projectname")
+
+		if rowData["publishtime"] != nil {
+			(*newData)[k]["firsttime"] = rowData["publishtime"]
+			delete((*newData)[k], "publishtime")
+		}
+	}
+	list = *newData
+	return
+}
+
+//GetWinnerNewProjectCount 企业中标-中标动态数量(近五年)
+func GetWinnerNewProjectCount(entId string) int64 {
+	defer qutil.Catch()
+	return elastic.Count(biddingIndex, biddingType, fmt.Sprintf(`{"query":{"bool":{"must":[{"term": {"entidlist": "%s"}},{"range":{"publishtime":{"gte":%d}}}]}}}`, entId, time.Now().AddDate(-5, 0, 0).Unix()))
+}
+
+//GetBuyerList 获取采购单位采购信息数据
+func (pwp *PortraitProjectScreen) GetBuyerList() (list []map[string]interface{}, total int64, err error) {
+	mustQueryArr := []string{}
+	if pwp.Screen.Ent == "" {
+		err = fmt.Errorf("企业名称异常")
+		return
+	}
+
+	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"buyer":"%s"}}`, pwp.Screen.Ent))
+
+	sTime, eTime := pwp.Screen.PareTimeSelect(false)
+	mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"firsttime":{"gte":"%d","lte":"%d"}}}`, sTime.Unix(), eTime.Unix()))
+
+	//文本输入框,字数限制50个字,超过上限不再允许输入内容
+	if pwp.Screen.Match != "" {
+		if pareWord := pwp.Screen.PareMatchWord(); pareWord != "" {
+			findFields := fmt.Sprintf(`"%s"`, strings.Join(pwp.Screen.PareMatchType(), "\",\""))
+			var keywordArr []string
+			for _, keyword := range strings.Split(pareWord, " ") {
+				if keyword == "" {
+					continue
+				}
+				keywordArr = append(keywordArr, fmt.Sprintf(multi_match, keyword, findFields))
+			}
+			if pwp.Screen.ExactMatch { //精确匹配(必须包含每个关键词)
+				mustQueryArr = append(mustQueryArr, fmt.Sprintf(must_match, strings.Join(keywordArr, ",")))
+			} else { //模糊匹配(只需包含一个关键词)
+				mustQueryArr = append(mustQueryArr, fmt.Sprintf(should_match, strings.Join(keywordArr, ",")))
+			}
+		}
+	}
+
+	//地区多选,选项:全部(初始值)、项目地区(省、直辖市)
+	if pwp.Screen.Area != "" {
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"area":["%s"]}}`, strings.ReplaceAll(pwp.Screen.Area, ",", "\",\"")))
+	}
+
+	//行业多选
+	if pwp.Screen.ScopeClass != "" {
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"terms":{"s_subscopeclass":["%s"]}}`, strings.ReplaceAll(pwp.Screen.ScopeClass, ",", "\",\"")))
+	}
+
+	if pwp.Screen.HasPower {
+		pwp.PageNum = qutil.If(pwp.PageNum == 0, 1, pwp.PageNum).(int)     //默认第一页
+		pwp.PageSize = qutil.If(pwp.PageSize == 0, 10, pwp.PageSize).(int) //默认每页10条
+	} else { //免费用户可以查看三条
+		pwp.PageNum = 1
+		pwp.PageSize = 3
+	}
+
+	//仅第一页查询总量
+	if pwp.PageNum == 1 {
+		total = elastic.Count(projectIndex, projectIndex, fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), ""))
+		if total <= 0 {
+			//log.Println(fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), ""))
+			return
+		}
+	} else {
+		total = -1
+	}
+	start, limit := (pwp.PageNum-1)*pwp.PageSize, pwp.PageSize
+
+	//列表查询
+	listQuery := fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), fmt.Sprintf(ListSearchLimit, `"bidstatus","list.infoid","list.title","list.subtype","projectname","list.area","firsttime","area"`, "firsttime", start, limit))
+	//log.Printf("PortraitWinnerProject GetList Sql %s\n", listQuery)
+	newData := elastic.Get(projectIndex, projectType, listQuery)
+
+	if newData == nil || len(*newData) == 0 {
+		return
+	}
+
+	for k, rowData := range *newData {
+		vs, _ := rowData["list"].([]interface{})
+		if len(vs) > 0 {
+			last := vs[len(vs)-1]
+			lastObj, _ := last.(map[string]interface{})
+			if lastObj != nil {
+				if lastObj["infoid"] != nil {
+					(*newData)[k]["id"] = qutil.CommonEncodeArticle("content", lastObj["infoid"].(string))
+				}
+				title := qutil.ObjToString(qutil.ObjToString(lastObj["title"]))
+				if title == "" {
+					title = qutil.ObjToString(lastObj["projectname"])
+				}
+				(*newData)[k]["title"] = util.ClearHtml.ReplaceAllString(title, "")
+			}
+		}
+		delete((*newData)[k], "list")
+		delete((*newData)[k], "projectname")
+	}
+	list = *newData
+	return
+}

+ 37 - 59
src/jfw/modules/bigmember/src/service/analysis/analysis.go

@@ -10,7 +10,6 @@ import (
 	"regexp"
 	"strconv"
 	"strings"
-	"sync"
 	"time"
 	"util"
 
@@ -19,75 +18,54 @@ import (
 
 type Analysis struct {
 	*xweb.Action
-	pName        xweb.Mapper `xweb:"/analysis/projectName"`  //根据项目名称关键词连带项目名称
-	pInfo        xweb.Mapper `xweb:"/analysis/projectInfo"`  //根据项目名称获取项目信息
-	csORRsList   xweb.Mapper `xweb:"/potential/corList"`     //潜在客户customers or 潜在竞争对手rivals
-	rMyRivals    xweb.Mapper `xweb:"/potential/rMyRivals"`   //移除我的潜在竞争对手rivals
-	decInfo      xweb.Mapper `xweb:"/decision/decInfo"`      //投标决策分析
-	trialInfo    xweb.Mapper `xweb:"/decision/trialInfo"`    //投标决策分析-使用用户 剩余次数
-	forPList     xweb.Mapper `xweb:"/forecast/forPList"`     //新项目预测结果list
-	forPContent  xweb.Mapper `xweb:"/forecast/forPContent"`  //新项目预测结果详情
-	fWData       xweb.Mapper `xweb:"/forecast/forWData"`     //中标预测分析
-	fWStatus     xweb.Mapper `xweb:"/forecast/forWStatus"`   //查看中标预测状态
-	fWResult     xweb.Mapper `xweb:"/forecast/forWResult"`   //中标预测结果
-	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 首页接口
+	pName           xweb.Mapper `xweb:"/analysis/projectName"`     //根据项目名称关键词连带项目名称
+	pInfo           xweb.Mapper `xweb:"/analysis/projectInfo"`     //根据项目名称获取项目信息
+	csORRsList      xweb.Mapper `xweb:"/potential/corList"`        //潜在客户customers or 潜在竞争对手rivals
+	rMyRivals       xweb.Mapper `xweb:"/potential/rMyRivals"`      //移除我的潜在竞争对手rivals
+	decInfo         xweb.Mapper `xweb:"/decision/decInfo"`         //投标决策分析
+	trialInfo       xweb.Mapper `xweb:"/decision/trialInfo"`       //投标决策分析-使用用户 剩余次数
+	forPList        xweb.Mapper `xweb:"/forecast/forPList"`        //新项目预测结果list
+	forPContent     xweb.Mapper `xweb:"/forecast/forPContent"`     //新项目预测结果详情
+	fWData          xweb.Mapper `xweb:"/forecast/forWData"`        //中标预测分析
+	fWStatus        xweb.Mapper `xweb:"/forecast/forWStatus"`      //查看中标预测状态
+	fWResult        xweb.Mapper `xweb:"/forecast/forWResult"`      //中标预测结果
+	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 首页接口
+	projectInfoByBW xweb.Mapper `xweb:"/decision/projectInfoByBW"` //投标决策分析-采购单位和中标企业 其他项目明细/类似项目明细
+
 }
 
 const (
-	C_FW_qyxy           = "qyxy_std"              //中标预测-企业信息
-	C_FPContent         = "project_forecast"      //新项目预测表
-	C_FPList            = "pushprojectforecast"   //新项目预测
-	FP_Limit            = 10                      //每页10条
-	C_ForecastData      = "forecast_info"         //中标预测数据
-	C_ForecastLog       = "forecast_log"          //中标预测日志
-	C_PTLog             = "potential_search"      //潜在竞争对手或客户日志表
-	C_FEnt              = "follow_entinfo_bigvip" //企业情报
-	C_Member            = "member"
-	C_User              = "user"
-	P_INDEX             = "projectset"
-	P_TYPE              = "projectset"
-	PSearch_PCount      = 500 //潜在客户和潜在竞争对手数量
-	PSearch_field       = `buyer`
-	P_limit             = 2000                   //查询两千个客户
-	P_redis_time        = 15 * 24 * 60 * 60      //redis存15天
-	PSearch_DecSimCount = 100                    //决策分析类似项目明细数据量
-	PSearch_DecSort     = `{"firsttime":"desc"}` //决策分析类似项目明细排序
-	PSearch_DecField    = `"projectname","_id","buyer","firsttime","area","city","s_winner","review_experts","budget","bidamount","project_rate","bidtype","ids","winnerorder","bidtype","bidcycle"`
-	PSearch_DecMust     = `"bidstatus": ["中标","成交","合同"]`
-	METHOD              = "POST"
+	C_FW_qyxy      = "qyxy_std"              //中标预测-企业信息
+	C_FPContent    = "project_forecast"      //新项目预测表
+	C_FPList       = "pushprojectforecast"   //新项目预测
+	FP_Limit       = 10                      //每页10条
+	C_ForecastData = "forecast_info"         //中标预测数据
+	C_ForecastLog  = "forecast_log"          //中标预测日志
+	C_PTLog        = "potential_search"      //潜在竞争对手或客户日志表
+	C_FEnt         = "follow_entinfo_bigvip" //企业情报
+	C_Member       = "member"
+	C_User         = "user"
+	P_INDEX        = "projectset"
+	P_TYPE         = "projectset"
+	PSearch_PCount = 500 //潜在客户和潜在竞争对手数量
+	PSearch_field  = `buyer`
+	P_limit        = 2000              //查询两千个客户
+	P_redis_time   = 15 * 24 * 60 * 60 //redis存15天
+	METHOD         = "POST"
 )
 
-var P_Starttime = "1514736000" //2018.01.01
-
-var RegWinner = regexp.MustCompile(".+[司院厂所心处普]$")
-
-type UserInfoLock struct {
-	sync.Mutex
-	decLock  map[string]*sync.Mutex
-	forWLock map[string]*sync.Mutex
-}
-
-var UIL *UserInfoLock
-
 //
 func init() {
 	now := time.Now()
 	newDate := time.Date(now.Year()-Config.TimeSpan, 1, 1, 0, 0, 0, 0, time.Local).Unix()
-	P_Starttime = strconv.FormatInt(newDate, 10)
+	entity.P_Starttime = strconv.FormatInt(newDate, 10)
 	if Config.RegWinner != "" {
-		RegWinner = regexp.MustCompile(Config.RegWinner)
-	}
-	UIL = NewUserInfoLock()
-}
-
-func NewUserInfoLock() *UserInfoLock {
-	return &UserInfoLock{
-		decLock:  make(map[string]*sync.Mutex),
-		forWLock: make(map[string]*sync.Mutex),
+		entity.RegWinner = regexp.MustCompile(Config.RegWinner)
 	}
+	entity.UIL = entity.NewUserInfoLock()
 }
 
 //根据项目名称获取项目信息

+ 54 - 19
src/jfw/modules/bigmember/src/service/analysis/decision.go

@@ -10,7 +10,6 @@ import (
 	"log"
 	qutil "qfw/util"
 	"qfw/util/jy"
-	"regexp"
 	"sort"
 	"strconv"
 	"strings"
@@ -42,9 +41,36 @@ type ViewKeyWord struct {
 	MatchWay int      `json:"matchway"`  //匹配模式
 }
 
-var regExperts = regexp.MustCompile("^[\\p{Han}]{2,4}$")
+//投标决策分析id
+var ServiceId = 6
 
-// var decisionLock = map[string]*sync.Mutex{}
+//采购单位和中标企业 其他项目明细/类似项目明细
+func (this *Analysis) ProjectInfoByBW() {
+	userId, _ := this.GetSession("userId").(string)
+	defer qutil.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}
+		}
+		EAD := entity.AnalysisDec{}
+		//接收参数
+		json.Unmarshal(this.Body(), &EAD)
+		if EAD.Sid == "" || EAD.Pname == "" || len(EAD.BuyerContent) == 0 {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		//是否是大会员用户
+		if EAD.UserId, EAD.IsPower = entity.CheckPower(userId); !EAD.IsPower {
+			return Result{Data: nil, Error_msg: Error_msg_1004}
+		}
+		EAD.ServiceId = ServiceId
+		EAD.UserLock = *entity.ThisLock(EAD.UserId)
+		return Result{Data: EAD.GetProjectInfoByBW()}
+	}()
+	this.ServeJson(r)
+}
 
 //试用用户分析
 func (this *Analysis) TrialInfo() {
@@ -109,13 +135,13 @@ func (this *Analysis) FreeDecInfo() {
 			userId, _ := this.GetSession("userId").(string)
 			var s_phone, _ = this.GetSession("s_phone").(string)
 			main_userId, phone, _ := util.MainUserId(userId, s_phone, 0)
-			UIL.Lock()
-			if UIL.decLock[main_userId] == nil {
-				UIL.decLock[main_userId] = &sync.Mutex{}
+			entity.UIL.Lock()
+			if entity.UIL.DecLock[main_userId] == nil {
+				entity.UIL.DecLock[main_userId] = &sync.Mutex{}
 			}
-			UIL.Unlock()
-			UIL.decLock[main_userId].Lock()
-			defer UIL.decLock[main_userId].Unlock()
+			entity.UIL.Unlock()
+			entity.UIL.DecLock[main_userId].Lock()
+			defer entity.UIL.DecLock[main_userId].Unlock()
 			if getRes.ServiceId == 0 {
 				getRes.ServiceId = 6
 			}
@@ -172,13 +198,13 @@ func (this *Analysis) DecInfo() {
 				regMap.Error_code = Error_code_1004
 				regMap.Error_msg = Error_msg_1004
 			} else {
-				UIL.Lock()
-				if UIL.decLock[main_userId] == nil {
-					UIL.decLock[main_userId] = &sync.Mutex{}
+				entity.UIL.Lock()
+				if entity.UIL.DecLock[main_userId] == nil {
+					entity.UIL.DecLock[main_userId] = &sync.Mutex{}
 				}
-				UIL.Unlock()
-				UIL.decLock[main_userId].Lock()
-				defer UIL.decLock[main_userId].Unlock()
+				entity.UIL.Unlock()
+				entity.UIL.DecLock[main_userId].Lock()
+				defer entity.UIL.DecLock[main_userId].Unlock()
 				if getRes.ServiceId == 0 {
 					getRes.ServiceId = 6
 				}
@@ -298,9 +324,11 @@ func getDecInfo(decQuery, buyer_buyerClass string, dec *DecParam) map[string]int
 	aggsArr["buyerHistroyList"] = buyerHistroyList
 	//聚合
 	aggs, res := GetAggs(P_INDEX, P_TYPE, decQuery)
+	log.Println("请求数据时间:", time.Since(t1))
 	if res != nil && len(res) > 0 {
 		res = Sequence(res)
 	}
+	log.Println("-请求数据时间-:", time.Since(t1))
 	if aggs != nil {
 		//标书编制周期
 		if bidcycle_ranges, ok := aggs.Children("bidcycle_ranges"); ok {
@@ -517,7 +545,7 @@ func getDecInfo(decQuery, buyer_buyerClass string, dec *DecParam) map[string]int
 					// log.Println(aggsMap)
 					var _aggsMap = []map[string]interface{}{}
 					for k, v := range aggsMap {
-						if !regExperts.MatchString(qutil.ObjToString(v["key"])) {
+						if !entity.RegExperts.MatchString(qutil.ObjToString(v["key"])) {
 							continue
 						}
 						_aggsMap = append(_aggsMap, aggsMap[k])
@@ -557,7 +585,7 @@ func getDecInfo(decQuery, buyer_buyerClass string, dec *DecParam) map[string]int
 				if len(aggsMap) > 0 {
 					var buckets = []*DecWinnerInfo{}
 					for _, v := range aggsMap {
-						if !RegWinner.MatchString(qutil.ObjToString(v["key"])) {
+						if !entity.RegWinner.MatchString(qutil.ObjToString(v["key"])) {
 							continue
 						}
 						//类似项目金额
@@ -566,6 +594,12 @@ func getDecInfo(decQuery, buyer_buyerClass string, dec *DecParam) map[string]int
 						if total_map["value"] != nil {
 							total_project = qutil.IntAll(total_map["value"])
 						}
+						//
+						var max_jytime_map = *qutil.ObjToMap(v["max_jytime"].(map[string]interface{}))
+						var max_jytime int64 = 0
+						if max_jytime_map["value"] != nil {
+							max_jytime = qutil.Int64All(max_jytime_map["value"])
+						}
 						//中标企业id
 						var group_entidlist = *qutil.ObjToMap(v["group_entidlist"].(map[string]interface{}))
 						var entId = ""
@@ -650,6 +684,7 @@ func getDecInfo(decQuery, buyer_buyerClass string, dec *DecParam) map[string]int
 							buyer_other_list,         //中标企业和采购单位其它项目合作历史
 							0,                        //中标企业注册资本
 							entId,                    //中标企业加密id
+							max_jytime,               //类似项目中标时间
 						})
 					}
 					//获取中标企业注资金信息
@@ -712,7 +747,7 @@ func Sequence(seqData []map[string]interface{}) []map[string]interface{} {
 			var s_winner = qutil.ObjToString(v["s_winner"])
 			var s_length = 0
 			for _, v := range strings.Split(s_winner, ",") {
-				if RegWinner.MatchString(v) {
+				if entity.RegWinner.MatchString(v) {
 					s_length += 1
 				}
 			}
@@ -724,7 +759,7 @@ func Sequence(seqData []map[string]interface{}) []map[string]interface{} {
 		review_experts := []string{}
 		if v["review_experts"] != nil {
 			for _, v := range qutil.ObjArrToStringArr(v["review_experts"].([]interface{})) {
-				if regExperts.MatchString(v) {
+				if entity.RegExperts.MatchString(v) {
 					review_experts = append(review_experts, v)
 				}
 			}

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

@@ -2,6 +2,7 @@ package analysis
 
 import (
 	"encoding/json"
+	"entity"
 	"fmt"
 	"log"
 	qutil "qfw/util"
@@ -56,7 +57,7 @@ var query_aggs_review_experts_count = `"all_review_experts":{"cardinality":{"fie
 func DecQuery(area map[string]interface{}, buyerClass []string, business_scope []ViewKeyWord, industry, buyer, buyer_buyerClass string, minPrice, maxPrice int) string {
 	//类似项目热点中标企业
 	var query_aggs_winners_aggs_buyer = `"group_projectname":{"terms":{"field":"buyer","size":3}},"this_buyer":{"filter":{"term":{"buyer":"%s"}},"aggs":{"total":{"sum":{"field":"sortprice"}},"my_top_hits":{"top_hits":{"size":20,"sort":{"jgtime":"desc"},"_source":["_id","jgtime"]}}}}`
-	var query_aggs_winners = `"group_winner":{"terms":{"field":"s_winner","size":10},"aggs":{"total":{"sum":{"field":"sortprice"}},"group_entidlist":{"terms":{"field":"entidlist","size":1}}%s}}`
+	var query_aggs_winners = `"group_winner":{"terms":{"field":"s_winner","size":10},"aggs":{"total":{"sum":{"field":"sortprice"}},"max_jytime": {"max": {"field": "jgtime"}},"group_entidlist":{"terms":{"field":"entidlist","size":1}}%s}}`
 
 	var query = `{"query":{"filtered":{"filter":{"bool":{"should":[%s],"must":[%s]}},"query":{"bool":{"should":[%s],"minimum_should_match":%d}}}},"_source":[%s],"sort":[%s],"from":0,"size":%d,"aggs":{%s}}`
 
@@ -67,9 +68,12 @@ func DecQuery(area map[string]interface{}, buyerClass []string, business_scope [
 	//类似项目预算
 	var query_aggs_budget = `"budget_ranges": {"range":{"field":"budget","ranges":[%s]},"aggs":{"count":{"cardinality":{"field":"id"}},"avg_rate":{"filter":{"range":{"project_rate":{"gte":0,"lte": 0.6}}},"aggs":{"avg_rate":{"avg":{"field":"project_rate"}},"sum_budget":{"sum":{"field":"budget"}},"sum_bidamount":{"sum":{"field":"bidamount"}}}}}}`
 
+	//基础查询
+	bools := []string{}
+	musts := []string{}
+	shoulds := []string{}
 	//聚合查询
 	query_aggs := ``
-
 	//标书周期
 	query_aggs_bidcycle = fmt.Sprintf(query_aggs_bidcycle, GetBidcycleDis())
 	//预算分布
@@ -87,10 +91,7 @@ func DecQuery(area map[string]interface{}, buyerClass []string, business_scope [
 		query_aggs = query_aggs + ","
 	}
 	query_aggs = query_aggs + fmt.Sprintf(query_aggs_winners, hotWinner)
-	//基础查询
-	bools := []string{}
-	musts := []string{}
-	shoulds := []string{}
+
 	//省份
 	areaCity := []string{}
 	citys := []string{}
@@ -132,6 +133,7 @@ func DecQuery(area map[string]interface{}, buyerClass []string, business_scope [
 	if len(areaCity) > 0 {
 		shoulds = append(shoulds, strings.Join(areaCity, ","))
 	}
+
 	//金额区间
 	if minPrice > 0 || maxPrice > 0 {
 		pricequery := `{"range":{"sortprice":{`
@@ -148,19 +150,19 @@ func DecQuery(area map[string]interface{}, buyerClass []string, business_scope [
 		musts = append(musts, pricequery)
 	}
 	//检索日期
-	if P_Starttime != "" {
+	if entity.P_Starttime != "" {
 		now := time.Now()
 		endtime := now.Unix()
 		timequery := `{"range":{"firsttime":{`
-		timequery += `"gte":` + P_Starttime
+		timequery += `"gte":` + entity.P_Starttime
 		timequery += `,`
 		timequery += `"lt":` + strconv.FormatInt(endtime, 10)
 		timequery += `}}}`
 		musts = append(musts, timequery)
 	}
 	//中标项目
-	if PSearch_DecMust != "" {
-		musts = append(musts, fmt.Sprintf(query_bool_must, PSearch_DecMust))
+	if entity.PSearch_DecMust != "" {
+		musts = append(musts, fmt.Sprintf(query_bool_must, entity.PSearch_DecMust))
 	}
 	//招标行业
 	if industry != "" {
@@ -221,7 +223,7 @@ func DecQuery(area map[string]interface{}, buyerClass []string, business_scope [
 			}
 		}
 	}
-	qstr := fmt.Sprintf(query, strings.Join(shoulds, ","), strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, PSearch_DecField, PSearch_DecSort, PSearch_DecSimCount, query_aggs)
+	qstr := fmt.Sprintf(query, strings.Join(shoulds, ","), strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, entity.PSearch_DecField, entity.PSearch_DecSort, entity.PSearch_DecSimCount, query_aggs)
 	log.Println("str:", qstr)
 	return qstr
 }
@@ -307,19 +309,19 @@ func DecQueryFree(area map[string]interface{}, buyerClass []string, business_sco
 		musts = append(musts, pricequery)
 	}
 	//检索日期
-	if P_Starttime != "" {
+	if entity.P_Starttime != "" {
 		now := time.Now()
 		endtime := now.Unix()
 		timequery := `{"range":{"firsttime":{`
-		timequery += `"gte":` + P_Starttime
+		timequery += `"gte":` + entity.P_Starttime
 		timequery += `,`
 		timequery += `"lt":` + strconv.FormatInt(endtime, 10)
 		timequery += `}}}`
 		musts = append(musts, timequery)
 	}
 	//中标项目
-	if PSearch_DecMust != "" {
-		musts = append(musts, fmt.Sprintf(query_bool_must, PSearch_DecMust))
+	if entity.PSearch_DecMust != "" {
+		musts = append(musts, fmt.Sprintf(query_bool_must, entity.PSearch_DecMust))
 	}
 	//招标行业
 	if industry != "" {
@@ -380,7 +382,7 @@ func DecQueryFree(area map[string]interface{}, buyerClass []string, business_sco
 			}
 		}
 	}
-	qstr := fmt.Sprintf(query, strings.Join(shoulds, ","), strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, "", PSearch_DecSort, 0, query_aggs)
+	qstr := fmt.Sprintf(query, strings.Join(shoulds, ","), strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, "", entity.PSearch_DecSort, 0, query_aggs)
 	// log.Println("str:", qstr)
 	return qstr
 }
@@ -434,11 +436,11 @@ func PCQuery(area map[string]interface{}, industry []string, buyerclass []string
 		musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(areaCity, ",")))
 	}
 	//检索日期
-	if P_Starttime != "" {
+	if entity.P_Starttime != "" {
 		now := time.Now()
 		endtime := now.Unix()
 		timequery := `{"range":{"firsttime":{`
-		timequery += `"gte":` + P_Starttime
+		timequery += `"gte":` + entity.P_Starttime
 		timequery += `,`
 		timequery += `"lt":` + strconv.FormatInt(endtime, 10)
 		timequery += `}}}`
@@ -525,7 +527,7 @@ func getQueryByEntName(entName string) string {
 				            {
 				              "range": {
 				                "firsttime": {
-				                  "gte": ` + P_Starttime + `,
+				                  "gte": ` + entity.P_Starttime + `,
 				                  "lt": ` + strconv.FormatInt(p_endtime, 10) + `
 				                }
 				              }
@@ -661,19 +663,19 @@ func GetListByBuyer(dec *DecParam) []map[string]interface{} {
 		musts = append(musts, pricequery)
 	}
 	//检索日期
-	if P_Starttime != "" {
+	if entity.P_Starttime != "" {
 		now := time.Now()
 		endtime := now.Unix()
 		timequery := `{"range":{"firsttime":{`
-		timequery += `"gte":` + P_Starttime
+		timequery += `"gte":` + entity.P_Starttime
 		timequery += `,`
 		timequery += `"lt":` + strconv.FormatInt(endtime, 10)
 		timequery += `}}}`
 		musts = append(musts, timequery)
 	}
 	//中标项目
-	if PSearch_DecMust != "" {
-		musts = append(musts, fmt.Sprintf(query_bool_must, PSearch_DecMust))
+	if entity.PSearch_DecMust != "" {
+		musts = append(musts, fmt.Sprintf(query_bool_must, entity.PSearch_DecMust))
 	}
 	//招标行业
 	if dec.Industry != "" {
@@ -734,7 +736,7 @@ func GetListByBuyer(dec *DecParam) []map[string]interface{} {
 			}
 		}
 	}
-	qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, PSearch_DecField, PSearch_DecSort, strconv.Itoa(PSearch_PCount))
+	qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, entity.PSearch_DecField, entity.PSearch_DecSort, strconv.Itoa(PSearch_PCount))
 	// log.Println("采购单位类似项目:", qstr)
 	return *elastic.Get("projectset", "projectset", qstr)
 
@@ -814,7 +816,7 @@ func GetBudgetDis() string {
 
 //查询此中标企业 和 此采购单位 所有合作的项目
 func GetAllBWQuery(winner, buyder string) string {
-	var query = `{"query":{"filtered":{"filter":{"bool":{"must":[{"term":{"buyer":"` + buyder + `"}},{"term":{"s_winner":"` + winner + `"}}]}}}},"_source":["_id","jgtime","sortprice"],"from":0,"size":50,"sort":[{"jgtime":"desc"}],"aggs":{"sum_project":{"sum":{"field":"sortprice"}}}}`
+	var query = `{"query":{"filtered":{"filter":{"bool":{"must":[{"term":{"buyer":"` + buyder + `"}},{"term":{"s_winner":"` + winner + `"}}]}}}},"_source":["_id","jgtime","sortprice"],"from":0,"size":100,"sort":[{"jgtime":"desc"}],"aggs":{"sum_project":{"sum":{"field":"sortprice"}}}}`
 	return query
 }
 

+ 387 - 14
src/jfw/modules/bigmember/src/service/analysis/forecastproject.go

@@ -4,13 +4,33 @@ package analysis
 import (
 	. "api"
 	"db"
+	"encoding/json"
+	"fmt"
+	"jfw/modules/common/src/qfw/util/jy"
 	"log"
 	qutil "qfw/util"
-	"qfw/util/jy"
+	dfa "qfw/util/dfa"
+	"qfw/util/elastic"
+
+	//"qfw/util/jy"
+	"sort"
+	"strconv"
 	"strings"
+	"time"
 	"util"
 )
 
+const (
+	INDEX          = "forecast"
+	TYPE           = "forecast"
+	bidSearch_sort = `{"yucetime":-1}`
+	findfields     = `"title"`
+
+	view_maxPageNum = 20
+	view_pageSize   = 50
+	bidSearch_field = ``
+)
+
 //预测详情页
 func (this *Analysis) ForPContent() {
 	defer qutil.Catch()
@@ -94,6 +114,35 @@ func (this *Analysis) ForPContent() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
+//预测详情页
+// func (this *Analysis) ForPContent() {
+// 	defer qutil.Catch()
+// 	userId, _ := this.GetSession("userId").(string)
+// 	rData, errMsg := func() (interface{}, error) {
+// 		id := this.GetString("id") //项目预测id
+// 		// keys := this.GetString("keys") //关键词
+// 		if id == "" { //}|| keys == "" {
+// 			return -1, nil
+// 		}
+// 		id = util.DecodeId(id)
+// 		data := elastic.GetById(INDEX, TYPE, id)
+// 		if len(*data) > 0 {
+// 			res := ForecastInfo{}
+// 			res.Buyer = qutil.ObjToString((*data)[0]["buyer"])
+// 			res.Createtime = qutil.Int64All((*data)[0]["yucetime"])
+// 			// res.Purchasing = (*data)[0]["results"].([]string)
+// 			res.Title = qutil.ObjToString((*data)[0]["title"])
+// 			res.Jyhref = qutil.ObjToString((*data)[0]["jyhref"])
+// 			return res, nil
+// 		}
+// 		return 0, nil
+// 	}()
+// 	if errMsg != nil {
+// 		log.Printf("%s   获取此预测项目信息出错-%s", userId, errMsg)
+// 	}
+// 	this.ServeJson(NewResult(rData, errMsg))
+// }
+
 //list
 func (this *Analysis) ForPList() {
 	defer qutil.Catch()
@@ -106,7 +155,9 @@ func (this *Analysis) ForPList() {
 		msg := ""
 		code := 0
 		list := []map[string]interface{}{}
+		flist := []map[string]interface{}{}
 		count := 0
+		var fcount int64 = 0
 		userId, _ := this.GetSession("userId").(string)
 		main_userId, _, _ := util.MainUserId(userId, "", 0)
 		isSubCount := false
@@ -114,20 +165,23 @@ func (this *Analysis) ForPList() {
 		if userId != main_userId {
 			isSubCount = true
 		}
+		pageNum, _ := this.GetInteger("pageNum")
+		o_member_jy := &map[string]interface{}{}
 		//查库获得大会员用户的信息
 		o_mb, ok := db.Mgo.FindById(C_User, main_userId, `{"o_member_jy":1}`)
 		if ok && o_mb != nil && (*o_mb) != nil {
 			if (*o_mb)["o_member_jy"] != nil {
-				pageNum, _ := this.GetInteger("pageNum")
-				list, count = getNewProjects(main_userId, pageNum)
-				o_member_jy := qutil.ObjToMap((*o_mb)["o_member_jy"])
+				// list, count = getNewProjects(main_userId, pageNum)
+				o_member_jy = qutil.ObjToMap((*o_mb)["o_member_jy"])
+				//项目预测检索库
+				flist, fcount = getNewForecast(main_userId, pageNum, *o_member_jy)
 				if pageNum == 1 {
 					if (*o_member_jy)["a_items"] != nil {
 						a_items := qutil.ObjArrToMapArr((*o_member_jy)["a_items"].([]interface{}))
-						if len(a_items) == 0 {
+						if len(a_items) == 0 || a_items[0]["a_key"] == nil || len(a_items[0]["a_key"].([]interface{})) == 0 {
 							msg = "暂无设置订阅关键词,无法进行预测"
 							code = 1
-						} else if list == nil || len(list) == 0 {
+						} else if (list == nil || len(list) == 0) && len(flist) == 0 {
 							msg = "您设置的订阅关键词无法进行预测"
 							code = 2
 						}
@@ -145,8 +199,8 @@ func (this *Analysis) ForPList() {
 		regMap.Data = map[string]interface{}{
 			"msg":        msg,
 			"code":       code,
-			"list":       list,
-			"count":      count,
+			"list":       forecastMerge(list, flist),
+			"count":      int64(count) + fcount,
 			"isSubCount": isSubCount,
 		}
 	} else {
@@ -156,6 +210,61 @@ func (this *Analysis) ForPList() {
 	this.ServeJson(regMap)
 }
 
+type ForecastInfo struct {
+	Buyer      string   `json:"buyer"`
+	Id         string   `json:"id"`
+	Purchasing []string `json:"purchasing"`
+	Title      string   `json:"title"`
+	Createtime int64    `json:"createtime"`
+	Keys       string   `json:"keys"`
+	Jyhref     string   `json:"jyhref"`
+}
+
+//合并去重
+func forecastMerge(r, f []map[string]interface{}) []*ForecastInfo {
+	var idMap = map[string]bool{}
+	var res = []*ForecastInfo{}
+	var isSort = 0
+	if len(r) > 0 {
+		isSort = isSort + 1
+		for _, rv := range r {
+			idMap[qutil.ObjToString(rv["id"])] = true
+			res = append(res, &ForecastInfo{
+				Buyer:      qutil.ObjToString(rv["buyer"]),
+				Id:         util.EncodeId(qutil.ObjToString(rv["id"])),
+				Purchasing: rv["results"].([]string),
+				Title:      qutil.ObjToString(rv["title"]),
+				Createtime: qutil.Int64All(rv["createtime"]),
+				Keys:       "",
+			})
+		}
+	}
+	if len(f) > 0 {
+		isSort = isSort + 1
+		for _, fv := range f {
+			if idMap[qutil.ObjToString(fv["id"])] {
+				continue
+			}
+			res = append(res, &ForecastInfo{
+				Buyer:      qutil.ObjToString(fv["buyer"]),
+				Id:         util.EncodeId(qutil.ObjToString(fv["id"])),
+				Purchasing: fv["results"].([]string),
+				Title:      qutil.ObjToString(fv["title"]),
+				Createtime: qutil.Int64All(fv["yucetime"]),
+				Jyhref:     qutil.ObjToString(fv["jyhref"]),
+				Keys:       "",
+			})
+		}
+	}
+	//
+	if isSort > 1 {
+		sort.Slice(res, func(i, j int) bool {
+			return res[i].Createtime > res[j].Createtime
+		})
+	}
+	return res
+}
+
 //getData
 func getNewProjects(userId string, cpage int) ([]map[string]interface{}, int) {
 	if cpage == 0 {
@@ -172,9 +281,8 @@ func getNewProjects(userId string, cpage int) ([]map[string]interface{}, int) {
 	}, `{"createtime":-1}`, `{"buyer":1,"results":1,"createtime":1,"title":1,"id":1}`, false, (cpage-1)*FP_Limit, FP_Limit)
 	if ok && data != nil && len(*data) > 0 {
 		for _, ov := range *data {
-			createtime := ov["createtime"]
-			ov["createtime"] = qutil.FormatDateWithObj(&createtime, qutil.Date_Short_Layout)
-			ov["id"] = util.EncodeId(ov["id"].(string))
+			ov["createtime"] = qutil.Float64All(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")
 		}
@@ -184,7 +292,7 @@ func getNewProjects(userId string, cpage int) ([]map[string]interface{}, int) {
 }
 
 //过滤 去重 处理特殊符号
-func keysfilter(result []map[string]interface{}) (res []map[string]interface{}) {
+func keysfilter(result []map[string]interface{}) (res []string) {
 	if len(result) > 0 {
 		var keysMap = map[string]bool{}
 	L:
@@ -198,9 +306,274 @@ func keysfilter(result []map[string]interface{}) (res []map[string]interface{})
 				keysMap[strings.ReplaceAll(kv, "+", "、")] = true
 				_keys = append(_keys, strings.ReplaceAll(kv, "+", "、"))
 			}
-			rv["keys"] = strings.Split(strings.Join(_keys, "、"), " ")
-			res = append(res, rv)
+			// rv["keys"] = strings.Split(strings.Join(_keys, "、"), " ")
+			res = append(res, strings.Split(strings.Join(_keys, "、"), " ")...)
 		}
 	}
 	return res
 }
+
+var d *dfa.DFA = &dfa.DFA{}
+
+//
+func getNewForecast(userId string, pageNum int, o_member_jy map[string]interface{}) (list []map[string]interface{}, count int64) {
+	if userId == "" {
+		return
+	}
+	sql := getSqlObjFromId(o_member_jy)
+	if sql == nil {
+		return
+	}
+	keys := []string{}
+	keyIsexists := map[string]bool{}
+	for _, v := range sql.Keyword {
+		var keys_one []string
+		for _, k := range v.Keyword {
+			keys_one = append(keys_one, k)
+		}
+		for _, k := range v.Appended {
+			keys_one = append(keys_one, k)
+		}
+		if keyIsexists[strings.Join(keys_one, "+")] {
+			continue
+		}
+		keyIsexists[strings.Join(keys_one, "+")] = true
+		keys = append(keys, strings.Join(keys_one, "+"))
+	}
+	if len(keys) == 0 {
+		return
+	}
+	qstr := GetMemberForecastSql(sql)
+	count = elastic.Count(INDEX, TYPE, qstr)
+	list = *elastic.GetAllByNgram(INDEX, TYPE, qstr, findfields, bidSearch_sort, bidSearch_field, (pageNum-1)*FP_Limit, FP_Limit, 0, false)
+	if list != nil {
+		d.AddWord(keys...)
+		for _, v := range list {
+			var rsArr = []string{}
+			var rsArrRes = []string{}
+			if v["results"] != nil {
+				results := qutil.ObjArrToMapArr(v["results"].([]interface{}))
+				rsvMap := map[string]bool{}
+				for _, rsv := range results {
+					rsArr = append(rsArr, d.Analy(rsv["purchasing"].(string))...)
+				}
+				for _, rv := range rsArr {
+					if rsvMap[strings.Join(rsArr, "+")] {
+						continue
+					}
+					rsArrRes = append(rsArrRes, rv)
+					rsvMap[strings.Join(rsArr, "+")] = true
+				}
+			}
+			v["results"] = rsArrRes
+			v["id"] = qutil.ObjToString(v["_id"])
+			v["yucetime"] = qutil.Int64All(v["yucetime"].(float64))
+		}
+		d.Clear()
+	}
+	return
+}
+
+//获取大会员forecast 检索库查询语句
+func GetMemberForecastSql(scd *util.ViewCondition) string {
+	query := `{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}}`
+	query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
+	multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
+	query_bool_must_and := `{"bool":{"must":[%s]%s}}`
+	query_must_exists := `{"bool":{"should":{"filtered":{"filter":{"bool":{"must":[{"exists":{"field":"yuceendtime"}},{"range":{"yuceendtime":{"lte":%d}}}]}}}}}}`
+
+	bools := []string{}
+	musts := []string{}
+	//预测时间最新三个月
+	musts = append(musts, fmt.Sprintf(`{"range":{"yucetime":{"gte":%d}}}`, time.Now().AddDate(0, -3, 0).Unix()), fmt.Sprintf(query_must_exists, time.Now().Unix()))
+	//省份
+	areaCity := []string{}
+	if len(scd.Area) > 0 {
+		areaquery := `{"terms":{"area":[`
+		for k, v := range scd.Area {
+			if k > 0 {
+				areaquery += `,`
+			}
+			areaquery += `"` + v + `"`
+		}
+		areaquery += `]}}`
+		areaCity = append(areaCity, areaquery)
+	}
+
+	//城市
+	if len(scd.City) > 0 {
+		areaquery := `{"terms":{"city":[`
+		for k, v := range scd.City {
+			if k > 0 {
+				areaquery += `,`
+			}
+			areaquery += `"` + v + `"`
+		}
+		areaquery += `]}}`
+		areaCity = append(areaCity, areaquery)
+	}
+	if len(areaCity) > 0 {
+		musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(areaCity, ",")))
+	}
+	// if len(scd.Subtype) > 0 {
+	// 	subquery := `{"terms":{"subtype":[`
+	// 	for k, v := range scd.Subtype {
+	// 		if k > 0 {
+	// 			subquery += `,`
+	// 		}
+	// 		subquery += `"` + v + `"`
+	// 	}
+	// 	subquery += `]}}`
+	// 	musts = append(musts, subquery)
+	// }
+	if len(scd.Buyerclass) > 0 {
+		Buyerclass := `{"terms":{"buyerclass":[`
+		for k, v := range scd.Buyerclass {
+			if k > 0 {
+				Buyerclass += `,`
+			}
+			Buyerclass += `"` + v + `"`
+		}
+		Buyerclass += `]}}`
+		musts = append(musts, Buyerclass)
+	}
+	boolsNum := 0 //should
+	if len(scd.Keyword) > 0 {
+		boolsNum = 1
+		multi_match = fmt.Sprintf(multi_match, "%s", `"results.purchasing.mypurchasing"`)
+
+		for _, v := range scd.Keyword {
+			shoulds := []string{}
+			must_not := []string{}
+			//附加词
+			for _, vv := range v.Keyword {
+				shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
+			}
+
+			for _, vv := range v.Appended {
+				shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
+			}
+
+			//排除词
+			for _, vv := range v.Exclude {
+				must_not = append(must_not, fmt.Sprintf(multi_match, "\""+vv+"\""))
+			}
+
+			//添加
+			if len(shoulds) > 0 {
+				notStr := ""
+				if len(must_not) > 0 {
+					notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
+				}
+				bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
+			}
+		}
+	}
+
+	qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum)
+	log.Println("------qstr", qstr)
+	return qstr
+}
+
+//
+
+//member_jy
+func getSqlObjFromId(o_member_jy map[string]interface{}) *util.ViewCondition {
+	if o_member_jy["a_items"] == nil {
+		return nil
+	}
+	a_items := []interface{}{}
+	if o_member_jy["a_items"] != nil {
+		a_items = o_member_jy["a_items"].([]interface{})
+	}
+	a_buyerclass := []interface{}{}
+	if o_member_jy["a_buyerclass"] != nil {
+		a_buyerclass = o_member_jy["a_buyerclass"].([]interface{})
+	}
+	if len(a_buyerclass) > 0 && qutil.IntAllDef(o_member_jy["i_matchbuyerclass_other"], 1) == 1 && len(a_items) > 0 {
+		a_buyerclass = append(a_buyerclass, "其它")
+	}
+	a_infotype := []interface{}{}
+	if o_member_jy["a_infotype"] != nil {
+		a_infotype = o_member_jy["a_infotype"].([]interface{})
+	}
+	o_area := map[string]interface{}{}
+	if o_member_jy["o_area"] != nil {
+		o_area = o_member_jy["o_area"].(map[string]interface{})
+	}
+	return &util.ViewCondition{
+		Keyword:    getKeyWordArr(a_items, "", -1),
+		Buyerclass: qutil.ObjArrToStringArr(a_buyerclass),
+		Subtype:    qutil.ObjArrToStringArr(a_infotype),
+		Area:       getStringArrFromDbResult(o_area, 1),
+		City:       getStringArrFromDbResult(o_area, 2),
+		SelectType: strconv.Itoa(qutil.IntAll(o_member_jy["i_matchway"])),
+	}
+}
+
+//关键词 附加词 排除词
+func getKeyWordArr(a_items []interface{}, item string, index int) (arr []util.ViewKeyWord) {
+	if a_items == nil {
+		return
+	}
+	for _, v := range a_items {
+		vm, _ := v.(map[string]interface{})
+		if item != "" && index >= 0 && item != qutil.ObjToString(vm["s_item"]) {
+			continue
+		}
+		if vm["a_key"] == nil {
+			continue
+		}
+		kwsArr := vm["a_key"]
+		for i, k := range kwsArr.([]interface{}) {
+			if item != "" && index >= 0 && i != index {
+				continue
+			}
+			kw := util.ViewKeyWord{}
+			b, e := json.Marshal(k)
+			if e != nil {
+				log.Println(e.Error())
+			}
+			json.Unmarshal(b, &kw)
+			if kw.MatchWay == 1 {
+				for _, kk := range kw.Keyword {
+					arr = append(arr, util.ViewKeyWord{
+						Keyword: []string{kk},
+						Exclude: kw.Exclude,
+					})
+				}
+				for _, kk := range kw.Appended {
+					arr = append(arr, util.ViewKeyWord{
+						Keyword: []string{kk},
+						Exclude: kw.Exclude,
+					})
+				}
+			} else {
+				arr = append(arr, kw)
+			}
+		}
+	}
+	return
+}
+
+//
+func getStringArrFromDbResult(area map[string]interface{}, i int) (arr []string) {
+	if area == nil {
+		return
+	}
+	var eareArr []string
+	var cityArr []string
+	for k, v := range area {
+		if len(v.([]interface{})) > 0 {
+			cityArr = append(cityArr, qutil.ObjArrToStringArr(v.([]interface{}))...)
+		} else {
+			eareArr = append(eareArr, k)
+		}
+	}
+	if i == 1 {
+		arr = eareArr
+	} else {
+		arr = cityArr
+	}
+	return
+}

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

@@ -124,13 +124,13 @@ func (this *Analysis) FWData() {
 						s_phone, _ = this.GetSession("s_m_phone").(string)
 					}
 					main_userId, phone, member_status := util.MainUserId(userId, s_phone, 0)
-					UIL.Lock()
-					if UIL.forWLock[main_userId] == nil {
-						UIL.forWLock[main_userId] = &sync.Mutex{}
+					entity.UIL.Lock()
+					if entity.UIL.ForWLock[main_userId] == nil {
+						entity.UIL.ForWLock[main_userId] = &sync.Mutex{}
 					}
-					UIL.Unlock()
-					UIL.forWLock[main_userId].Lock()
-					defer UIL.forWLock[main_userId].Unlock()
+					entity.UIL.Unlock()
+					entity.UIL.ForWLock[main_userId].Lock()
+					defer entity.UIL.ForWLock[main_userId].Unlock()
 					// log.Println(getRes.ServiceId, "----------", phone)
 					//判断是否有中标预测权限
 					var currentCount = 0

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

@@ -170,6 +170,7 @@ type DecWinnerInfo struct {
 	Buyer_other_list   BuyerSOOL `json:"buyer_other_list"`   //与采购单位其他项目合作历史
 	Capital            int64     `json:"capital"`            //中标企业注册资本
 	EntId              string    `json:"entId"`              //中标企业加密id
+	Max_jytime         int64     `json:"max_jytime"`         //类似项目中标时间
 }
 
 type BuyerSOOL struct {

+ 6 - 2
src/jfw/modules/bigmember/src/service/follow/enterprise.go

@@ -177,17 +177,21 @@ func (this *FollowEnt) EntChangeList() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
 		cepm, err := entity.CreateEntFollowManager(userId, "entChange")
+
 		if err != nil {
 			return nil, err
 		}
 		if !cepm.HasPower {
 			return nil, fmt.Errorf("暂无权限")
 		}
-		entInfo, err := cepm.GetEntChangeList(util.DecodeId(this.GetString("entId")))
+		entInfo, total, err := cepm.GetEntChangeList(util.DecodeId(this.GetString("entId")), qutil.IntAll(this.GetString("showPart")))
 		if err != nil {
 			return nil, err
 		}
-		return entInfo, nil
+		return map[string]interface{}{
+			"list":  entInfo,
+			"total": total,
+		}, nil
 	}()
 	if errMsg != nil {
 		log.Printf("%s 企业画像-查询企业基本信息:%s\n", userId, errMsg.Error())

+ 85 - 48
src/jfw/modules/bigmember/src/service/portrait/memberPortraitAction.go

@@ -15,16 +15,17 @@ import (
 type EntPortrait struct {
 	*xweb.Action
 	//中标企业画像
-	entDetail           xweb.Mapper `xweb:"/portrait/ent/detail"`              //企业基本信息
-	winnerNewMsg        xweb.Mapper `xweb:"/portrait/winner/getNewMsg"`        //最新项目动态(需购买项目进度监控)
-	winnerNewMsgSelects xweb.Mapper `xweb:"/portrait/winner/getNewMsgSelects"` //最新招标信息可筛选项
-	winnerContacts      xweb.Mapper `xweb:"/portrait/winner/contacts"`         //历史项目联系方式
-	winnerPortrait      xweb.Mapper `xweb:"/portrait/winner/getData"`          //最新项目动态
-	winnerMiniPortrait  xweb.Mapper `xweb:"/portrait/winner/miniData"`         //三级页展示中标企业基础画像信息
+	entDetail          xweb.Mapper `xweb:"/portrait/ent/detail"`       //企业基本信息
+	winnerContacts     xweb.Mapper `xweb:"/portrait/winner/contacts"`  //历史项目联系方式
+	winnerSelects      xweb.Mapper `xweb:"/portrait/winner/selects"`   //企业画像可筛选项
+	winnerNewMsg       xweb.Mapper `xweb:"/portrait/winner/getNewMsg"` //最新项目动态(需购买项目进度监控)[筛选]
+	winnerPortrait     xweb.Mapper `xweb:"/portrait/winner/getData"`   //中标企业画像数据[筛选]
+	winnerMiniPortrait xweb.Mapper `xweb:"/portrait/winner/miniData"`  //三级页展示中标企业基础画像信息
 	//采购单位画像
-	buyerNewMsg       xweb.Mapper `xweb:"/portrait/buyer/getNewMsg"` //最新项目动态
 	buyerContacts     xweb.Mapper `xweb:"/portrait/buyer/contacts"`  //采购项目联系方式
-	buyerPortrait     xweb.Mapper `xweb:"/portrait/buyer/getData"`   //最新项目动态
+	buyerSelects      xweb.Mapper `xweb:"/portrait/buyer/selects"`   //采购单位画像可筛选项
+	buyerNewMsg       xweb.Mapper `xweb:"/portrait/buyer/getNewMsg"` //最新项目动态[筛选]
+	buyerPortrait     xweb.Mapper `xweb:"/portrait/buyer/getData"`   //采购单位画像数据[筛选]
 	buyerMiniPortrait xweb.Mapper `xweb:"/portrait/buyer/miniData"`  //三级页展示采购单位基础画像信息
 }
 
@@ -75,8 +76,8 @@ func (this *EntPortrait) WinnerContacts() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
-// WinnerNewMsgSelects 企业最新项目动态可供筛选的条件
-func (this *EntPortrait) WinnerNewMsgSelects() {
+// WinnerSelects 企业画像可供筛选的条件
+func (this *EntPortrait) WinnerSelects() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
 		entId := util.DecodeId(this.GetString("entId"))
@@ -90,11 +91,11 @@ func (this *EntPortrait) WinnerNewMsgSelects() {
 		if !hasPower {
 			return nil, fmt.Errorf("非法请求")
 		}
-		pwp := &entity.PortraitWinnerProject{EntId: entId}
-		return pwp.GetProjectSelectItems()
+		pwp := &entity.PortraitScreen{Ent: entId}
+		return pwp.GetProjectSelectItems(true)
 	}()
 	if errMsg != nil {
-		log.Printf("%s WinnerNewMsgSelects 获取企业最新中标信息筛选条件出错:%s\n", userId, errMsg.Error())
+		log.Printf("%s WinnerSelects 获取企业画像可筛选条件出错:%s\n", userId, errMsg.Error())
 	}
 	this.ServeJson(NewResult(rData, errMsg))
 }
@@ -117,15 +118,19 @@ func (this *EntPortrait) WinnerNewMsg() {
 		pageNum, _ := this.GetInteger("pageNum")
 		pageSize, _ := this.GetInteger("pageSize")
 
-		rData, total, err := cepm.GetWinnerNewMsg(&entity.PortraitWinnerProject{
-			EntId:     entId,
-			Match:     this.GetString("match"),
-			MatchType: this.GetString("matchType"),
-			Area:      this.GetString("area"),
-			InfoType:  this.GetString("infoType"),
-			PushTime:  this.GetString("pushTime"),
-			PageNum:   pageNum,
-			PageSize:  pageSize,
+		rData, total, err := cepm.GetWinnerNewMsg(&entity.PortraitProjectScreen{
+			Screen: &entity.PortraitScreen{
+				Ent:        entId,
+				Match:      this.GetString("match"),
+				ExactMatch: this.GetString("exactMatch") == "1",
+				MatchRange: this.GetString("matchRange"),
+				Area:       this.GetString("area"),
+				ScopeClass: this.GetString("scopeClass"),
+				TimeRange:  this.GetString("timeRange"),
+				HasPower:   hasPower,
+			},
+			PageNum:  pageNum,
+			PageSize: pageSize,
 		})
 		if err != nil {
 			return nil, err
@@ -150,7 +155,16 @@ func (this *EntPortrait) WinnerPortrait() {
 			return nil, err
 		}
 		entId := this.GetString("entId")
-		rData, err := cepm.WinnerPortraitData(util.DecodeId(entId), hasPower)
+		rData, err := cepm.WinnerPortraitData(&entity.PortraitScreen{
+			Ent:        util.DecodeId(entId),
+			Match:      this.GetString("match"),
+			ExactMatch: this.GetString("exactMatch") == "1",
+			MatchRange: this.GetString("matchRange"),
+			Area:       this.GetString("area"),
+			ScopeClass: this.GetString("scopeClass"),
+			TimeRange:  this.GetString("timeRange"),
+			HasPower:   hasPower,
+		})
 		if err != nil {
 			return nil, err
 		}
@@ -194,6 +208,28 @@ func (this *EntPortrait) WinnerMiniPortrait() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
+//BuyerSelects 采购单位画像可供筛选的条件
+//dev.6.2.1免费用户可筛选画像
+func (this *EntPortrait) BuyerSelects() {
+	userId := qutil.ObjToString(this.GetSession("userId"))
+	rData, errMsg := func() (interface{}, error) {
+		buyer := this.GetString("buyer")
+		if buyer == "" {
+			return nil, fmt.Errorf("企业参数异常")
+		}
+		_, _, err := entity.CreatePortraitManager(userId, "buyerPortrait")
+		if err != nil {
+			return nil, err
+		}
+		pwp := &entity.PortraitScreen{Ent: buyer}
+		return pwp.GetProjectSelectItems(false)
+	}()
+	if errMsg != nil {
+		log.Printf("%s BuyerSelects 获取采购的单位画像可筛选条件出错:%s\n", userId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}
+
 //BuyerNewMsg 采购单位画像-最新招标动态(免费用户仅可查看3条记录,付费50条)
 func (this *EntPortrait) BuyerNewMsg() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
@@ -204,38 +240,30 @@ func (this *EntPortrait) BuyerNewMsg() {
 		}
 
 		buyer := this.GetString("buyer")
-		count, _ := this.GetInt("count")
-
 		pageNum, _ := this.GetInteger("pageNum")
-		limit, _ := this.GetInteger("pageSize")
-		if limit == 0 {
-			limit = 3
-		}
-		var start = 0
-		if pageNum > 0 {
-			start = (pageNum - 1) * limit
-		}
+		pageSize, _ := this.GetInteger("pageSize")
 
-		if pageSign := this.GetString("pageSign"); pageSign != "" && hasPower { //more:4-23条;max:24-50条(移动端)
-			if pageSign == "more" {
-				start = 3
-				limit = 20
-			} else if pageSign == "max" {
-				start = 20 + 3
-				limit = entity.PortraitNewMegsLimit - start
-			}
-		}
 		//免费用户仅可查看三条记录
-		rData, err := cepm.GetBuyerNewMsg(buyer, start, limit, hasPower)
+		rData, total, err := cepm.GetBuyerNewMsg(&entity.PortraitProjectScreen{
+			Screen: &entity.PortraitScreen{
+				Ent:        buyer,
+				Match:      this.GetString("match"),
+				ExactMatch: this.GetString("exactMatch") == "1",
+				MatchRange: this.GetString("matchRange"),
+				Area:       this.GetString("area"),
+				ScopeClass: this.GetString("scopeClass"),
+				TimeRange:  this.GetString("timeRange"),
+				HasPower:   hasPower,
+			},
+			PageNum:  pageNum,
+			PageSize: pageSize,
+		})
 		if err != nil {
 			return nil, err
 		}
-		if count == 0 {
-			count = cepm.GetBuyerNewCount(buyer)
-		}
 		return map[string]interface{}{
 			"list":  rData,
-			"count": count,
+			"count": total,
 		}, nil
 	}()
 	if errMsg != nil {
@@ -280,7 +308,16 @@ func (this *EntPortrait) BuyerPortrait() {
 		}
 		entName := this.GetString("buyer")
 		flag := this.GetString("flag") //分段请求标识
-		rData, err := cepm.BuyerPortraitData(entName, flag, hasPower)
+		rData, err := cepm.BuyerPortraitData(&entity.PortraitScreen{
+			Ent:        entName,
+			Match:      this.GetString("match"),
+			ExactMatch: this.GetString("exactMatch") == "1",
+			MatchRange: this.GetString("matchRange"),
+			Area:       this.GetString("area"),
+			ScopeClass: this.GetString("scopeClass"),
+			TimeRange:  this.GetString("timeRange"),
+			HasPower:   hasPower,
+		}, flag)
 		if err != nil {
 			return nil, err
 		}

+ 44 - 30
src/jfw/modules/bigmember/src/service/portrait/subvipPortraitAction.go

@@ -18,15 +18,15 @@ import (
 //超级订阅升级版画像接口
 type SubVipPortrait struct {
 	*xweb.Action
-	subVipEntDetail     xweb.Mapper `xweb:"/portrait/subVipPortrait/entDetail"`        //企业基本信息
-	subVipPortrait      xweb.Mapper `xweb:"/portrait/subVipPortrait/winner"`           //超级订阅升级版查看画像
-	subVipWinnerNewMsg  xweb.Mapper `xweb:"/portrait/subVipPortrait/winnerNewMsg"`     //超级订阅升级版查看最新项目动态
-	subVipNewMsgSelects xweb.Mapper `xweb:"/portrait/subVipPortrait/getNewMsgSelects"` //最新招标信息可筛选项
-	portraitUsage       xweb.Mapper `xweb:"/portrait/subVipPortrait/usage"`            //超级订阅升级版画像浏览详情
-	portraitRecord      xweb.Mapper `xweb:"/portrait/subVipPortrait/record"`           //超级订阅升级版画像浏览记录
+	subVipEntDetail     xweb.Mapper `xweb:"/portrait/subVipPortrait/entDetail"`    //企业基本信息
+	subVipPortrait      xweb.Mapper `xweb:"/portrait/subVipPortrait/winner"`       //超级订阅升级版查看画像
+	subVipWinnerNewMsg  xweb.Mapper `xweb:"/portrait/subVipPortrait/winnerNewMsg"` //超级订阅升级版查看最新项目动态
+	subVipNewMsgSelects xweb.Mapper `xweb:"/portrait/subVipPortrait/selects"`      //最新招标信息可筛选项
+	portraitUsage       xweb.Mapper `xweb:"/portrait/subVipPortrait/usage"`        //超级订阅升级版画像浏览详情
+	portraitRecord      xweb.Mapper `xweb:"/portrait/subVipPortrait/record"`       //超级订阅升级版画像浏览记录
 }
 
-//超级订阅升级版查询基本信息
+//SubVipEntDetail 超级订阅升级版查询基本信息
 func (this *SubVipPortrait) SubVipEntDetail() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
@@ -47,7 +47,7 @@ func (this *SubVipPortrait) SubVipEntDetail() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
-//超级订阅升级版查看最新中标动态
+//SubVipWinnerNewMsg 超级订阅升级版查看最新中标动态
 func (this *SubVipPortrait) SubVipWinnerNewMsg() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
@@ -67,15 +67,19 @@ func (this *SubVipPortrait) SubVipWinnerNewMsg() {
 		pageNum, _ := this.GetInteger("pageNum")
 		pageSize, _ := this.GetInteger("pageSize")
 
-		rData, total, err := cepm.GetWinnerNewMsg(&entity.PortraitWinnerProject{
-			EntId:     entId,
-			Match:     this.GetString("match"),
-			MatchType: this.GetString("matchType"),
-			Area:      this.GetString("area"),
-			InfoType:  this.GetString("infoType"),
-			PushTime:  this.GetString("pushTime"),
-			PageNum:   pageNum,
-			PageSize:  pageSize,
+		rData, total, err := cepm.GetWinnerNewMsg(&entity.PortraitProjectScreen{
+			Screen: &entity.PortraitScreen{
+				Ent:        entId,
+				Match:      this.GetString("match"),
+				ExactMatch: this.GetString("matchType") == "1",
+				MatchRange: this.GetString("matchRange"),
+				Area:       this.GetString("area"),
+				ScopeClass: this.GetString("scopeClass"),
+				TimeRange:  this.GetString("timeRange"),
+				HasPower:   true,
+			},
+			PageNum:  pageNum,
+			PageSize: pageSize,
 		})
 		if err != nil {
 			return nil, err
@@ -91,6 +95,7 @@ func (this *SubVipPortrait) SubVipWinnerNewMsg() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
+//SubVipNewMsgSelects 获取画像可筛选项
 func (this *SubVipPortrait) SubVipNewMsgSelects() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
@@ -98,13 +103,16 @@ func (this *SubVipPortrait) SubVipNewMsgSelects() {
 		if entId == "" {
 			return nil, fmt.Errorf("企业参数异常")
 		}
-		//仅大会员、超级订阅升级版 可使用此接口
-		userMsg := jy.GetBigVipUserBaseMsg(userId, db.Mysql, db.Mgo)
-		if !(userMsg.VipStatus > 0 && userMsg.Vip_BuySet.Upgrade > 0) {
-			return nil, fmt.Errorf("非法请求")
+		_, bigMsg, err := entity.CreateSubVipPortraitManager(userId, "entNewMsg")
+		if err != nil {
+			return nil, err
 		}
-		pwp := &entity.PortraitWinnerProject{EntId: entId}
-		return pwp.GetProjectSelectItems()
+		//校验超级订阅画像浏览次数
+		if err = bigMsg.SubVipPortraitTimesCheck(db.Mysql, entId); err != nil {
+			return nil, err
+		}
+		pwp := &entity.PortraitScreen{Ent: entId}
+		return pwp.GetProjectSelectItems(true)
 	}()
 	if errMsg != nil {
 		log.Printf("%s SubVipNewMsgSelects 获取企业最新中标信息筛选条件出错:%s\n", userId, errMsg.Error())
@@ -112,7 +120,7 @@ func (this *SubVipPortrait) SubVipNewMsgSelects() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
-//超级订阅升级版查看企业画像
+//SubVipPortrait 超级订阅升级版查看企业画像
 func (this *SubVipPortrait) SubVipPortrait() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
@@ -128,10 +136,16 @@ func (this *SubVipPortrait) SubVipPortrait() {
 		if err = bigMsg.SubVipPortraitTimesCheck(db.Mysql, entId); err != nil {
 			return nil, err
 		}
-		rData, err := cepm.WinnerPortraitData(entId, true)
-		if err != nil {
-			return nil, err
-		}
+		rData, err := cepm.WinnerPortraitData(&entity.PortraitScreen{
+			Ent:        entId,
+			Match:      this.GetString("match"),
+			ExactMatch: this.GetString("exactMatch") == "1",
+			MatchRange: this.GetString("matchRange"),
+			Area:       this.GetString("area"),
+			ScopeClass: this.GetString("scopeClass"),
+			TimeRange:  this.GetString("timeRange"),
+			HasPower:   true,
+		})
 		return rData, nil
 	}()
 	if errMsg != nil {
@@ -140,7 +154,7 @@ func (this *SubVipPortrait) SubVipPortrait() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
-//超级订阅升级版画像浏览量查询
+//PortraitUsage 超级订阅升级版画像浏览量查询
 func (this *SubVipPortrait) PortraitUsage() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
@@ -166,7 +180,7 @@ func (this *SubVipPortrait) PortraitUsage() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
-//超级订阅升级版画像查看记录
+//PortraitRecord 超级订阅升级版画像查看记录
 func (this *SubVipPortrait) PortraitRecord() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {

+ 9 - 0
src/jfw/modules/bigmember/src/service/use/use.go

@@ -612,6 +612,15 @@ func (u *Use) IsAdd() {
 		d["viper"] = bigPower.Vip_BuySet.Upgrade == 1
 		d["isSubCount"] = bigPower.Pid != ""
 		d["is_member_trial"] = bigPower.HasTrial
+		d["entniche"] = false                       //是否是商机管理用户
+		d["freeEntPort"] = bigPower.FreeEntPort     //免费用户可查看企业画像次数
+		d["freeBuyerPort"] = bigPower.FreeBuyerPort //免费用户可查看采购单位画像次数
+		d["freeFile"] = bigPower.FreeFile           //免费用户可以进行附件下载次数
+		d["isUpgrade"] = bigPower.IsUpgrade         //是否是升级后的免费用户  默认false
+		//新用户->新订阅设置页面
+		if config.Config.NewFreeUser < bigPower.Registedate {
+			d["isUpgrade"] = true
+		}
 		uid := userid
 		if bigPower.Pid != "" {
 			uid = bigPower.Pid

+ 6 - 5
src/jfw/modules/common/src/qfw/util/bidsearch/search.go

@@ -25,9 +25,10 @@ const (
 	SearchPageSize_PC  = 50
 
 	//招标搜索分页--最大页数
-	SearchMaxPageNum_APP = 20
-	SearchMaxPageNum_WX  = 20
-	SearchMaxPageNum_PC  = 10
+	SearchMaxPageNum_APP   = 10
+	SearchMaxPageNum_WX    = 10
+	SearchMaxPageNum_PC    = 10 //免费用户500条记录
+	SearchMaxPageNum_PAYED = 10 //付费用户5000条记录
 )
 
 //GetWxsearchlistData 移动端招标信息搜索
@@ -65,7 +66,7 @@ func GetWxsearchlistData(keywords, scope, publishtime, subtype, industry, minpri
 }
 
 //GetPcBidSearchData pc端招标信息搜索
-func GetPcBidSearchData(searchvalue, area, publishtime, subtype, industry, minprice, maxprice, winner, buyerclass, hasBuyerTel, hasWinnerTel string, start, pageSize int, isGetCount bool, selectTypeArr []string, field, notkey string) (count, totalPage int64, list *[]map[string]interface{}) {
+func GetPcBidSearchData(searchvalue, area, publishtime, subtype, industry, minprice, maxprice, winner, buyerclass, hasBuyerTel, hasWinnerTel string, start, pageSize int, isGetCount bool, selectTypeArr []string, field, notkey string, ispayed bool) (count, totalPage int64, list *[]map[string]interface{}) {
 	var findfields string
 	var hightlightContent bool = false //是否高亮正文
 	for _, v := range selectTypeArr {
@@ -95,7 +96,7 @@ func GetPcBidSearchData(searchvalue, area, publishtime, subtype, industry, minpr
 			list = repl
 		}
 	}
-	limitCount := int64(SearchPageSize_PC * SearchMaxPageNum_PC)
+	limitCount := util.If(ispayed, int64(SearchPageSize_PC*SearchMaxPageNum_PAYED), int64(SearchPageSize_PC*SearchMaxPageNum_PC)).(int64)
 	if count > limitCount {
 		count = limitCount
 	}

+ 27 - 3
src/jfw/modules/common/src/qfw/util/jy/bigVipPower.go

@@ -26,6 +26,12 @@ type BigVipBaseMsg struct {
 
 	VipStatus  int    `json:"vip_status"` //超级订阅状态
 	Vip_BuySet BuySet `json:"vip_buyset"` //超级订阅套餐内容
+
+	FreeEntPort   int   `json:"freeEntPort"`   //免费用户可查看企业画像次数
+	FreeBuyerPort int   `json:"freeBuyerPort"` //免费用户可查看采购单位画像次数
+	FreeFile      int   `json:"freeFile"`      //免费用户可进行附件下载次数
+	IsUpgrade     bool  `json:"isUpgrade"`     //是否是免费用户订阅升级用户 默认true
+	Registedate   int64 `json:"registedate"`   //用户注册时间
 }
 
 //超级订阅购买内容
@@ -44,6 +50,12 @@ const (
 	PowerCacheDb  = "other"
 	PowerCacheKey = "bigmember_power_3_%s"
 	OneDay        = 60 * 60 * 24
+
+	PowerCacheEntPortKey   = "free_power_entport_%s"
+	PowerCacheBuyerPortKey = "free_power_buyerport_%s"
+	PowerCacheFileKey      = "free_power_File_%s"
+	UserUpdateAreaKey      = "free_area_num_%s_%s"
+	BaseAreaNum            = 1
 )
 
 //初始化大会员权益
@@ -87,6 +99,7 @@ func GetBigVipUserBaseMsg(userId string, mysql *mysql.Mysql, mg MongodbSim) *Big
 	if userId == "" {
 		return &userPower
 	}
+	userPower.IsUpgrade = false
 	userPower.Uid = userId
 	cacheKey := fmt.Sprintf(PowerCacheKey, userId)
 
@@ -96,9 +109,9 @@ func GetBigVipUserBaseMsg(userId string, mysql *mysql.Mysql, mg MongodbSim) *Big
 		}
 	}
 	//大会员状态
-	data, ok := mg.FindById("user", userId, `{"i_member_status":1,"i_member_give":1,"s_member_mainid":1,"i_member_sub_status":1,"i_member_trial":1,"i_vip_status":1,"o_vipjy":1}`)
-
+	data, ok := mg.FindById("user", userId, `{"i_member_status":1,"i_member_give":1,"s_member_mainid":1,"i_member_sub_status":1,"i_member_trial":1,"i_vip_status":1,"o_vipjy":1,"o_jy":1,"l_registedate":1}`)
 	if ok && *data != nil && len(*data) > 0 {
+		userPower.Registedate = qutil.Int64All((*data)["l_registedate"])
 		userPower.Status = qutil.IntAllDef((*data)["i_member_status"], 0)
 		//子账号被启用
 		i_member_sub_status := qutil.IntAllDef((*data)["i_member_sub_status"], 0)
@@ -123,8 +136,19 @@ func GetBigVipUserBaseMsg(userId string, mysql *mysql.Mysql, mg MongodbSim) *Big
 				}
 			}
 		}
+		//免费用户画像和附件下载权限
+		if userPower.Status <= 0 && userPower.VipStatus <= 0 {
+			//免费用户在企业画像/采购单位画像/附件下载留资 留资成功后用户才有功能使用次数
+			userPower.FreeEntPort = redis.GetInt(PowerCacheDb, fmt.Sprintf(PowerCacheEntPortKey, userId))
+			userPower.FreeBuyerPort = redis.GetInt(PowerCacheDb, fmt.Sprintf(PowerCacheBuyerPortKey, userId))
+			userPower.FreeFile = redis.GetInt(PowerCacheDb, fmt.Sprintf(PowerCacheFileKey, userId))
+			o_jy := qutil.ObjToMap((*data)["o_jy"])
+			//"i_newfree":    1, //新免费用户=>新订阅设置页面 20211122
+			if qutil.IntAll((*o_jy)["i_newfree"]) > 0 {
+				userPower.IsUpgrade = true
+			}
+		}
 	}
-
 	//子账号查询父节点权限
 	queryId := qutil.If(userPower.Pid == "", userId, userPower.Pid).(string)
 	//用户购买的服务

+ 5 - 5
src/jfw/modules/common/src/qfw/util/jy/switchService.go

@@ -32,16 +32,16 @@ func (s *switchService) Get(session *httpsession.Session, m MongodbSim) string {
 	v, _ := session.Get(s.SessionKey).(string)
 	u, ok := m.FindById("user", userId, `{"i_member_status":1,"i_vip_status":1}`)
 	if ok && u != nil {
-		if i_member_status := util.IntAll((*u)["i_member_status"]); v == s.Member && i_member_status > 0 {
-			return s.Member
-		} else if i_vip_status := util.IntAll((*u)["i_vip_status"]); v == s.Vip && i_vip_status > 0 {
+		if i_vip_status := util.IntAll((*u)["i_vip_status"]); v == s.Vip && i_vip_status > 0 {
 			return s.Vip
-		} else if i_member_status > 0 {
-			session.Set(s.SessionKey, s.Member)
+		} else if i_member_status := util.IntAll((*u)["i_member_status"]); v == s.Member && i_member_status > 0 {
 			return s.Member
 		} else if i_vip_status > 0 {
 			session.Set(s.SessionKey, s.Vip)
 			return s.Vip
+		} else if i_member_status > 0 {
+			session.Set(s.SessionKey, s.Member)
+			return s.Member
 		}
 	}
 	session.Del(s.SessionKey)

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác