Browse Source

Merge remote-tracking branch 'origin/feature/v4.9.39' into v4.9.39_ws

# Conflicts:
#	src/jfw/modules/app/src/go.mod
wangshan 1 năm trước cách đây
mục cha
commit
ec8c162f4d
100 tập tin đã thay đổi với 5229 bổ sung1335 xóa
  1. 3 1
      src/jfw/filter/pcfilter.go
  2. 4 3
      src/jfw/filter/sesssionKeep.go
  3. 1 1
      src/jfw/front/commonPayWx.go
  4. 8 2
      src/jfw/front/dataPackRouter.go
  5. 1 1
      src/jfw/front/front.go
  6. 6 5
      src/jfw/front/frontRouter.go
  7. 8 6
      src/jfw/front/login.go
  8. 2 1
      src/jfw/front/org_structure.go
  9. 2 1
      src/jfw/front/pchelper.go
  10. 8 7
      src/jfw/front/singleLogin.go
  11. 3 2
      src/jfw/front/swordfish.go
  12. 9 8
      src/jfw/front/websocket.go
  13. 15 0
      src/jfw/modules/app/p583.http
  14. 46 12
      src/jfw/modules/app/src/active.json
  15. 18 2
      src/jfw/modules/app/src/app/config/active.go
  16. 2 0
      src/jfw/modules/app/src/app/filter/loginfilter.go
  17. 110 0
      src/jfw/modules/app/src/app/front/activity.go
  18. 312 0
      src/jfw/modules/app/src/app/jyutil/activity.go
  19. 93 93
      src/jfw/modules/app/src/config.json
  20. 2 1
      src/jfw/modules/app/src/go.mod
  21. 5 0
      src/jfw/modules/app/src/go.sum
  22. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_portrait.css
  23. 5 2
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js
  24. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis_history.js
  25. 7 2
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js
  26. 5 1
      src/jfw/modules/app/src/web/templates/big-member/page_client_portrayal.html
  27. 21 4
      src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait.html
  28. 5 2
      src/jfw/modules/app/src/web/templates/big-member/page_orderdetail_member.html
  29. 643 603
      src/jfw/modules/app/src/web/templates/big-member/page_report_analysis.html
  30. 11 3
      src/jfw/modules/app/src/web/templates/big-member/page_report_analysis_history.html
  31. 7 1
      src/jfw/modules/app/src/web/templates/big-member/page_unit_portrayal.html
  32. 121 0
      src/jfw/modules/app/src/web/templates/commonPay/enterpriseAnalysis/orderDetail.html
  33. 121 0
      src/jfw/modules/app/src/web/templates/commonPay/marketAnalysis/orderDetail.html
  34. 121 0
      src/jfw/modules/app/src/web/templates/commonPay/ownerAnalysis/orderDetail.html
  35. 88 1
      src/jfw/modules/app/src/web/templates/commonPay/paySuccess.html
  36. 186 0
      src/jfw/modules/app/src/web/templates/frontRouter/activity/free/open-mini-program.html
  37. 500 0
      src/jfw/modules/bigmember/src/entity/marketAnalysis/analysisPdf.go
  38. 4 4
      src/jfw/modules/bigmember/src/entity/marketAnalysis/customized_analysis.go
  39. 29 0
      src/jfw/modules/bigmember/src/entity/marketAnalysis/marketAnalysisEntity.go
  40. 2 2
      src/jfw/modules/bigmember/src/entity/marketAnalysis/scaleRefineQuery.go
  41. 3 3
      src/jfw/modules/bigmember/src/entity/portrait.go
  42. 1 1
      src/jfw/modules/bigmember/src/entity/portraitBuyerSearch.go
  43. 30 3
      src/jfw/modules/bigmember/src/entity/portrait_screen.go
  44. 4 0
      src/jfw/modules/bigmember/src/filter/sessionfilter.go
  45. 2 0
      src/jfw/modules/bigmember/src/service/init.go
  46. 2 2
      src/jfw/modules/bigmember/src/service/portrait/subvipPortraitAction.go
  47. 2 2
      src/jfw/modules/bigmember/src/service/report/marketAnalysis.go
  48. 3 0
      src/jfw/modules/publicapply/src/detail/config.json
  49. 2 0
      src/jfw/modules/publicapply/src/detail/consts/consts.go
  50. 72 0
      src/jfw/modules/publicapply/src/detail/dao/baseInfo.go
  51. 3 0
      src/jfw/modules/publicapply/src/detail/entity/config.go
  52. 6 5
      src/jfw/modules/publicapply/src/detail/service/action.go
  53. 49 0
      src/jfw/modules/publicapply/src/detail/service/service.go
  54. 45 41
      src/jfw/modules/publicapply/src/filter/sessionfilter.go
  55. 9 0
      src/jfw/modules/publicapply/src/test/detail_test.http
  56. 1 0
      src/jfw/modules/subscribepay/src/a/init.go
  57. 7 7
      src/jfw/modules/subscribepay/src/baseApi.json
  58. 4 1
      src/jfw/modules/subscribepay/src/config.json
  59. 26 0
      src/jfw/modules/subscribepay/src/config.yaml
  60. 2 2
      src/jfw/modules/subscribepay/src/entity/basePack.go
  61. 69 0
      src/jfw/modules/subscribepay/src/entity/commodity.go
  62. 5 5
      src/jfw/modules/subscribepay/src/entity/commonApi.go
  63. 1 1
      src/jfw/modules/subscribepay/src/entity/equityCode.go
  64. 73 44
      src/jfw/modules/subscribepay/src/entity/member.go
  65. 55 0
      src/jfw/modules/subscribepay/src/entity/order.go
  66. 510 0
      src/jfw/modules/subscribepay/src/entity/pdfExportPack.go
  67. 3 15
      src/jfw/modules/subscribepay/src/go.mod
  68. 6 29
      src/jfw/modules/subscribepay/src/go.sum
  69. 12 3
      src/jfw/modules/subscribepay/src/pay/aliPay.go
  70. 17 5
      src/jfw/modules/subscribepay/src/pay/util.go
  71. 11 4
      src/jfw/modules/subscribepay/src/pay/wxPay.go
  72. 3 2
      src/jfw/modules/subscribepay/src/service/commonAction.go
  73. 13 0
      src/jfw/modules/subscribepay/src/service/payCallback.go
  74. 106 0
      src/jfw/modules/subscribepay/src/service/pdfExportPack.go
  75. 1 1
      src/jfw/modules/subscribepay/src/service/resourcePack.go
  76. 338 338
      src/jfw/modules/subscribepay/src/util/dataExportExcel.go
  77. 271 0
      src/jfw/modules/subscribepay/src/util/pdfSendEmail.go
  78. 5 2
      src/web/staticres/big-member/js/unit_portrayal.js
  79. 1 1
      src/web/staticres/big-member/weixin/css/ent_portrait.css
  80. 4 2
      src/web/staticres/common-module/big-member/js/client_portrayal.js
  81. 13 0
      src/web/staticres/common-module/chart-module/js/chart-common.js
  82. 6 3
      src/web/staticres/common-module/collection/js/ent_portrait.js
  83. 19 0
      src/web/staticres/common-module/common/css/appDownloadfile.css
  84. 214 0
      src/web/staticres/common-module/common/js/appDownloadfile.js
  85. 14 0
      src/web/staticres/common-module/diy-report/css/report-list.css
  86. 5 1
      src/web/staticres/common-module/diy-report/js/report-list.js
  87. 7 0
      src/web/staticres/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css
  88. 40 31
      src/web/staticres/common-module/mobile-portrayal-footer/js/mobile-portrayal-footer.js
  89. BIN
      src/web/staticres/common-module/order-list/image/enterpriseAnalysis.png
  90. BIN
      src/web/staticres/common-module/order-list/image/marketAnalysis.png
  91. BIN
      src/web/staticres/common-module/order-list/image/ownerAnalysis.png
  92. 33 0
      src/web/staticres/common-module/order-list/js/order-detail.js
  93. 77 4
      src/web/staticres/common-module/order-list/js/order-list-config.js
  94. 98 0
      src/web/staticres/common-module/order-list/js/order-list.js
  95. BIN
      src/web/staticres/common-module/pdf/【剑鱼标讯】业主采购分析报告样例.pdf
  96. BIN
      src/web/staticres/common-module/pdf/【剑鱼标讯】企业中标分析报告样例.pdf
  97. BIN
      src/web/staticres/common-module/pdf/【剑鱼标讯】市场分析定制报告样例.pdf
  98. 1 0
      src/web/staticres/common-module/perfect-info/index.css
  99. 48 4
      src/web/staticres/common-module/perfect-info/js/perfect-info.js
  100. 341 0
      src/web/staticres/common-module/portrait/css/downloadpopup.css

+ 3 - 1
src/jfw/filter/pcfilter.go

@@ -37,6 +37,9 @@ func (this *pcFilter) Do() bool {
 		//wx
 		return true
 	}
+	if strings.HasPrefix(string(this.Session.Id()), "JianyuDebug") {
+		return true
+	}
 	//企业搜索
 	if strings.Contains(this.R.RequestURI, "/jylab/entSearch/index.html") ||
 		strings.Contains(this.R.RequestURI, "/swordfish/page_big_pc/ent_portrait/") ||
@@ -75,7 +78,6 @@ func (this *pcFilter) Do() bool {
 	} else {
 		return true
 	}
-
 	http.Redirect(this.W, this.R, href, 302)
 	return false
 }

+ 4 - 3
src/jfw/filter/sesssionKeep.go

@@ -1,13 +1,14 @@
 package filter
 
 import (
-	jybase "app.yhyue.com/moapp/jybase/common"
-	"app.yhyue.com/moapp/jybase/encrypt"
-	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 	"jy/src/jfw/front"
 	"jy/src/jfw/jyutil"
 	"net/http"
 	"strconv"
+
+	jybase "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 )
 
 // SessionKeep 延长登录时间过滤器

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

@@ -32,7 +32,7 @@ var (
 		"areaPack":          {"省份订阅包"},
 		"filePack":          {"附件下载包"},
 		"buyerPortraitPack": {"采购单位画像包"},
-		"docMember":               {"剑鱼文库会员"},
+		"docMember":         {"剑鱼文库会员"},
 	}
 )
 

+ 8 - 2
src/jfw/front/dataPackRouter.go

@@ -13,13 +13,15 @@ type DataPackRouter struct {
 	wxIndex       xweb.Mapper `xweb:"/swordfish/dataPack/myIndex"`     //数据包详情
 	wxCreateOrder xweb.Mapper `xweb:"/swordfish/dataPack/createOrder"` //数据包创建订单
 	wxRecordList  xweb.Mapper `xweb:"/swordfish/dataPack/recordList"`  //数据包详情
+
+	pcDownloadPack xweb.Mapper `xweb:"/front/downloadPack/packDetail"` //pdf下载包
 }
 
 func init() {
 	xweb.AddAction(&DataPackRouter{})
 }
 
-//pc端
+// pc端
 func (this *DataPackRouter) PcIndex() {
 	this.Render("/pc/dataPack/index.html")
 }
@@ -36,7 +38,7 @@ func (this *DataPackRouter) PcPackDetail() {
 	this.Render("/pc/dataPack/packDetail.html")
 }
 
-//wx端
+// wx端
 func (this *DataPackRouter) WxIndex() {
 	this.Render("/weixin/dataPack/index.html")
 }
@@ -48,3 +50,7 @@ func (this *DataPackRouter) WxCreateOrder() {
 func (this *DataPackRouter) WxRecordList() {
 	this.Render("/weixin/dataPack/recordList.html")
 }
+
+func (this *DataPackRouter) PcDownloadPack() {
+	this.Render("/order/pc/reportDownloadPack/detail.html")
+}

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

@@ -836,7 +836,7 @@ func CreateSession(q map[string]interface{}, sess *httpsession.Session, typ stri
 		return false, nil, nil
 	}
 	userid := util.ObjToString(sessionVal["userId"])
-	if pcSessionFlag, ok := config.Sysconfig["pcSessionFlag"].(bool); pcSessionFlag && ok && flag {
+	if pcSessionFlag, ok := config.Sysconfig["pcSessionFlag"].(bool); pcSessionFlag && ok && flag && !strings.HasPrefix(string(sess.Id()), "JianyuDebug") {
 		//无限制登陆用户
 		if util.IntAll(sessionVal["i_unlimited"]) <= 0 {
 			redis.Put("other", jyutil.LoginRedisKey(userid), sess.Id(), 3600*util.IntAllDef(config.Sysconfig["pcSessionTimeout"], 168))

+ 6 - 5
src/jfw/front/frontRouter.go

@@ -1,11 +1,6 @@
 package front
 
 import (
-	"app.yhyue.com/moapp/jybase/common"
-	"app.yhyue.com/moapp/jybase/encrypt"
-	elastic "app.yhyue.com/moapp/jybase/es"
-	"app.yhyue.com/moapp/jybase/redis"
-	"app.yhyue.com/moapp/jypkg/public"
 	"fmt"
 	"jy/src/jfw/config"
 	"jy/src/jfw/jyutil"
@@ -14,6 +9,12 @@ import (
 	"regexp"
 	"strings"
 
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	elastic "app.yhyue.com/moapp/jybase/es"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/public"
+
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
 
 	//"strings"

+ 8 - 6
src/jfw/front/login.go

@@ -1,16 +1,18 @@
 package front
 
 import (
-	"app.yhyue.com/moapp/jybase/date"
 	"fmt"
-	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/config"
 	jutil "jy/src/jfw/jyutil"
 	"log"
+	"net/http"
 	"regexp"
 	"strings"
 	"time"
 
+	"app.yhyue.com/moapp/jybase/date"
+	"github.com/gogf/gf/v2/util/gconv"
+
 	qutil "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/dchest/captcha"
 	"app.yhyue.com/moapp/jybase/encrypt"
@@ -111,7 +113,7 @@ func (l *Login) Login() error {
 			}, `{"s_phone":-1}`, `{"_id":1,"s_password":1}`, false, 0, 1)
 			if ok && user != nil && len(*user) > 0 {
 				if qutil.ObjToString((*user)[0]["s_password"]) == qutil.GetMd5String(password) {
-					ok, _, userInfo := afterLogin(phone, l.Session(), true)
+					ok, _, userInfo := afterLogin(l.Request, phone, l.Session(), true)
 					if ok {
 						result["userInfo"] = userInfo
 						go anonymousLogin(l.Session(), l.Cookie("JYTrustedId"))
@@ -212,7 +214,7 @@ func (l *Login) Login() error {
 						//用户日志保存
 						jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "pc", source, "", gconv.String(l.GetSession("RSource")), gconv.String(sessVal["RSource"]), qutil.GetIp(l.Request), l.UserAgent(), "jybx", "")
 						jy.ClearPhoneIdentSession(l.Session())
-						ok, _, userInfo := afterLogin(phone, l.Session(), false)
+						ok, _, userInfo := afterLogin(l.Request, phone, l.Session(), false)
 						userInfo["isNewUser"] = true
 						nsqPath, _ := config.Sysconfig["nsq"].(string)
 						nsq_topic, _ := config.Sysconfig["nsq_topic"].(string)
@@ -256,7 +258,7 @@ func (l *Login) Login() error {
 						})
 					}
 					jy.ClearPhoneIdentSession(l.Session())
-					ok, _, userInfo := afterLogin(phone, l.Session(), false)
+					ok, _, userInfo := afterLogin(l.Request, phone, l.Session(), false)
 					if ok {
 						result["userInfo"] = userInfo
 						go anonymousLogin(l.Session(), l.Cookie("JYTrustedId"))
@@ -471,7 +473,7 @@ func anonymousLogin(session *httpsession.Session, trustedId string) {
 	//}
 }
 
-func afterLogin(phone string, session *httpsession.Session, fool bool) (bool, *map[string]interface{}, map[string]interface{}) {
+func afterLogin(request *http.Request, phone string, session *httpsession.Session, fool bool) (bool, *map[string]interface{}, map[string]interface{}) {
 	ok, user := getPhoneUser(phone, fool)
 	if !ok {
 		return false, nil, nil

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

@@ -9,12 +9,13 @@ package front
 
 import (
 	"fmt"
-	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/config"
 	"log"
 	"net/url"
 	"time"
 
+	"github.com/gogf/gf/v2/util/gconv"
+
 	"jy/src/jfw/jyutil"
 	. "jy/src/jfw/public"
 

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

@@ -3,7 +3,6 @@ package front
 import (
 	"encoding/base64"
 	"fmt"
-	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/config"
 	"jy/src/jfw/jyutil"
 	"log"
@@ -11,6 +10,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/gogf/gf/v2/util/gconv"
+
 	"app.yhyue.com/moapp/jypkg/public"
 
 	. "app.yhyue.com/moapp/jybase/date"

+ 8 - 7
src/jfw/front/singleLogin.go

@@ -1,6 +1,14 @@
 package front
 
 import (
+	"fmt"
+	"jy/src/jfw/config"
+	"jy/src/jfw/jyutil"
+	"log"
+	"net/url"
+	"strings"
+	"time"
+
 	qutil "app.yhyue.com/moapp/jybase/common"
 	. "app.yhyue.com/moapp/jybase/date"
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
@@ -10,15 +18,8 @@ import (
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
 	. "app.yhyue.com/moapp/jypkg/identity"
 	"app.yhyue.com/moapp/jypkg/public"
-	"fmt"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
-	"jy/src/jfw/config"
-	"jy/src/jfw/jyutil"
-	"log"
-	"net/url"
-	"strings"
-	"time"
 )
 
 type SingleLogin struct {

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

@@ -1,8 +1,6 @@
 package front
 
 import (
-	. "app.yhyue.com/moapp/jybase/date"
-	. "app.yhyue.com/moapp/jybase/mongodb"
 	"encoding/base64"
 	"encoding/json"
 	"fmt"
@@ -17,6 +15,9 @@ import (
 	"strings"
 	"time"
 
+	. "app.yhyue.com/moapp/jybase/date"
+	. "app.yhyue.com/moapp/jybase/mongodb"
+
 	util "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/encrypt"
 	elastic "app.yhyue.com/moapp/jybase/es"

+ 9 - 8
src/jfw/front/websocket.go

@@ -1,14 +1,6 @@
 package front
 
 import (
-	qutil "app.yhyue.com/moapp/jybase/common"
-	. "app.yhyue.com/moapp/jybase/date"
-	"app.yhyue.com/moapp/jybase/encrypt"
-	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
-	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
-	"app.yhyue.com/moapp/jybase/redis"
-	"app.yhyue.com/moapp/jypkg/golang.org/x/net/websocket"
-	"app.yhyue.com/moapp/jypkg/public"
 	"encoding/json"
 	"fmt"
 	. "jy/src/jfw/config"
@@ -18,6 +10,15 @@ import (
 	"strings"
 	"sync"
 	"time"
+
+	qutil "app.yhyue.com/moapp/jybase/common"
+	. "app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/golang.org/x/net/websocket"
+	"app.yhyue.com/moapp/jypkg/public"
 )
 
 // socket对象放在内存中,待rpc回调使用

+ 15 - 0
src/jfw/modules/app/p583.http

@@ -0,0 +1,15 @@
+GET http://127.0.0.1:89/jyapp/m/RVw=
+Content-Type: application/json
+
+{}
+
+###
+POST http://127.0.0.1:89/jyapp/checkSubscribe
+Content-Type: application/json
+
+{
+  "id":"RQ=="
+
+}
+
+###

+ 46 - 12
src/jfw/modules/app/src/active.json

@@ -1,17 +1,51 @@
 {
-	"pullnew":{
-		"startTime": 1567390259,
-		"endTime": 1569982259,
-		"url":"https://pan.baidu.com/s/1alKNc4hzuEK3q4XOFfz5Ow",
-		"password":"j2ks",
-		"desc":"拉新活动"
-	},
-	"doubleEleven":{
-		"active_Start":1504505600,
-		"active_End":1605024000
-	},
+  "pullnew": {
+    "startTime": 1567390259,
+    "endTime": 1569982259,
+    "url": "https://pan.baidu.com/s/1alKNc4hzuEK3q4XOFfz5Ow",
+    "password": "j2ks",
+    "desc": "拉新活动"
+  },
+  "doubleEleven": {
+    "active_Start": 1504505600,
+    "active_End": 1605024000
+  },
   "activateInfo": {
     "name": "激活活动",
-    "endTime":  1725120000
+    "endTime": 1625120000,
+    "appID": "wx37f06c38292f7d82",
+    "envVersion": "trial",
+    "endUrl": "https://mp.weixin.qq.com/s?__biz=Mzk0MjIyMzY2Nw==&mid=2247497288&idx=1&sn=06e3b7145af4d46d5410a340413870c6&chksm=c2c4ce14f5b34702761205555b871b96223a9f6ff4133a3654b3aa804b9024312cc43ff44fd5#rd",
+    "url": "/frontRouter/activity/free/open-mini-program.html",
+    "to": [
+      {
+        "path": {
+          "sub": "/pages/index/index",
+          "unsub": "/pages/article/bidding/index"
+        },
+        "query": {
+          "sub": "url=/jyapp/free/al/%s",
+          "unsub": "id=%s"
+        }
+      },
+      {
+        "path": {
+          "sub": "/pages/index/index",
+          "unsub": "/pages/article/bidding/index"
+        },
+        "query": {
+          "sub": "url=/jyapp/free/al/%s",
+          "unsub": "id=%s"
+        }
+      },
+      {
+        "path": {
+          "default": "/pages/index/index"
+        },
+        "query": {
+          "default": "source=ac"
+        }
+      }
+    ]
   }
 }

+ 18 - 2
src/jfw/modules/app/src/app/config/active.go

@@ -10,8 +10,24 @@ type active struct {
 	Pullnew      *pullnew
 	DoubleEleven *doubleEleven
 	ActivateInfo struct {
-		Name    string `json:"name"`
-		EndTime int64  `json:"endTime"`
+		Name       string `json:"name"`
+		EndTime    int64  `json:"endTime"`
+		AppID      string `json:"appID"`         // 要跳转的小程序appid
+		EnvVersion string `json:"envVersion"`    // 小程序版本
+		EndUrl     string `json:"endUrl"`        // 结束后跳转到
+		Url        string `json:"url,omitempty"` // 跳的地址
+		To         []struct {
+			Path struct {
+				Sub     string `json:"sub,omitempty"`   // 关注
+				Unsub   string `json:"unsub,omitempty"` // 未关注
+				Default string `json:"default,omitempty"`
+			} `json:"path,omitempty"`
+			Query struct {
+				Sub     string `json:"sub,omitempty"`
+				Unsub   string `json:"unsub,omitempty"`
+				Default string `json:"default,omitempty"`
+			} `json:"query,omitempty"`
+		} `json:"to"`
 	} `json:"activateInfo"`
 }
 

+ 2 - 0
src/jfw/modules/app/src/app/filter/loginfilter.go

@@ -37,6 +37,8 @@ var urls = []*regexp.Regexp{
 	regexp.MustCompile("^/jyapp/initialize/whiteList"),
 	regexp.MustCompile("^/jyapp/transit/.*"),
 	regexp.MustCompile("^/jyapp/new/.*"),
+	regexp.MustCompile("^/jyapp/m/.*"),
+	regexp.MustCompile("^/jyapp/checkSubscribe$"),
 }
 
 type loginFilter struct {

+ 110 - 0
src/jfw/modules/app/src/app/front/activity.go

@@ -0,0 +1,110 @@
+package front
+
+import (
+	"app.yhyue.com/moapp/jybase/api"
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"jy/src/jfw/modules/app/src/app/config"
+	"jy/src/jfw/modules/app/src/app/jyutil"
+	"net/url"
+	"time"
+)
+
+type Activity struct {
+	*xweb.Action
+	mini           xweb.Mapper `xweb:"/jyapp/m/(.*)"`         // /min/0013 p583短地址
+	checkSubscribe xweb.Mapper `xweb:"/jyapp/checkSubscribe"` // 是否关注 p583短地址
+}
+
+func init() {
+	xweb.AddAction(&Activity{})
+}
+
+// Mini  p583 用户短信激活短地址
+func (s *Activity) Mini(args string) {
+	if time.Now().Unix() > config.Active.ActivateInfo.EndTime {
+		s.Redirect(config.Active.ActivateInfo.EndUrl)
+		return
+	}
+
+	sidStr := encrypt.SE.DecodeString(args)
+	if sidStr == "" {
+		s.ServeJson(api.NewResult(nil, errors.New("参数异常")))
+		return
+	}
+	if len(sidStr) < 2 {
+		s.ServeJson(api.NewResult(nil, errors.New("参数异常")))
+	}
+	step := common.IntAll(sidStr[len(sidStr)-1:])
+	id := common.IntAll(sidStr[:len(sidStr)-1])
+	encryId := url.QueryEscape(encrypt.SE.EncodeString(sidStr[:len(sidStr)-1]))
+	if step > len(config.Active.ActivateInfo.To) || id == 0 || common.IntAll(id) == 0 {
+		s.ServeJson(api.NewResult(nil, errors.New("参数异常")))
+		return
+	}
+	stepIndex := step - 1 //
+	isFirst, b := jyutil.UpdateActivateCount(common.IntAll(id), step)
+	if !b {
+		s.ServeJson(api.NewResult(nil, errors.New("稍后再试")))
+	}
+	// 获取用户id
+	userId, positionID := jyutil.GetActivateUser(id)
+	// 判断用户关注未关注
+	s.T["appid"] = config.Active.ActivateInfo.AppID
+	s.T["env_version"] = config.Active.ActivateInfo.EnvVersion
+	if config.Active.ActivateInfo.To[stepIndex].Path.Default == "" {
+		if jyutil.IsSubscribe(userId) {
+			s.T["path"] = config.Active.ActivateInfo.To[stepIndex].Path.Sub
+			s.T["query"] = fmt.Sprintf(config.Active.ActivateInfo.To[stepIndex].Query.Sub, encryId)
+		} else {
+			s.T["path"] = config.Active.ActivateInfo.To[stepIndex].Path.Unsub
+			s.T["query"] = fmt.Sprintf(config.Active.ActivateInfo.To[stepIndex].Query.Unsub, encryId)
+		}
+	} else {
+		if isFirst {
+			// 没有点过则送7天会员
+			jyutil.GiveVip(userId, positionID, s.Request.UserAgent())
+		}
+		s.T["path"] = config.Active.ActivateInfo.To[stepIndex].Path.Default
+		s.T["query"] = config.Active.ActivateInfo.To[stepIndex].Query.Default
+	}
+	s.Render(config.Active.ActivateInfo.Url, &s.T)
+	return
+
+}
+
+// CheckSubscribe 是否关注
+func (s *Activity) CheckSubscribe() {
+	defer common.Catch()
+	r := func() api.Result {
+		if s.Method() != "POST" {
+			return api.Result{Data: nil, Error_msg: api.Error_msg_1005}
+		}
+		//接收参数
+		// 查询
+		if string(s.Body()) == "" {
+			return api.Result{Data: nil, Error_msg: api.Error_msg_1003}
+		}
+		param := struct {
+			Id string
+		}{}
+		//接收参数
+		err := json.Unmarshal(s.Body(), &param)
+		if err != nil || param.Id == "" {
+			return api.Result{Data: nil, Error_msg: api.Error_msg_1003}
+		}
+		auId := param.Id
+		id := common.IntAll(encrypt.SE.DecodeString(auId))
+		if id == 0 {
+			return api.Result{Data: nil, Error_msg: api.Error_msg_1003}
+		}
+		userId, _ := jyutil.GetActivateUser(id)
+		status := jyutil.IsSubscribe(common.InterfaceToStr(userId))
+		return api.Result{Data: status}
+	}()
+	s.ServeJson(r)
+}

+ 312 - 0
src/jfw/modules/app/src/app/jyutil/activity.go

@@ -0,0 +1,312 @@
+package jyutil
+
+import (
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/public"
+	"bp.jydev.jianyu360.cn/BaseService/entManageApplication/entity"
+	"bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
+	"database/sql"
+	"encoding/json"
+	"fmt"
+	"go.mongodb.org/mongo-driver/bson"
+	"jy/src/jfw/modules/app/src/jfw/config"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+)
+
+const (
+	TableActivateUser     = "jyactivities.activate_user"  // 活动用户表
+	TableActivateCount    = "jyactivities.activate_count" // 活动用户记录表
+	TableDataexport_order = "jianyu.dataexport_order"     // 订单表
+
+)
+
+var (
+	MobileReg = regexp.MustCompile("(?i)(Android|Mobile|Phone)")
+	stepMap   = map[int]string{
+		1: "first_click",
+		2: "second_click",
+		3: "three_click",
+	}
+)
+
+// UpdateActivateCount 更新访问次数
+func UpdateActivateCount(id int, step int) (isFirst bool, b bool) {
+	field, ok := stepMap[step]
+	if !ok {
+		return false, false
+	}
+	b = public.BaseMysql.ExecTx("更新访问次数", func(tx *sql.Tx) bool {
+		rs := public.BaseMysql.SelectBySqlByTx(tx, fmt.Sprintf("SELECT * FROM %s where au_id=? for update;", TableActivateCount), id)
+		if rs == nil || len(*rs) == 0 {
+			log.Println("未获取到用户信息:", id)
+			return false
+		}
+		linkClick := common.IntAll((*rs)[0][field])
+		// 第三步首次访问的时候送会员
+		if linkClick == 0 {
+			isFirst = true
+		}
+		// 更新次数
+		_, err := public.BaseMysql.ExecBySqlByTx(tx, fmt.Sprintf("update  %s set %s = %s+1,update_date=? where au_id=?", TableActivateCount, field, field), date.NowFormat(date.Date_Full_Layout), id)
+		if err != nil {
+			return false
+		}
+		return true
+	})
+	return
+}
+
+// 获取活动用户信息
+func GetActivateUser(id int) (userId string, positionId string) {
+	rs := public.BaseMysql.SelectBySql(fmt.Sprintf("SELECT user_id,position_id FROM %s where id=? ", TableActivateUser), id)
+	if rs != nil && len(*rs) > 0 {
+		userId = common.InterfaceToStr((*rs)[0]["user_id"])
+		positionId = common.InterfaceToStr((*rs)[0]["position_id"])
+	}
+	return
+}
+
+// IsSubscribe 获取用户是否关注
+func IsSubscribe(mgoId string) bool {
+	user, ok := mongodb.FindById("user", mgoId, `{"i_ispush":1}`)
+	if ok && user != nil {
+		if (*user)["_id"] == nil || common.IntAllDef((*user)["i_ispush"], 1) == 0 {
+			return false
+		} else {
+			return true
+		}
+	}
+	return false
+}
+
+// GiveVip 送7天超级订阅会员 如果已经是付费用户则生续费订单  (个人身份)
+func GiveVip(mgoUserId string, positionId string, ua string) {
+	// 查用户信息
+	userData, _ := public.MQFW.FindById("user", mgoUserId, `{"i_vip_status":1,"l_vip_starttime":1,"l_vip_endtime":1,"s_phone":1,"s_m_phone":1,"o_vipjy":1,"o_jy":1,"base_user_id":1}`)
+	// 不是超级订阅
+	if userData == nil || *userData == nil || len(*userData) == 0 {
+		log.Println("未获取到用户信息")
+		return
+	}
+	i_vip_status := common.IntAll((*userData)["i_vip_status"])
+	l_vip_endtime := common.Int64All((*userData)["l_vip_endtime"])
+	log.Println("查询到用户信息:", mgoUserId, l_vip_endtime, i_vip_status)
+	phone := common.InterfaceToStr((*userData)["s_phone"])
+	if phone == "" {
+		phone = common.InterfaceToStr((*userData)["s_m_phone"])
+	}
+	vipType := 0 // 默认是新购
+	area := map[string]any{"北京": []any{}}
+	buyset := &entity.SubvipBuySet{}
+	startTime := time.Now()
+	o_vipjy := common.ObjToMap((*userData)["o_vipjy"])
+	o_jy := common.ObjToMap((*userData)["o_jy"])
+	if i_vip_status > 0 {
+		vipType = 1 // 续费
+		startTime = time.Unix(l_vip_endtime, 0)
+		if o_vipjy != nil {
+			if common.ObjToMap((*o_vipjy)["o_area"]) != nil {
+				area = *common.ObjToMap((*o_vipjy)["o_area"])
+			}
+			if common.ObjToMap((*o_vipjy)["o_buyset"]) != nil {
+				o_buyset := (*o_vipjy)["o_buyset"]
+				marshal, _ := json.Marshal(o_buyset)
+				err := json.Unmarshal(marshal, &buyset)
+				if err != nil {
+					log.Println("buyset反序列化失败", err)
+				}
+			}
+		}
+	} else {
+		buyset = &entity.SubvipBuySet{
+			Upgrade:         1,
+			AreaCount:       1,
+			NewCitys:        []int{},
+			BuyerclassCount: -1,
+		}
+	}
+	endTime := startTime.AddDate(0, 0, 7)
+	//  生订单
+	var (
+		product = "VIP订阅"
+		now     = time.Now()
+		filter  = entity.VipSimpleMsg{
+			Area:       &area,
+			Industry:   []string{},
+			Cyclecount: 7,
+			Cycleunit:  3,
+			Badge:      "give",
+			NewBuyset:  buyset,
+		}
+		filterStr, _ = json.Marshal(filter)
+		orderChannel = func() (way string) {
+			if ua != "" {
+				if MobileReg.MatchString(ua) {
+					if strings.Index(strings.ToLower(ua), "micromessenger") > -1 {
+						way = "xdqd02"
+					} else {
+						way = "xdqd03"
+					}
+				} else {
+					way = "xdqd01"
+				}
+			}
+			return
+		}() //下单渠道 剑鱼PC[xdqd01]、剑鱼微信[xdqd02]、剑鱼APP[xdqd03]
+	)
+	orderCode := VarOrderCode.Get()
+	insertM := map[string]interface{}{
+		"order_money":          0, //订单金额 单位分
+		"order_status":         1, //订单状态 0未支付 1已支付
+		"service_status":       1, //服务状态,1已提供服务及已经下载,0未服务
+		"user_phone":           phone,
+		"order_code":           orderCode,
+		"create_time":          date.FormatDate(&now, date.Date_Full_Layout),
+		"original_price":       0,
+		"user_id":              mgoUserId,
+		"filter":               string(filterStr),
+		"distribution_channel": "x010",       //销售渠道>线上直销-剑鱼平台[x010]
+		"order_channel":        orderChannel, //下单渠道
+		"audit_status":         3,            //默认审核通过
+		"user_openid":          "",
+		"vip_starttime":        date.FormatDate(&startTime, date.Date_Full_Layout),
+		"vip_endtime":          date.FormatDate(&endTime, date.Date_Full_Layout),
+		"vip_type":             vipType,
+		"is_backstage_order":   0,
+		"product_type":         product,
+	}
+	// 保存订单
+	public.Mysql.Insert(TableDataexport_order, insertM)
+	// 开通权益
+	if i_vip_status > 0 { // 续费
+		public.MQFW.UpdateById("user", mgoUserId, map[string]any{"$set": map[string]any{
+			"l_vip_endtime": endTime.Unix()},
+		})
+	} else {
+		// 新购买
+		StartSubVip(mgoUserId, o_vipjy, o_jy, filter, endTime, 1)
+	}
+	go config.Middleground.UserCenter.WorkDesktopClearUserInfo(pb.WorkDesktopClearUserInfoReq{
+		PositionId: positionId,
+		AppId:      "10000",
+	})
+}
+
+// 初始化超级订阅
+func StartSubVip(mgoUserID string, vip_jy *map[string]interface{}, o_jy *map[string]interface{}, vMsg entity.VipSimpleMsg, endTime time.Time, status int) (err error) {
+	if o_jy == nil || len(*o_jy) == 0 {
+		*o_jy = map[string]interface{}{}
+	}
+	vMsg.Area = GetUserArea(vMsg.NewBuyset.AreaCount, o_jy)
+	set := map[string]interface{}{
+		"o_vipjy.i_trial":      -1,                //已激活试用
+		"o_vipjy.o_area":       vMsg.Area,         //设置地区
+		"o_vipjy.o_buyset":     vMsg.NewBuyset,    //购买内容 城市、省份、行业数量
+		"l_vip_starttime":      time.Now().Unix(), //开始时间
+		"l_vip_endtime":        endTime.Unix(),    //结束时间
+		"i_vip_status":         status,            //1试用 2正式
+		"i_vip_expire_tip":     0,                 //消息提示初始化
+		"o_vipjy.a_buyerclass": []string{},
+	}
+	if status > 0 {
+		//是否已经设置过行业
+		if !BuyerClassStatus(vip_jy) {
+			set["o_vipjy.a_buyerclass"] = vMsg.Industry //设置行业
+		}
+		if !Compatible.Update(mgoUserID,
+			bson.M{"$set": set}) {
+			err = fmt.Errorf("开启超级订阅异常")
+			return
+		}
+		if vip_jy == nil || len(*vip_jy) == 0 {
+			*vip_jy = map[string]interface{}{}
+		}
+		//初始化vip订阅关键词
+		if err = MergeKws(mgoUserID, *vip_jy); err != nil {
+			return
+		}
+	}
+	redis.Del("other", "p1_indexMessage_"+mgoUserID) //清除redis中vip状态
+	return
+}
+
+// 获取用户设置的区域
+// A.购买超级订阅前是免费用户:则区域默认为免费订阅区域,免费区域为空则默认为北京;
+// B.购买超级订阅前是省份订阅包用户:则区域默认为省份订阅包区域,如超级订阅可订阅省份<省份订阅包可用省份,则随机展示省份订阅包的部分区域;
+func GetUserArea(areaCount int, ojy *map[string]interface{}) (area *map[string]interface{}) {
+	if areaCount == -1 {
+		area = &map[string]interface{}{}
+		return
+	}
+	area = &map[string]interface{}{"北京": []string{}} //默认
+	i_ppstatus := common.IntAll((*ojy)["i_ppstatus"])
+	o_area_p := common.ObjToMap((*ojy)["o_area_p"])
+	if i_ppstatus > 0 && o_area_p != nil && len(*o_area_p) > 0 {
+		if len(*o_area_p) > areaCount {
+			area = &map[string]interface{}{}
+			for k, v := range *o_area_p {
+				(*area)[k] = v
+				if len(*area) == areaCount {
+					break
+				}
+			}
+		} else {
+			area = o_area_p
+		}
+		return
+	}
+	// 判断免费订阅
+	o_area := common.ObjToMap((*ojy)["o_area"])
+	if o_area != nil && len(*o_area) > 0 {
+		area = o_area
+	}
+	return
+}
+
+// 是否已经设置过订阅设置 true 已设置  fasle未设置
+func BuyerClassStatus(vipjy *map[string]interface{}) bool {
+	mData := vipjy
+	if mData == nil || len(*mData) == 0 {
+		return false
+	}
+	ovipjy, _ := (*mData)["o_vipjy"].(map[string]interface{})
+	if ovipjy != nil {
+		if ovipjy["a_buyerclass"] != nil {
+			return true
+		}
+	}
+	return false
+}
+
+// 初始化vip订阅关键词
+func MergeKws(mgoUserId string, o_vipjy map[string]interface{}) (err error) {
+	defer common.Catch()
+	a_items, _ := o_vipjy["a_items"].([]interface{})
+	m := map[string]interface{}{}
+	if a_items == nil { //首次
+		m = map[string]interface{}{"o_vipjy.i_matchway": 1, "o_vipjy.i_ratemode": 1, "o_vipjy.i_wxpush": 1, "o_vipjy.i_apppush": 1, "o_vipjy.a_infotype": []string{}, "o_vipjy.a_items": []string{}, "o_vipjy.l_modifydate": time.Now().Unix()}
+	} else {
+		//免费用户试用超级订阅
+		wxpush := o_vipjy["i_wxpush"]
+		apppush := o_vipjy["i_apppush"]
+		if wxpush == nil && apppush == nil {
+			m = map[string]interface{}{"o_vipjy.i_ratemode": 1, "o_vipjy.i_wxpush": 1, "o_vipjy.i_apppush": 1, "o_vipjy.l_modifydate": time.Now().Unix()}
+		}
+	}
+	if m != nil && len(m) > 0 {
+		if b := Compatible.Update(mgoUserId, map[string]interface{}{
+			"$set": m,
+		}); !b {
+			err = fmt.Errorf("初始化vip订阅关键词 异常")
+		}
+	} else {
+		fmt.Println("不用设置关键词")
+	}
+
+	return
+}

+ 93 - 93
src/jfw/modules/app/src/config.json

@@ -127,112 +127,112 @@
       "user": "public03@topnet.net.cn"
     }
   ],
-"policy": {
-"title": "使用许可协议和隐私政策",
-"content": "欢迎使用剑鱼标讯!\n我们依据最新法规及监管政策要求,更新了《剑鱼标讯用户使用许可协议》和《剑鱼标讯隐私政策》,在您使用剑鱼标讯前,请仔细阅读并充分了解。\n如你同意《剑鱼标讯用户使用许可协议》和《剑鱼标讯隐私政策》,请点击“同意”并开始使用我们的产品和服务,我们会全力保护你的个人信息安全。",
-"href": [
-	"jyapp/free/staticPage/privacy_rules_client.html",
-	"jyapp/free/staticPage/permission_rules_client.html"
-],
-"name": [
-	"《剑鱼标讯隐私政策》",
-	"《剑鱼标讯用户使用许可协议》"
-]
-},
-"tencentcloud": {
-"appid": "TIDAXUV9",
-"secretKey": "c7KJhtLMF805EeImBcOsoygu8KkdOrAfIaSU9SqAh8a2aiCgc69EfsaLM5EQcadF",
-"version": "1.0.0"
-},
-"termValidity": 3600,
-"uploadPath": "./web/staticres/jyapp/res/",
-"appConfig":{
-"pushGrpcServer":"192.168.20.114:5565",
-"pushGrpcHeartBeat":3
-},
-  "redisSessionLockSize":20,
-  "nsq":"192.168.3.240:4260",
+  "policy": {
+    "title": "使用许可协议和隐私政策",
+    "content": "欢迎使用剑鱼标讯!\n我们依据最新法规及监管政策要求,更新了《剑鱼标讯用户使用许可协议》和《剑鱼标讯隐私政策》,在您使用剑鱼标讯前,请仔细阅读并充分了解。\n如你同意《剑鱼标讯用户使用许可协议》和《剑鱼标讯隐私政策》,请点击“同意”并开始使用我们的产品和服务,我们会全力保护你的个人信息安全。",
+    "href": [
+      "jyapp/free/staticPage/privacy_rules_client.html",
+      "jyapp/free/staticPage/permission_rules_client.html"
+    ],
+    "name": [
+      "《剑鱼标讯隐私政策》",
+      "《剑鱼标讯用户使用许可协议》"
+    ]
+  },
+  "tencentcloud": {
+    "appid": "TIDAXUV9",
+    "secretKey": "c7KJhtLMF805EeImBcOsoygu8KkdOrAfIaSU9SqAh8a2aiCgc69EfsaLM5EQcadF",
+    "version": "1.0.0"
+  },
+  "termValidity": 3600,
+  "uploadPath": "./web/staticres/jyapp/res/",
+  "appConfig": {
+    "pushGrpcServer": "192.168.20.114:5565",
+    "pushGrpcHeartBeat": 3
+  },
+  "redisSessionLockSize": 20,
+  "nsq": "192.168.3.240:4260",
   "nsq_topic": "jy_event",
-  "accountMergeOnline":"2021-04-07 12:00:00",
+  "accountMergeOnline": "2021-04-07 12:00:00",
   "bidSearchOldUserLimit": 1626105600,
   "contextOldVipLimit": 1664553600,
-  "firstBindPop":3,
-  "maxBindPop":8,
-  "bindPopRedis":"merge",
-  "phoneFilterFlag":true,
-  "optimalTime":"2021-08-03 12:00:00",
-  "criticality":2,
+  "firstBindPop": 3,
+  "maxBindPop": 8,
+  "bindPopRedis": "merge",
+  "phoneFilterFlag": true,
+  "optimalTime": "2021-08-03 12:00:00",
+  "criticality": 2,
   "canReadNotice": 3,
-  "namePrefix":"JY_%s",
-  "smsServiceRpc":"127.0.0.1:932",
+  "namePrefix": "JY_%s",
+  "smsServiceRpc": "127.0.0.1:932",
   "searchTypeSwitch": true,
-  "baseUserFilterFlag":true,
-  "userCenterApi":"https://web-zxl.jydev.jianyu360.com",
+  "baseUserFilterFlag": true,
+  "userCenterApi": "https://web-zxl.jydev.jianyu360.com",
   "freeProjectFocus": 10,
-  "detailMosaicTxt":"略",
-  "needMosaic":{
-    "projectname":true,
-    "projectcode":true,
-    "budget":true,
-    "bidamount":true,
-    "buyer":false,
-    "buyerperson":true,
-    "buyertel":true,
-    "buyeraddr":true,
-    "agency":true,
-    "agencyperson":true,
-    "agencytel":true,
-    "agencyaddr":true,
-    "winner":true,
-    "s_winner":true,
-    "winnerperson":true,
-    "winnertel":true,
-    "winneraddr":true,
-    "docstarttime":true,
-    "docendtime":true,
-    "bidendtime":true,
-    "bidstarttime":true,
-    "bidopentime":true,
-    "bidopenaddress":true,
-    "contractcode":true,
-    "signaturedate":true,
-    "purchasinglist":true,
-    "item":true,
-    "purchasing":true,
-    "itemname":true,
-    "brandname":true,
-    "specs":true,
-    "model":true,
-    "unitname":true,
-    "dimensions":true,
-    "number":true,
-    "unitprice":true,
-    "totalprice":true,
-    "guaranteetime":true,
-    "orderno":true,
-    "procurementlist":true,
-    "projectscope":true,
-    "reserved_amount":true,
-    "expurasingtime":true,
-    "winnerMap":true
+  "detailMosaicTxt": "略",
+  "needMosaic": {
+    "projectname": true,
+    "projectcode": true,
+    "budget": true,
+    "bidamount": true,
+    "buyer": false,
+    "buyerperson": true,
+    "buyertel": true,
+    "buyeraddr": true,
+    "agency": true,
+    "agencyperson": true,
+    "agencytel": true,
+    "agencyaddr": true,
+    "winner": true,
+    "s_winner": true,
+    "winnerperson": true,
+    "winnertel": true,
+    "winneraddr": true,
+    "docstarttime": true,
+    "docendtime": true,
+    "bidendtime": true,
+    "bidstarttime": true,
+    "bidopentime": true,
+    "bidopenaddress": true,
+    "contractcode": true,
+    "signaturedate": true,
+    "purchasinglist": true,
+    "item": true,
+    "purchasing": true,
+    "itemname": true,
+    "brandname": true,
+    "specs": true,
+    "model": true,
+    "unitname": true,
+    "dimensions": true,
+    "number": true,
+    "unitprice": true,
+    "totalprice": true,
+    "guaranteetime": true,
+    "orderno": true,
+    "procurementlist": true,
+    "projectscope": true,
+    "reserved_amount": true,
+    "expurasingtime": true,
+    "winnerMap": true
   },
-  "detailMosaic":"登录即可免费查看",
-  "detailNeedMosaic":{
-    "buyerperson":true,
-    "buyertel":true,
-    "winnerperson":true,
-    "winnertel":true,
-    "agencyperson":true,
-    "agencytel":true,
-    "budget":true,
-    "bidamount":true
+  "detailMosaic": "登录即可免费查看",
+  "detailNeedMosaic": {
+    "buyerperson": true,
+    "buyertel": true,
+    "winnerperson": true,
+    "winnertel": true,
+    "agencyperson": true,
+    "agencytel": true,
+    "budget": true,
+    "bidamount": true
   },
   "keepShowRedSpot": true,
   "detail_element": [
     "table",
     "div"
   ],
-  "purchaseMosaic":{
+  "purchaseMosaic": {
     "projectname": true,
     "bidamount": true,
     "budget": true,

+ 2 - 1
src/jfw/modules/app/src/go.mod

@@ -6,6 +6,7 @@ require (
 	app.yhyue.com/moapp/jybase v0.0.0-20240412015757-6d8429bb4dae
 	app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545
 	app.yhyue.com/moapp/jypkg v1.21.10
+	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20231226074509-942d80dc34eb
 	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.18
 	github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67
 	github.com/gogf/gf/v2 v2.7.0
@@ -17,8 +18,8 @@ require (
 	app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d // indirect
 	app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547 // indirect
 	app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736 // indirect
+	app.yhyue.com/moapp/jyResourcesCenter v0.0.0-20231024011103-8a2aacdbbd3e // indirect
 	app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 // indirect
-	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20231226074509-942d80dc34eb // indirect
 	bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2 // indirect
 	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843 // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 // indirect

+ 5 - 0
src/jfw/modules/app/src/go.sum

@@ -5,6 +5,8 @@ app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547 h1:cCmWQW8D
 app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547/go.mod h1:JvIs8uKjdT963+7JnZGIEcL4ctBiBjwkoz0kNyigE78=
 app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736 h1:7Vl3qq1nJZyRQNyMDoCTC14ScKABZqbUmJP0WpOLnIQ=
 app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736/go.mod h1:NEkVbas7w0Lg4/BPoN4rkl808q4OKv7Bk5lwTXvOThU=
+app.yhyue.com/moapp/jyResourcesCenter v0.0.0-20231024011103-8a2aacdbbd3e h1:bUeBEkJ7H4t80sHndLBxFkvK+25mJ6ab2cPcAMN94ao=
+app.yhyue.com/moapp/jyResourcesCenter v0.0.0-20231024011103-8a2aacdbbd3e/go.mod h1:rJkLX9AT0W53O03w6LnCK8q4djR1tfVtvr8jTNGK8nY=
 app.yhyue.com/moapp/jy_docs v1.1.1/go.mod h1:54sK98Z5tpMFd2aPLN1IRfEyV3zpFRyFxKj6oi2C5/Q=
 app.yhyue.com/moapp/jybase v0.0.0-20210322021809-141cc2c37946/go.mod h1:29ShuI8y7qEyg2KviHSx1iamiCioBKdTMm2ndVzWAhk=
 app.yhyue.com/moapp/jybase v0.0.0-20220415064050-37ce64b3e2d4/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
@@ -1119,6 +1121,7 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogf/gf/v2 v2.0.6/go.mod h1:8uYzw7qNzuq8vrhVlWke1b1925FFqOJIgmyYW1sr/0M=
+github.com/gogf/gf/v2 v2.5.5/go.mod h1:17K/gBYrp0bHGC3XYC7bSPoywmZ6MrZHrZakTfh4eIQ=
 github.com/gogf/gf/v2 v2.7.0 h1:CjxhbMiE7oqf6K8ZtGuKt3dQEwK4vL6LhiI+dI7tJGU=
 github.com/gogf/gf/v2 v2.7.0/go.mod h1:Qu8nimKt9aupJQcdUL85tWF4Mfxocz97zUt8UC4abVI=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -1436,6 +1439,7 @@ github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuz
 github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
 github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o=
 github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk=
+github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -1461,6 +1465,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=

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

@@ -400,7 +400,7 @@
     bottom: 0;
     width: 0.8rem;
     border-bottom: 1.5px solid #2ABED1;
-    z-index: 99999999;
+    z-index: 99;
 }
 
 .top-switch div:not(active) {

+ 5 - 2
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js

@@ -5,6 +5,8 @@ var vNode = {
     vipComponent: vipComponent,
     hisproComponent: hisproComponent,
     forwardshare: vmForward,
+    mobilePortrayalFooter:mobilePortrayalFooter,
+    downloadpopup: downloadpopup,
 
   },
   data () {
@@ -189,7 +191,8 @@ var vNode = {
       // 用户是否登录
       isLogin: false,
       // 是否是免费用户
-      isFree: false
+      isFree: false,
+      balance:0
     }
   },
   created: function () {
@@ -656,7 +659,7 @@ var vNode = {
       var _this = this
       var urls = ''
       // 判断专家版、智慧版; 商机版和自定义版时判断是不是超级订阅
-      if (_this.powerInfo.memberStatus > 0 && _this.powerInfo.power.indexOf(13) > -1) {
+      if (_this.powerInfo.memberStatus > 0 && (_this.powerInfo.power.indexOf(13) > -1  || _this.powerInfo.power.indexOf(4) > -1)) {
         urls = '/bigmember/portrait/winner/getNewMsg'
       }
       // else if (_this.powerInfo.memberStatus > 2) {

+ 1 - 1
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis_history.js

@@ -2,7 +2,7 @@ var vm = new Vue({
   delimiters: ['${', '}'],
   el: '#analysis',
   components: {
-    reportListMobileComponent: reportListMobileComponent
+    reportListMobileComponent: reportListMobileComponent,
   },
   data: {
     sessStorageKey: '$data-report_analysis_history',

+ 7 - 2
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js

@@ -7,7 +7,8 @@ var vNode = {
     hisproComponent: hisproComponent,
     buyerExample: buyerExample,
     forwardshare: vmForward,
-    mobilePortrayalFooter:mobilePortrayalFooter
+    mobilePortrayalFooter:mobilePortrayalFooter,
+    downloadpopup: downloadpopup,
   },
   data () {
     // 修改柱状条颜色为渐变色
@@ -176,7 +177,10 @@ var vNode = {
       follow:false, // 是否监控
       allpower:{},
       // 页面滚动距离
-      pageScrollTop: 0
+      pageScrollTop: 0,
+      // 下载弹窗需要用的参数
+        portraitName:'',
+        balance:0, //定制下载余额
     }
   },
   computed: {
@@ -320,6 +324,7 @@ var vNode = {
   },
   created () {
     this.buyer.name = decodeURIComponent(utils.getParam('entName'))
+    this.portraitName = decodeURIComponent(utils.getParam('entName'))
     this.getUserSimpleInfo()
     this.restore = this.reStoreState()
     setTimeout(() => {

+ 5 - 1
src/jfw/modules/app/src/web/templates/big-member/page_client_portrayal.html

@@ -24,6 +24,7 @@
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/css/client_portrayal.css?v={{Msg "seo" "version"}}' />
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/forward-share/css/forward.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css?v={{Msg "seo" "version"}}'/>
+  <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/portrait/css/downloadpopup.css?v={{Msg "seo" "version"}}' />
   <style>
     .skeleton{
       height: 100%;
@@ -574,8 +575,10 @@
         </van-tab>
       </van-tabs>
     </div>
+       <!-- 下载弹窗 -->
+    <downloadpopup ref="downloadpopup" :type="'unit'" :data="{'power':!noAuth,'portraitName':buyer.name,'searchcount':dt.total,'allmoney':statistics.buyerScale,'allcount':statistics.buyerCount,'otherone':statistics.winnerCount,'othertwo':statistics.otherWinner,balance}"></downloadpopup>
     <!-- 底部按钮组件 -->
-    <mobile-portrayal-footer ref="portrayalFooter" @monitorclick="changeFollowState('g')" @claimclick="changeClaimState" :islogin="true" :monitorshow="true" :monitor="follow" :params="clientParams" :shareshow="true" :claimshow="claimShow" :claim="claim" :allpower="powerInfo"></mobile-portrayal-footer>
+    <mobile-portrayal-footer ref="portrayalFooter" @monitorclick="changeFollowState('g')" @claimclick="changeClaimState" :downshow="true" :islogin="true" :monitorshow="true" :monitor="follow" :params="clientParams" :downshow="true" :shareshow="true" :claimshow="claimShow" :claim="claim" :allpower="powerInfo"></mobile-portrayal-footer>
       <!--客服组件-->
       <customer-corner-component :scroll-status="pageScrollTop < 60" bottom-position="12%"></customer-corner-component>
   </div>
@@ -615,6 +618,7 @@
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/keep-tags/keep-ent-tags-template.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/forward-share/js/forward.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/portrait/js/downloadpopup.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module//mobile-portrayal-footer/js/mobile-portrayal-footer.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/js/client_portrayal.js?v={{Msg "seo" "version"}}11'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/customer-corner/mobile-template.js?v={{Msg "seo" "version"}}'></script>

+ 21 - 4
src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait.html

@@ -21,6 +21,8 @@
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mainSearch/css/j-icons.css?v={{Msg "seo" "version"}}' />
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/forward-share/css/forward.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/dataExport/css/popup-data-export.css?v={{Msg "seo" "version"}}'/>
+  <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css?v={{Msg "seo" "version"}}'/>
+  <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/portrait/css/downloadpopup.css?v={{Msg "seo" "version"}}' />
   <!--E-当前页面的css资源-->
 </head>
 <style>
@@ -126,10 +128,10 @@
     <div class="j-header ent-header">
       <span class="j-icon icon-company"></span>
       <span class="ent-title">${ entInfo.name }</span>
-      <span class="j-icon" :class="!!entInfo.follow ? 'icon-favorite' : 'icon-add-favorite'"
+      <!-- <span class="j-icon" :class="!!entInfo.follow ? 'icon-favorite' : 'icon-add-favorite'"
             @click="changeFollowState" v-if="!isLogin || (entInfo.followSearchFinish && entInfo.entExist)"></span>
       <van-loading v-if="isLogin && !entInfo.followSearchFinish" size="24px"></van-loading>
-      <forwardshare style="margin-left: .32rem;" :params="entParams" :show-text="false" v-if="isLogin" ></forwardshare>
+      <forwardshare style="margin-left: .32rem;" :params="entParams" :show-text="false" v-if="isLogin" ></forwardshare> -->
     </div>
     <section class="tabs-container">
       <div class="tabs-list bg-white" :class="{ transparent: pageState.transparent }">
@@ -336,10 +338,10 @@
                   </div>
                 </li>
                 <li class="show-more clickable"
-                    v-if="topProject.showGetNextButton && (isMemberAndSvip || canFreeTrial) && topProject.count > 3 && noShowTip"
+                    v-if="(topProject.showGetNextButton && (isMemberAndSvip || canFreeTrial) && topProject.count > 3 && noShowTip) || powerInfo.power.indexOf(4) > -1"
                     @click="goToFilterProjectNews">查看更多
                 </li>
-                <li v-if="(isFree && !canFreeTrial) || updateVipStatus || customerServiceStatus" class="dt-text-tips light-bg">
+                <li v-if="powerInfo.power.indexOf(4) == -1 && ((isFree && !canFreeTrial) || updateVipStatus || customerServiceStatus)" class="dt-text-tips light-bg">
                   免费用户支持查看最近30条招标动态,数据更新频率为每周1次,最近更新时间为${topProject.updateTime},您可
                   <!-- 免费用户 -->
                   <span class="highlight-text" v-if="(isFree && !canFreeTrial)" @click="onDtTextClick('buy')">开通超级订阅实时查看更多数据</span>
@@ -658,6 +660,19 @@
         </div>
       </div>
     </div>
+               <!-- 下载弹窗 -->
+               <downloadpopup ref="downloadpopup" :type="'ent'" :data="{
+                'power':!getStatus,
+                'portraitName':entInfo.name ,
+                'searchcount':topProject.total,
+                'allmoney':entPortraitInfo.bidamount_count ? utils.moneyUnit(entPortraitInfo.bidamount_count) : '--',
+                'allcount':entPortraitInfo.project_count ? entPortraitInfo.project_count + '个' : '--',
+                'otherone':entPortraitInfo.area_count ? entPortraitInfo.area_count + '个' : '--',
+                'othertwo':entPortraitInfo.buyer_count ? entPortraitInfo.buyer_count + '个' : '--',balance}">
+                 </downloadpopup>
+                <!-- 底部按钮组件 -->
+                <mobile-portrayal-footer ref="portrayalFooter":monitorshow="entInfo.followSearchFinish && entInfo.entExist" :monitor="!!entInfo.follow" @monitorclick="changeFollowState" :custom-monitor="true"  :downshow="true" :islogin="isLogin" :params="entParams" :shareshow="true">
+                </mobile-portrayal-footer>
     <popup-data-export ref="popup_dataExport" @next="next_export"></popup-data-export>
   </div>
   <div id="jyKeepComponent">
@@ -684,6 +699,8 @@
 </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}}/common-module/portrait/js/downloadpopup.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module//mobile-portrayal-footer/js/mobile-portrayal-footer.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/forward-share/js/forward.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>

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

@@ -84,7 +84,7 @@
     }
     .service-map{
       display: flex;
-      align-items: center;
+      /* align-items: center; */
       border-bottom: 1px solid #E6E6E6;
     }
     .service-table .first {
@@ -333,7 +333,10 @@
                             }
                             if (level.num) {
                               buchongbaoHtml += '<div class="third">' + level.num  + '</div></div>'
-                            } else {
+                            } else if(level.Tworows_text && level.Tworows_desc){ // 分析相关产品显示报告下载份数
+                                buchongbaoHtml += '<div class="third"><div><span>'+level.Tworows_text+'</span><span class="jy-icon-tick"></span><br><span>'+level.Tworows_desc+'<span></div></div></div>'
+
+                            } else{
                               buchongbaoHtml += '<div class="third"><span class="jy-icon-tick"></span></div></div>'
                             }
                           }

+ 643 - 603
src/jfw/modules/app/src/web/templates/big-member/page_report_analysis.html

@@ -1,689 +1,729 @@
 <!DOCTYPE html>
 <html lang="zh-CN">
+
 <head>
     <!--引入公共资源头部-->
     {{include "/big-member/meta.html"}}
-    <title>市场分析报告</title>
+    <title>市场分析定制报告</title>
     <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/report-analysis/css/report_analysis.css?v={{Msg "seo" "version"}}1' />
-    <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/filter/css/project_header.css?v={{Msg "seo" "version"}}' />
+    <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/report-analysis/css/report_analysis.css?v={{Msg "seo" "version"}}1' />
+    <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/filter/css/project_header.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet"
+        href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/css/downloadpopup.css?v={{Msg "seo" "version"}}' />
+
     <style>
+        
         /* fix: --- 弹窗组件不能显示底部问题  */
         .report-popup .j-main.unitTab {
             height: unset;
         }
+
         .collection .unitTab {
             flex: 1;
         }
-        .example-title{
-        padding: .32rem .32rem .12rem;
-        font-size: .36rem;
-        line-height: .52rem;
-        color: #171826;
-        font-weight: bold;
-        background-color: #fcfcfd;
-      }
-      .vip_openDialog{
-        margin-top: 0.92rem 0 .6rem;
-        width: 6.06rem;
-        background: url(/jyapp/big-member/image/openVip.png) no-repeat;
-        background-size: 100% 100%;
-        box-sizing: border-box;
-      }
-      .vip_openDialog .goBtn{
-        margin-bottom: .48rem;
-      }
-      .vip_extend{
-        padding: .16rem 0 0;
-        line-height: .4rem;
-        color: #171826;
-      }
-      .vip_component {
-        margin-top: .16rem;
-        flex-direction: column;
-      }
 
-      .vip_component .example-title {
-        width: 100%;
-        min-height: .96rem;
-        background: #fcfcfd;
-        font-size: .36rem;
-      }
-      .vip_component .chart_com{
-        width: 100%;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        height: inherit;
-      }
+        .example-title {
+            padding: .32rem .32rem .12rem;
+            font-size: .36rem;
+            line-height: .52rem;
+            color: #171826;
+            font-weight: bold;
+            background-color: #fcfcfd;
+        }
+
+        .vip_openDialog {
+            margin-top: 0.92rem 0 .6rem;
+            width: 6.06rem;
+            background: url(/jyapp/big-member/image/openVip.png) no-repeat;
+            background-size: 100% 100%;
+            box-sizing: border-box;
+        }
+
+        .vip_openDialog .goBtn {
+            margin-bottom: .48rem;
+        }
+
+        .vip_extend {
+            padding: .16rem 0 0;
+            line-height: .4rem;
+            color: #171826;
+        }
+
+        .vip_component {
+            margin-top: .16rem;
+            flex-direction: column;
+        }
+
+        .vip_component .example-title {
+            width: 100%;
+            min-height: .96rem;
+            background: #fcfcfd;
+            font-size: .36rem;
+        }
+
+        .vip_component .chart_com {
+            width: 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: inherit;
+        }
+
         /* fix: --- end */
     </style>
 </head>
 
 <body>
-<div class="j-container">
-    {{include "/big-member/header.html"}}
-    <div class="j-main" id="analysis" v-cloak>
-        <div class="j-container">
-            <van-tabs
-                class="analysis-tab"
-                :title-active-color="tabConf.titleActiveColor"
-                :title-inactive-color="tabConf.titleInactiveColor"
-                :line-width="tabConf.lineWidth"
-                :color="tabConf.color"
-                :before-change="beforeTabChange"
-                v-model="tabActiveName">
-                <van-tab
-                    v-for="(tab, index) in tabList"
-                    :key="index"
-                    :title="tab.label"
-                    :name="tab.name"></van-tab>
-            </van-tabs>
-            <section v-show="tabActiveName === 'analysis'" class="j-main analysis-content">
-                <div class="j-container search-filters bg-white" v-show="!rid">
-                    <div class="j-main">
-                        <div class="height8">height8</div>
-                        <div class="filters-title pd-lr16">
-                            <span>分析条件</span>
-                        </div>
-                        <van-cell-group class="filters-list">
-                            <van-cell center title="分析内容" is-link value-class="ellipsis" :value="resolveSelected('keys')" @click="clickCell('keys')"></van-cell>
-                            <van-cell center title="匹配方式" is-link value-class="ellipsis" :value="resolveSelected('matchway')" @click="clickCell('matchway')"></van-cell>
-                            <van-cell center title="区域" is-link value-class="ellipsis" :value="resolveSelected('area')" @click="clickCell('area')"></van-cell>
-                            <van-cell center title="行业" is-link value-class="ellipsis" :value="resolveSelected('industry')" @click="clickCell('industry')"></van-cell>
-                            <van-cell center title="采购单位类型" value-class="ellipsis" is-link :value="resolveSelected('buyerclass')" @click="clickCell('buyerclass')"></van-cell>
-                            <div class="date-cell collection">
-                                <div class="cell-title">时间</div>
-                                <date-component
-                                    ref="dateSelector"
-                                    popup-container="body"
-                                    :diy="true"
-                                    :times="timeOptions"></date-component>
+    <div class="j-container">
+        {{include "/big-member/header.html"}}
+        <div class="j-main" id="analysis" v-cloak>
+            <div class="j-container">
+                <van-tabs class="analysis-tab" :title-active-color="tabConf.titleActiveColor"
+                    :title-inactive-color="tabConf.titleInactiveColor" :line-width="tabConf.lineWidth"
+                    :color="tabConf.color" :before-change="beforeTabChange" v-model="tabActiveName">
+                    <van-tab v-for="(tab, index) in tabList" :key="index" :title="tab.label" :name="tab.name"></van-tab>
+                </van-tabs>
+                <section v-show="tabActiveName === 'analysis'" class="j-main analysis-content">
+                    <div class="j-container search-filters bg-white" v-show="!rid">
+                        <div class="j-main">
+                            <div class="height8">height8</div>
+                            <div class="filters-title pd-lr16">
+                                <span>分析条件</span>
                             </div>
-                        </van-cell-group>
-                        <div class="empty-container analysis-empty" v-show="emptyShow">
-                            <div class="empty-content-position">
-                                <div class="image">
-                                    <img src='/common-module/public/image/jy-sleep.png'>
+                            <van-cell-group class="filters-list">
+                                <van-cell center title="分析内容" is-link value-class="ellipsis"
+                                    :value="resolveSelected('keys')" @click="clickCell('keys')"></van-cell>
+                                <van-cell center title="匹配方式" is-link value-class="ellipsis"
+                                    :value="resolveSelected('matchway')" @click="clickCell('matchway')"></van-cell>
+                                <van-cell center title="区域" is-link value-class="ellipsis"
+                                    :value="resolveSelected('area')" @click="clickCell('area')"></van-cell>
+                                <van-cell center title="行业" is-link value-class="ellipsis"
+                                    :value="resolveSelected('industry')" @click="clickCell('industry')"></van-cell>
+                                <van-cell center title="采购单位类型" value-class="ellipsis" is-link
+                                    :value="resolveSelected('buyerclass')" @click="clickCell('buyerclass')"></van-cell>
+                                <div class="date-cell collection">
+                                    <div class="cell-title">成交时间</div>
+                                    <date-component ref="dateSelector" popup-container="body" :diy="true"
+                                        :times="timeOptions"></date-component>
+                                </div>
+                            </van-cell-group>
+                            <div class="empty-container analysis-empty" v-show="emptyShow">
+                                <div class="empty-content-position">
+                                    <div class="image">
+                                        <img src='/common-module/public/image/jy-sleep.png'>
+                                    </div>
+                                    <div class="empty-main tip-text" v-html="empty.msg"></div>
                                 </div>
-                                <div class="empty-main tip-text" v-html="empty.msg"></div>
                             </div>
                         </div>
+                        <div class="j-footer j-button-group">
+                            <button class="j-button-cancel" @click="resetAllFilters">重置</button>
+                            <button class="j-button-confirm" @click="startAnalysis">开始分析</button>
+                        </div>
                     </div>
-                    <div class="j-footer j-button-group">
-                        <button class="j-button-cancel" @click="resetAllFilters">重置</button>
-                        <button class="j-button-confirm" @click="startAnalysis">开始分析</button>
-                    </div>
-                </div>
-                <div class="j-container search-result" v-show="!filtersPageShow && rid">
-                    <div class="j-main">
-                        <div class="height8">height8</div>
-                        <van-cell-group class="filters-list">
-                            <van-cell center title="分析条件" is-link @click="toAnalysisPage"></van-cell>
-                        </van-cell-group>
-                        <div class="height8" v-show="false"></div>
-                        <section class="section bg-white dimension">
-                            <div class="section-title"> - 分析维度 -</div>
-                            <van-sticky class="section-sticky" z-index="2000" :offset-top="stickyOffset">
-                                <div class="section-content dimension-list bg-white">
-                                    <div
-                                        class="j-button j-button-item dimension-item"
-                                        v-for="(item, index) in dimensionList"
-                                        :key="index"
-                                        v-text="item.name"
-                                        :class="{ active: item.id === activeDimension }"
-                                        @click="anchorTo(item)"
-                                    ></div>
-                                </div>
-                            </van-sticky>
-                            <div class="section-footer section-tip-text">
-                                <span>数据统计范围:</span>
-                                <span v-text="formatSelectTime(reportFilters.selectTime)"></span>
-                            </div>
-                        </section>
-                        <!-- 市场概况 -->
-                        <section class="section bg-white market-overview" id="market" v-if="getStatus">
-                            <div class="section-title add-pro-list-inlet pd-16">
-                              <span>市场概况</span>
-                              <div class="pro_list_inlet" @click="inProList">
-                                <img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"}}" alt="">
-                                <span>项目明细</span>
-                              </div>
-                            </div>
-                            <div class="section-content market-overview-list">
-                                <div
-                                    class="market-overview-item"
-                                    v-for="(item, index) in sections.market.overview"
-                                    :key="index">
-                                    <span class="m-overview-name">${ item.label }</span>
-                                    <span class="m-overview-unit">(${ item.unit })</span>
-                                    <span class="m-overview-count">${ item.count }</span>
-                                    <span class="m-overview-type" v-if="item.ringRatio">环比</span>
-                                    <span
-                                        class="m-overview-ratio"
-                                        v-show="overviewRateTotal"
-                                        :class="{
+                    <div class="j-container search-result" v-show="!filtersPageShow && rid">
+                        <div class="j-main">
+                            <div class="height8">height8</div>
+                            <van-cell-group class="filters-list">
+                                <van-cell center title="分析条件" is-link @click="toAnalysisPage"></van-cell>
+                            </van-cell-group>
+                            <div class="height8" v-show="false"></div>
+                            <section class="section bg-white dimension">
+                                <div class="section-title"> - 分析维度 -</div>
+                                <van-sticky class="section-sticky" z-index="2000" :offset-top="stickyOffset">
+                                    <div class="section-content dimension-list bg-white">
+                                        <div class="j-button j-button-item dimension-item"
+                                            v-for="(item, index) in dimensionList" :key="index" v-text="item.name"
+                                            :class="{ active: item.id === activeDimension }" @click="anchorTo(item)">
+                                        </div>
+                                    </div>
+                                </van-sticky>
+                                <div class="section-footer section-tip-text">
+                                    <span>数据统计范围:</span>
+                                    <span v-text="formatSelectTime(reportFilters.selectTime)"></span>
+                                </div>
+                            </section>
+                            <!-- 市场概况 -->
+                            <section class="section bg-white market-overview" id="market" v-if="getStatus">
+                                <div class="section-title add-pro-list-inlet pd-16">
+                                    <span>市场概况</span>
+                                    <div class="pro_list_inlet" @click="inProList">
+                                        <img src="{{Cdns .Host " seo" "cdn"
+                                            |SafeUrl}}/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"
+                                            }}" alt="">
+                                        <span>项目明细</span>
+                                    </div>
+                                </div>
+                                <div class="section-content market-overview-list">
+                                    <div class="market-overview-item" v-for="(item, index) in sections.market.overview"
+                                        :key="index">
+                                        <span class="m-overview-name">${ item.label }</span>
+                                        <span class="m-overview-unit">(${ item.unit })</span>
+                                        <span class="m-overview-count">${ item.count }</span>
+                                        <span class="m-overview-type" v-if="item.ringRatio">环比</span>
+                                        <span class="m-overview-ratio" v-show="overviewRateTotal" :class="{
                                             red: item.ringRatio > 0,
                                             green: item.ringRatio < 0
                                         }">
-                                        <van-icon name="down" :class="{ 'icon-reverse': item.ringRatio >= 0 }" v-if="item.ringRatio"></van-icon>
-                                        <span>${ item.ringRatio ? (Math.abs(item.ringRatio) + '%') : '-' }</span>
-                                    </span>
+                                            <van-icon name="down" :class="{ 'icon-reverse': item.ringRatio >= 0 }"
+                                                v-if="item.ringRatio"></van-icon>
+                                            <span>${ item.ringRatio ? (Math.abs(item.ringRatio) + '%') : '-' }</span>
+                                        </span>
+                                    </div>
+                                </div>
+                                <div class="section-footer section-tip-text pd-16">
+                                    环比:统计学术语,是表示连续2个统计周期(比如连<br />续两月)内的量的变化比。
+                                </div>
+                            </section>
+                            <div class="vip_component" v-if="!getStatus" style="height:8.84rem">
+                                <div class="example-title add-pro-list-inlet">
+                                    <span>市场概况</span>
+                                    <div class="pro_list_inlet" @click="inProList">
+                                        <img src="{{Cdns .Host " seo" "cdn"
+                                            |SafeUrl}}/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"
+                                            }}" alt="">
+                                        <span>项目明细</span>
+                                    </div>
+                                </div>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/01-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example ref="chartExampleRef" type="item_1"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/01.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
                                 </div>
                             </div>
-                            <div class="section-footer section-tip-text pd-16">
-                                环比:统计学术语,是表示连续2个统计周期(比如连<br />续两月)内的量的变化比。
-                            </div>
-                        </section>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:8.84rem">
-                          <div class="example-title add-pro-list-inlet">
-                            <span>市场概况</span>
-                            <div class="pro_list_inlet" @click="inProList">
-                              <img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"}}" alt="">
-                              <span>项目明细</span>
-                            </div>
-                          </div>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/01-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example ref="chartExampleRef" type="item_1" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/01.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
-                        </div>
-                        <!-- 项目规模分布 -->
-                        <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.dataAlready && getStatus">
-                            <div class="section-title">项目规模分布</div>
-                            <div class="section-content">
-                                <project-scatter :chart-data="sections.projectScatter.chartData"></project-scatter>
-                            </div>
-                        </section>
-                        <!-- 项目规模TOP10 -->
-                        <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.tableData.length && getStatus">
-                            <div class="section-title">项目规模TOP10</div>
-                            <div class="section-content project-top-list">
-                                <div
-                                    class="project-top-item"
-                                    v-for="(item, index) in sections.projectScatter.tableData"
-                                    :key="index">
-                                    <div class="p-t-i-hd">
-                                        <div
-                                            class="p-t-i-hd-l table-index-rect"
-                                            :class="{
+                            <!-- 项目规模分布 -->
+                            <section class="section bg-white pd-16 project-scatter"
+                                v-if="sections.projectScatter.dataAlready && getStatus">
+                                <div class="section-title">项目规模分布</div>
+                                <div class="section-content">
+                                    <project-scatter :chart-data="sections.projectScatter.chartData"></project-scatter>
+                                </div>
+                            </section>
+                            <!-- 项目规模TOP10 -->
+                            <section class="section bg-white pd-16 project-scatter"
+                                v-if="sections.projectScatter.tableData.length && getStatus">
+                                <div class="section-title">项目规模TOP10</div>
+                                <div class="section-content project-top-list">
+                                    <div class="project-top-item"
+                                        v-for="(item, index) in sections.projectScatter.tableData" :key="index">
+                                        <div class="p-t-i-hd">
+                                            <div class="p-t-i-hd-l table-index-rect" :class="{
                                                 red: index === 0,
                                                 orange: index === 1,
                                                 'soft-orange': index === 2
                                             }">
-                                            ${ index + 1 }</div>
-                                        <div class="p-t-i-hd-r" @click="toArticleContent(item)">
-                                            <div class="project-name">${ item.projectname }</div>
-                                            <div class="project-info">
-                                                <div class="project-tags">
-                                                    <div class="j-tag tag-orange" v-if="item.sortprice">项目金额:${ item.sortprice }万元</div>
-                                                    <div class="j-tag tag-plain" v-if="item.area">${ item.area }</div>
-                                                    <div class="j-tag tag-plain" v-if="item.city">${ item.city }</div>
+                                                ${ index + 1 }</div>
+                                            <div class="p-t-i-hd-r" @click="toArticleContent(item)">
+                                                <div class="project-name">${ item.projectname }</div>
+                                                <div class="project-info">
+                                                    <div class="project-tags">
+                                                        <div class="j-tag tag-orange" v-if="item.sortprice">项目金额:${
+                                                            item.sortprice }万元</div>
+                                                        <div class="j-tag tag-plain" v-if="item.area">${ item.area }
+                                                        </div>
+                                                        <div class="j-tag tag-plain" v-if="item.city">${ item.city }
+                                                        </div>
+                                                    </div>
+                                                    <div class="project-right">${ item.jgtime }</div>
                                                 </div>
-                                                <div class="project-right">${ item.jgtime }</div>
                                             </div>
                                         </div>
+                                        <div class="p-t-i-ft" v-if="item.winner_s.length">
+                                            <div class="p-t-i-ft-title">中标单位</div>
+                                            <div class="p-t-i-ft-winner" :class="{ disabled: !winner.id }"
+                                                v-for="(winner, i) in item.winner_s" :key="index" v-text="winner.name"
+                                                @click="toPortrait(winner.id, 'winner')"></div>
+                                        </div>
                                     </div>
-                                    <div class="p-t-i-ft" v-if="item.winner_s.length">
-                                        <div class="p-t-i-ft-title">中标单位</div>
-                                        <div
-                                            class="p-t-i-ft-winner"
-                                            :class="{ disabled: !winner.id }"
-                                            v-for="(winner, i) in item.winner_s"
-                                            :key="index"
-                                            v-text="winner.name"
-                                            @click="toPortrait(winner.id, 'winner')"></div>
+                                </div>
+                            </section>
+                            <div class="vip_component" v-if="!getStatus" style="height:11.38rem">
+                                <p class="example-title">项目规模分布</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/02-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_2"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/02.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
+                                </div>
+                            </div>
+                            <!-- 时间分布 -->
+                            <section class="section bg-white pd-16 time-scatter"
+                                v-if="sections.timeScatter.dataAlready">
+                                <div class="section-header">
+                                    <div class="section-title">时间分布</div>
+                                    <div class="section-actions">
+                                        <div class="action-button"
+                                            :class="{ active: sections.timeScatter.activeAction == 'month' }"
+                                            @click="sections.timeScatter.activeAction = 'month'">
+                                            月度数据</div>
+                                        <div class="action-button"
+                                            :class="{ active: sections.timeScatter.activeAction == 'year' }"
+                                            @click="sections.timeScatter.activeAction = 'year'">
+                                            年度数据</div>
+                                    </div>
+                                </div>
+                                <div class="section-content">
+                                    <div class="sub-section-content">
+                                        <market-time-scatter width="100%"
+                                            :chart-data="sections.timeScatter[sections.timeScatter.activeAction].count"></market-time-scatter>
                                     </div>
+                                    <div class="sub-section-content">
+                                        <market-time-scatter width="100%"
+                                            :chart-data="sections.timeScatter[sections.timeScatter.activeAction].amount"></market-time-scatter>
+                                    </div>
+                                </div>
+                            </section>
+                            <!-- 地区分布 -->
+                            <div class="section bg-white pd-16 area-scatter"
+                                v-if="sections.areaScatter.dataAlready && notOneAreaFilter && getStatus">
+                                <div class="section-title">地区分布</div>
+                                <div class="section-content">
+                                    <market-area-scatter
+                                        :chart-data="sections.areaScatter.chartData"></market-area-scatter>
                                 </div>
                             </div>
-                        </section>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:11.38rem">
-                          <p class="example-title">项目规模分布</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/02-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_2" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/02.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
-                        </div>
-                        <!-- 时间分布 -->
-                        <section class="section bg-white pd-16 time-scatter" v-if="sections.timeScatter.dataAlready">
-                            <div class="section-header">
-                                <div class="section-title">时间分布</div>
-                                <div class="section-actions">
-                                    <div
-                                        class="action-button"
-                                        :class="{ active: sections.timeScatter.activeAction == 'month' }"
-                                        @click="sections.timeScatter.activeAction = 'month'">
-                                        月度数据</div>
-                                    <div
-                                        class="action-button"
-                                        :class="{ active: sections.timeScatter.activeAction == 'year' }"
-                                        @click="sections.timeScatter.activeAction = 'year'">
-                                        年度数据</div>
+                            <!-- 城市分布 -->
+                            <div class="section bg-white pd-16 city-scatter"
+                                v-if="sections.areaScatter.dataAlready && notOneAreaCityFilter && getStatus">
+                                <div class="section-title">城市分布</div>
+                                <div class="section-content">
+                                    <!-- <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter> -->
+                                    <div class="section-content-header">
+                                        <div class="set-area-city" @click="setAreaCity">
+                                            <span>${sections.areaScatter.selectArea.area}</span>
+                                            <van-icon name="play"></van-icon>
+                                        </div>
+                                        <div class="set-sort-type">
+                                            <project-header :sort-option="sortOptionContent"
+                                                :sort-optiontitle="sortOptionTitle" :showtotal="false"
+                                                @setsort="setsortType"></project-header>
+                                        </div>
+                                        <div class="set-unit">单位:${sections.areaScatter.sortType===0?'个':'万元'}</div>
+                                    </div>
+                                    <div class="progress-bar-container">
+                                        <div class="progress-bar-item" v-for="(item,index) in showAreaCityBtn"
+                                            :key="index">
+                                            <div class="item-label">
+                                                <span class="item-name">${item.city}</span>
+                                                <span class="item-count"
+                                                    v-if="sections.areaScatter.sortType===0">${item.total}个</span>
+                                                <span class="item-count" v-else>${showCountAmount(item)}万元</span>
+                                            </div>
+                                            <div class="item-progress">
+                                                <span class="item-progress-count blue-progress"
+                                                    :style="{width: item.parent}"></span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="more" @click="sections.areaScatter.showAreaCityListBtn = false"
+                                        v-if="sections.areaScatter.showAreaCityListBtn">
+                                        <span>查看更多</span>
+                                    </div>
                                 </div>
                             </div>
-                            <div class="section-content">
-                                <div class="sub-section-content">
-                                    <market-time-scatter width="100%" :chart-data="sections.timeScatter[sections.timeScatter.activeAction].count"></market-time-scatter>
+                            <van-popup v-model="sections.areaScatter.showAreaPopup" closeable round position="bottom"
+                                close-icon="clear" class="j-popup collection" :lazy-render="false"
+                                overlay-class="j-overlay" :style="{ height: '60%' }" get-container="body">
+                                <div class="j-container report-popup">
+                                    <div class="popup-header header-title">请选择省份</div>
+                                    <div class="j-main area-content">
+                                        <area-component :multiple="false" :newprovincelist="reportFilters.area"
+                                            :showcountry="false" ref="areaSelector" @cancel="cancelSelectArea"
+                                            @confirm="confirmSelectArea"></area-component>
+                                    </div>
                                 </div>
-                                <div class="sub-section-content">
-                                    <market-time-scatter width="100%" :chart-data="sections.timeScatter[sections.timeScatter.activeAction].amount"></market-time-scatter>
+                            </van-popup>
+                            <div class="section bg-white pd-16"
+                                v-if="sections.areaScatter.projectCountTop3 && getStatus">
+                                <div class="section-title">各地区重点中标单位-项目数量</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="sections.areaScatter.projectCountTop3" type="count"
+                                        @save="saveState"></market-top3-table>
+                                    <div class="more" v-if="sections.areaScatter.projectCountMorebtn"
+                                        @click="goAlldetail('areaScatter_projectCountMorebtn','各地区重点中标单位-项目数量')">
+                                        <span>查看更多</span>
+                                    </div>
                                 </div>
                             </div>
-                        </section>
-                        <!-- 地区分布 -->
-                        <div class="section bg-white pd-16 area-scatter" v-if="sections.areaScatter.dataAlready && notOneAreaFilter && getStatus">
-                            <div class="section-title">地区分布</div>
-                            <div class="section-content">
-                                <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter>
+                            <div class="section bg-white pd-16"
+                                v-if="sections.areaScatter.projectAmountTop3 && getStatus">
+                                <div class="section-title">各地区重点中标单位-项目金额</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="sections.areaScatter.projectAmountTop3"
+                                        type="amount" @save="saveState"></market-top3-table>
+                                    <div class="more" v-if="sections.areaScatter.projectAmountMorebtn"
+                                        @click="goAlldetail('areaScatter_projectAmountMorebtn','各地区重点中标单位-项目金额')">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
                             </div>
-                        </div>
-                        <!-- 城市分布 -->
-                        <div class="section bg-white pd-16 city-scatter" v-if="sections.areaScatter.dataAlready && notOneAreaCityFilter && getStatus">
-                          <div class="section-title">城市分布</div>
-                          <div class="section-content">
-                            <!-- <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter> -->
-                            <div class="section-content-header">
-                              <div class="set-area-city" @click="setAreaCity">
-                                <span>${sections.areaScatter.selectArea.area}</span>
-                                <van-icon name="play"></van-icon>
-                              </div>
-                              <div class="set-sort-type">
-                                <project-header :sort-option="sortOptionContent" :sort-optiontitle="sortOptionTitle" :showtotal="false" @setsort="setsortType"></project-header>
-                              </div>
-                              <div class="set-unit">单位:${sections.areaScatter.sortType===0?'个':'万元'}</div>
+                            <div class="vip_component" v-if="!getStatus" style="height:13.08rem">
+                                <p class="example-title">地区分布</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/03-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_3"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/03.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
+                                </div>
                             </div>
-                            <div class="progress-bar-container">
-                              <div class="progress-bar-item" v-for="(item,index) in showAreaCityBtn" :key="index">
-                                  <div class="item-label">
-                                      <span class="item-name">${item.city}</span>
-                                      <span class="item-count" v-if="sections.areaScatter.sortType===0">${item.total}个</span>
-                                      <span class="item-count" v-else>${showCountAmount(item)}万元</span>
-                                  </div>
-                                  <div class="item-progress">
-                                      <span class="item-progress-count blue-progress" :style="{width: item.parent}"></span>
-                                  </div>
-                              </div>
+                            <!-- 客户分布 -->
+                            <div class="section bg-white pd-16 user-scatter" v-if="sections.userScatter.list.length">
+                                <div class="clearfix">
+                                    <div class="section-title fl_">客户分布</div>
+                                    <div class="detail-btn" @click="gotable">查看详情<img src="{{Cdns .Host " seo" "cdn"
+                                            |SafeUrl}}/common-module/collection/image/icon.png?v={{Msg "seo" "version"
+                                            }}" alt=""></div>
+                                </div>
+                                <div class="section-content">
+                                    <market-user-scatter :chart-data="sections.userScatter.list"></market-user-scatter>
+                                </div>
                             </div>
-                            <div class="more" @click="sections.areaScatter.showAreaCityListBtn = false" v-if="sections.areaScatter.showAreaCityListBtn">
-                              <span>查看更多</span>
+                            <div class="section bg-white pd-16" v-if="sections.userScatter.projectCountTop3">
+                                <div class="section-title">各客户类型重点中标单位-项目数量</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="sections.userScatter.projectCountTop3" type="count"
+                                        @save="saveState"></market-top3-table>
+                                    <div class="more" v-if="sections.userScatter.projectCountMorebtn"
+                                        @click="goAlldetail('userScatter_projectCountMorebtn','各客户类型重点中标单位-项目数量')">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
                             </div>
-                          </div>
-                        </div>
-                        <van-popup
-                          v-model="sections.areaScatter.showAreaPopup"
-                          closeable
-                          round
-                          position="bottom"
-                          close-icon="clear"
-                          class="j-popup collection"
-                          :lazy-render="false"
-                          overlay-class="j-overlay"
-                          :style="{ height: '60%' }"
-                          get-container="body">
-                          <div class="j-container report-popup">
-                              <div class="popup-header header-title">请选择省份</div>
-                              <div class="j-main area-content">
-                                  <area-component
-                                      :multiple="false"
-                                      :newprovincelist="reportFilters.area"
-                                      :showcountry="false"
-                                      ref="areaSelector"
-                                      @cancel="cancelSelectArea"
-                                      @confirm="confirmSelectArea"></area-component>
-                              </div>
-                          </div>
-                        </van-popup>
-                        <div class="section bg-white pd-16" v-if="sections.areaScatter.projectCountTop3 && getStatus">
-                            <div class="section-title">项目数量TOP3地区的重点中标单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="sections.areaScatter.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                            <div class="section bg-white pd-16" v-if="sections.userScatter.projectAmountTop3">
+                                <div class="section-title">各客户类型重点中标单位-项目金额</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="sections.userScatter.projectAmountTop3"
+                                        type="amount" @save="saveState"></market-top3-table>
+                                    <div class="more" v-if="sections.userScatter.projectAmountMorebtn"
+                                        @click="goAlldetail('userScatter_projectAmountMorebtn','各客户类型重点中标单位-项目金额')">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
                             </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="sections.areaScatter.projectAmountTop3 && getStatus">
-                            <div class="section-title">项目金额TOP3地区的重点中标单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="sections.areaScatter.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                            <!-- 细分市场 - 项目数量 -->
+                            <div class="section bg-white pd-16 market-refine"
+                                v-if="sections.market.refine.dataAlready && getStatus">
+                                <div class="section-title">细分市场 - 项目数量</div>
+                                <div class="section-content">
+                                    <market-segment :chart-data="sections.market.refine.projectCountData"
+                                        type="count"></market-segment>
+                                </div>
                             </div>
-                        </div>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:13.08rem">
-                          <p class="example-title">地区分布</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/03-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_3" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/03.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
-                        </div>
-                        <!-- 客户分布 -->
-                        <div class="section bg-white pd-16 user-scatter" v-if="sections.userScatter.list.length">
-                           <div class="clearfix">
-                            <div class="section-title fl_">客户分布</div>
-                            <div class="detail-btn" @click="gotable">查看详情<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/image/icon.png?v={{Msg "seo" "version"}}" alt=""></div>
-                           </div>
-                            <div class="section-content">
-                                <market-user-scatter :chart-data="sections.userScatter.list"></market-user-scatter>
+                            <div class="section bg-white pd-16"
+                                v-if="sections.market.refine.projectCountTop3 && getStatus">
+                                <div class="section-title">细分市场的重点中标单位-项目数量</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="sections.market.refine.projectCountTop3"
+                                        type="count" @save="saveState"></market-top3-table>
+                                    <div class="more" v-if="sections.market.refine.projectCountMorebtn"
+                                        @click="goAlldetail('market_projectCountMorebtn','细分市场的重点中标单位-项目数量')">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
                             </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="sections.userScatter.projectCountTop3">
-                            <div class="section-title">项目数量TOP3客户类型的重点中标单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="sections.userScatter.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                            <div class="vip_component" v-if="!getStatus" style="height:10.8rem">
+                                <p class="example-title">细分市场 - 项目数量</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/04-2-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_4_1"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-2.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
+                                </div>
                             </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="sections.userScatter.projectAmountTop3">
-                            <div class="section-title">项目金额TOP3客户类型的重点中标单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="sections.userScatter.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                            <!-- 细分市场 - 项目金额 -->
+                            <div class="section bg-white pd-16 market-refine"
+                                v-if="sections.market.refine.dataAlready && getStatus">
+                                <div class="section-title">细分市场 - 项目金额</div>
+                                <div class="section-content">
+                                    <market-segment :chart-data="sections.market.refine.projectAmountData"
+                                        type="amount"></market-segment>
+                                </div>
                             </div>
-                        </div>
-                        <!-- 细分市场 - 项目数量 -->
-                        <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready && getStatus">
-                            <div class="section-title">细分市场 - 项目数量</div>
-                            <div class="section-content">
-                                <market-segment :chart-data="sections.market.refine.projectCountData" type="count"></market-segment>
+                            <div class="section bg-white pd-16"
+                                v-if="sections.market.refine.projectAmountTop3 && getStatus">
+                                <div class="section-title">细分市场的重点中标单位-项目金额</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="sections.market.refine.projectAmountTop3"
+                                        type="amount" @save="saveState"></market-top3-table>
+                                    <div class="more" v-if="sections.market.refine.projectAmountMorebtn"
+                                        @click="goAlldetail('market_projectAmountMorebtn','细分市场的重点中标单位-项目金额')">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
                             </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="sections.market.refine.projectCountTop3 && getStatus">
-                            <div class="section-title">细分市场的重点中标单位-项目数量</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="sections.market.refine.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                            <div class="vip_component" v-if="!getStatus" style="height:10.8rem">
+                                <p class="example-title">细分市场 - 项目金额</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/04-1-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_4_2"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-1.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
+                                </div>
                             </div>
-                        </div>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:10.8rem">
-                          <p class="example-title">细分市场 - 项目数量</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-2-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_4_1" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-2.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
-                        </div>
-                        <!-- 细分市场 - 项目金额 -->
-                        <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready && getStatus">
-                            <div class="section-title">细分市场 - 项目金额</div>
-                            <div class="section-content">
-                                <market-segment :chart-data="sections.market.refine.projectAmountData" type="amount"></market-segment>
+                            <!-- 采购规模分布 -->
+                            <div class="section bg-white pd-16 buyerclass-scatter" id="buyer"
+                                v-if="sections.buyerclass.dataAlready">
+                                <div class="section-title">采购规模分布</div>
+                                <div class="section-content">
+                                    <line-chart-scatter
+                                        :chart-data="sections.buyerclass.chartData"></line-chart-scatter>
+                                </div>
                             </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="sections.market.refine.projectAmountTop3 && getStatus">
-                            <div class="section-title">细分市场的重点中标单位-项目金额</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="sections.market.refine.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                            <div class="section bg-white pd-16" v-if="showBuyerBtn && getStatus">
+                                <div class="section-title">项目数量TOP30采购单位及其重点合作中标单位</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="showBuyerBtn" type="count"
+                                        @save="saveState"></market-top3-table>
+                                    <div class="more" @click="sections.buyerclass.showCountAllBtn = false"
+                                        v-if="sections.buyerclass.showCountAllBtn">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
                             </div>
-                        </div>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:10.8rem">
-                          <p class="example-title">细分市场 - 项目金额</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-1-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_4_2" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-1.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
-                        </div>
-                        <!-- 采购规模分布 -->
-                        <div class="section bg-white pd-16 buyerclass-scatter" id="buyer" v-if="sections.buyerclass.dataAlready">
-                            <div class="section-title">采购规模分布</div>
-                            <div class="section-content">
-                                <line-chart-scatter :chart-data="sections.buyerclass.chartData"></line-chart-scatter>
+                            <div class="vip_component" v-if="!getStatus" style="height:10.8rem">
+                                <p class="example-title">项目数量TOP30采购单位及其重点合作中标单位</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/05-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_5"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/05.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
+                                </div>
                             </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="showBuyerBtn && getStatus">
-                            <div class="section-title">项目数量TOP30采购单位及其重点合作中标单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="showBuyerBtn" type="count" @save="saveState"></market-top3-table>
-                                <div class="more" @click="sections.buyerclass.showCountAllBtn = false" v-if="sections.buyerclass.showCountAllBtn">
-                                  <span>查看更多</span>
+                            <div class="section bg-white pd-16" v-if="showAmoutBtn && getStatus">
+                                <div class="section-title">采购金额TOP30采购单位及其重点合作中标单位</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="showAmoutBtn" type="amount"
+                                        @save="saveState"></market-top3-table>
+                                    <div class="more" @click="sections.buyerclass.showAmoutAllBtn = false"
+                                        v-if="sections.buyerclass.showAmoutAllBtn">
+                                        <span>查看更多</span>
+                                    </div>
                                 </div>
                             </div>
-                        </div>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:10.8rem">
-                          <p class="example-title">项目数量TOP30采购单位及其重点合作中标单位</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/05-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_5" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/05.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="showAmoutBtn && getStatus">
-                            <div class="section-title">采购金额TOP30采购单位及其重点合作中标单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="showAmoutBtn" type="amount" @save="saveState"></market-top3-table>
-                                <div class="more" @click="sections.buyerclass.showAmoutAllBtn = false" v-if="sections.buyerclass.showAmoutAllBtn">
-                                  <span>查看更多</span>
+                            <div class="vip_component" v-if="!getStatus" style="height:10.8rem">
+                                <p class="example-title">采购金额TOP30采购单位及其重点合作中标单位</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/06-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_6"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/06.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
                                 </div>
                             </div>
-                        </div>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:10.8rem">
-                          <p class="example-title">采购金额TOP30采购单位及其重点合作中标单位</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/06-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_6" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/06.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
-                        </div>
-                        <!-- 中标规模分布 -->
-                        <div class="section bg-white pd-16 winner-scatter" id="winner" v-if="sections.winner.dataAlready">
-                            <div class="section-title">中标规模分布</div>
-                            <div class="section-content">
-                                <line-chart-scatter :chart-data="sections.winner.chartData"></line-chart-scatter>
+                            <!-- 中标规模分布 -->
+                            <div class="section bg-white pd-16 winner-scatter" id="winner"
+                                v-if="sections.winner.dataAlready">
+                                <div class="section-title">中标规模分布</div>
+                                <div class="section-content">
+                                    <line-chart-scatter :chart-data="sections.winner.chartData"></line-chart-scatter>
+                                </div>
                             </div>
-                        </div>
-                        <div class="section bg-white pd-16" v-if="showWinnerCountBtn && getStatus">
-                            <div class="section-title">项目数量TOP30中标单位及其重点合作采购单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="showWinnerCountBtn" type="count" @save="saveState"></market-top3-table>
-                                <div class="more" @click="sections.winner.showCountAllBtn = false" v-if="sections.winner.showCountAllBtn">
-                                  <span>查看更多</span>
+                            <div class="section bg-white pd-16" v-if="showWinnerCountBtn && getStatus">
+                                <div class="section-title">项目数量TOP30中标单位及其重点合作采购单位</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="showWinnerCountBtn" type="count"
+                                        @save="saveState"></market-top3-table>
+                                    <div class="more" @click="sections.winner.showCountAllBtn = false"
+                                        v-if="sections.winner.showCountAllBtn">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="vip_component" v-if="!getStatus" style="height:10.8rem">
+                                <p class="example-title">项目数量TOP30中标单位及其重点合作采购单位</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/07-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_7"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/07.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
+                                </div>
+                            </div>
+                            <div class="section bg-white pd-16" v-if="showWinnerAmoutBtn && getStatus">
+                                <div class="section-title">中标金额TOP30中标单位及其重点合作采购单位</div>
+                                <div class="section-content">
+                                    <market-top3-table :table-data="showWinnerAmoutBtn" type="amount"
+                                        @save="saveState"></market-top3-table>
+                                    <div class="more" @click="sections.winner.showAmoutAllBtn = false"
+                                        v-if="sections.winner.showAmoutAllBtn">
+                                        <span>查看更多</span>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="vip_component" v-if="!getStatus" style="height:10.8rem">
+                                <p class="example-title">中标金额TOP30中标单位及其重点合作采购单位</p>
+                                <div class="chart_com" style="background:url('{{Cdns .Host " seo" "cdn"
+                                    |SafeUrl}}/common-module/report-analysis/image/08-bg.png?v={{Msg "seo" "version"
+                                    }}') no-repeat;background-size:100% 100%">
+                                    <chart-example type="item_8"
+                                        imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/08.png?v={{Msg "seo" "version"}}'>
+                                    </chart-example>
                                 </div>
                             </div>
                         </div>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:10.8rem">
-                          <p class="example-title">项目数量TOP30中标单位及其重点合作采购单位</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/07-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_7" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/07.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
+                        <div class="fixed-bottom-right clickable scroll-to-top" style="display: none;">
+                            <van-icon name="arrow-up"></van-icon>
                         </div>
-                        <div class="section bg-white pd-16" v-if="showWinnerAmoutBtn && getStatus">
-                            <div class="section-title">中标金额TOP30中标单位及其重点合作采购单位</div>
-                            <div class="section-content">
-                                <market-top3-table :table-data="showWinnerAmoutBtn" type="amount" @save="saveState"></market-top3-table>
-                                <div class="more" @click="sections.winner.showAmoutAllBtn = false" v-if="sections.winner.showAmoutAllBtn">
-                                  <span>查看更多</span>
-                                </div>
+                        <div class="down-footer" v-if="showdownFooter">
+                            <div class="foot-title" v-text="downFootertitle"></div>
+                            <div class="footbtnGroup">
+                                <div class="btn-left" v-if="!getStatus" @click="freeGolink">申请免费体验</div>
+                                <div class="btn-right" @click="goDown"><span>下载报告</span></div>
                             </div>
                         </div>
-                        <div class="vip_component"
-                          v-if="!getStatus"
-                          style="height:10.8rem">
-                          <p class="example-title">中标金额TOP30中标单位及其重点合作采购单位</p>
-                          <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/08-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_8" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/08.png?v={{Msg "seo" "version"}}'>
-                            </chart-example>
-                          </div>
+                        <div class="down-footer-seat" v-if="showdownFooter"></div>
+                    </div>
+                </section>
+            </div>
+            <!-- 下载弹窗 -->
+            <downloadpopup ref="downloadpopup"  @lookmore="anchorTo({top:0})" :data="{buyercount,winnercount,projectTotalMoney,projectCount,balance,getStatus}"></downloadpopup>
+
+            <van-popup v-model="filterDialogShow.keys" closeable round position="bottom" close-icon="clear"
+                class="j-popup collection" overlay-class="j-overlay" :lazy-render="false" :style="{ height: '60%' }"
+                get-container="body">
+                <div class="j-container keys-popup">
+                    <div class="popup-header">
+                        <div class="header-top">
+                            <div class="header-title">选择分析内容</div>
+                            <div class="header-action" @click="toSubManageButtonClick">订阅管理</div>
                         </div>
+                        <div class="header-bottom">注:如需新增分析内容,请完善您的订阅关键词</div>
                     </div>
-                    <div class="fixed-bottom-right clickable scroll-to-top" style="display: none;">
-                        <van-icon name="arrow-up"></van-icon>
+                    <div class="j-main">
+                        <keyword-component ref="keywordSelector" protype="bigmember" :use-key-card="true"
+                            @nokeys="showSetKeyTip" @cancel="cancel($event, 'keys')" @confirm="confirm($event, 'keys')"
+                            :selectkeywordlist="filters.selectKeysArr"></keyword-component>
                     </div>
                 </div>
-            </section>
-        </div>
-        <van-popup
-            v-model="filterDialogShow.keys"
-            closeable
-            round
-            position="bottom"
-            close-icon="clear"
-            class="j-popup collection"
-            overlay-class="j-overlay"
-            :lazy-render="false"
-            :style="{ height: '60%' }"
-            get-container="body">
-            <div class="j-container keys-popup">
-                <div class="popup-header">
-                    <div class="header-top">
-                        <div class="header-title">选择分析内容</div>
-                        <div class="header-action" @click="toSubManageButtonClick">订阅管理</div>
+            </van-popup>
+            <van-popup v-model="filterDialogShow.matchway" closeable round position="bottom" close-icon="clear"
+                class="j-popup collection" overlay-class="j-overlay" :lazy-render="false" :style="{ height: '36%' }"
+                get-container="body">
+                <div class="j-container matchway-popup">
+                    <div class="popup-header header-title">请选择匹配方式</div>
+                    <div class="j-main">
+                        <van-radio-group v-model="filtersCache.matchway">
+                            <van-cell-group>
+                                <van-cell v-for="item in matchWayList" :key="item.label" :title="item.name" clickable
+                                    @click="filtersCache.matchway = item.label">
+                                    <template #right-icon>
+                                        <van-radio checked-color="#2ABED1" :name="item.label" />
+                                    </template>
+                                </van-cell>
+                        </van-radio-group>
+                    </div>
+                    <div class="j-footer">
+                        <div class="j-button-group">
+                            <button class="j-button-cancel" @click="filtersCache.matchway = 'title'">重置</button>
+                            <button class="j-button-confirm"
+                                @click="filters.matchway = filtersCache.matchway;filterDialogShow.matchway = false">确认</button>
+                        </div>
                     </div>
-                    <div class="header-bottom">注:如需新增分析内容,请完善您的订阅关键词</div>
-                </div>
-                <div class="j-main">
-                    <keyword-component
-                        ref="keywordSelector"
-                        protype="bigmember"
-                        :use-key-card="true"
-                        @nokeys="showSetKeyTip"
-                        @cancel="cancel($event, 'keys')"
-                        @confirm="confirm($event, 'keys')"
-                        :selectkeywordlist="filters.selectKeysArr"></keyword-component>
-                </div>
-            </div>
-        </van-popup>
-        <van-popup
-            v-model="filterDialogShow.matchway"
-            closeable
-            round
-            position="bottom"
-            close-icon="clear"
-            class="j-popup collection"
-            overlay-class="j-overlay"
-            :lazy-render="false"
-            :style="{ height: '36%' }"
-            get-container="body">
-            <div class="j-container matchway-popup">
-                <div class="popup-header header-title">请选择匹配方式</div>
-                <div class="j-main">
-                    <van-radio-group v-model="filtersCache.matchway">
-                        <van-cell-group>
-                          <van-cell
-                            v-for="item in matchWayList"
-                            :key="item.label"
-                            :title="item.name"
-                            clickable
-                            @click="filtersCache.matchway = item.label">
-                            <template #right-icon>
-                              <van-radio checked-color="#2ABED1" :name="item.label" />
-                            </template>
-                          </van-cell>
-                    </van-radio-group>
-                </div>
-                <div class="j-footer">
-                    <div class="j-button-group">
-                        <button class="j-button-cancel" @click="filtersCache.matchway = 'title'">重置</button>
-                        <button class="j-button-confirm" @click="filters.matchway = filtersCache.matchway;filterDialogShow.matchway = false">确认</button>
-                      </div>
                 </div>
-            </div>
-        </van-popup>
-        <van-popup
-            v-model="filterDialogShow.area"
-            closeable
-            round
-            position="bottom"
-            close-icon="clear"
-            :lazy-render="false"
-            class="j-popup collection"
-            overlay-class="j-overlay"
-            :style="{ height: '60%' }"
-            get-container="body">
-            <div class="j-container report-popup">
-                <div class="popup-header header-title">选择区域</div>
-                <div class="j-main">
-                    <area-city-mobile
-                        ref="areaCitySelector"
-                        @cancel="cancel($event, 'area')"
-                        @confirm="confirm($event, 'area')"></area-city-mobile>
+            </van-popup>
+            <van-popup v-model="filterDialogShow.area" closeable round position="bottom" close-icon="clear"
+                :lazy-render="false" class="j-popup collection" overlay-class="j-overlay" :style="{ height: '60%' }"
+                get-container="body">
+                <div class="j-container report-popup">
+                    <div class="popup-header header-title">选择区域</div>
+                    <div class="j-main">
+                        <area-city-mobile ref="areaCitySelector" @cancel="cancel($event, 'area')"
+                            @confirm="confirm($event, 'area')"></area-city-mobile>
+                    </div>
                 </div>
-            </div>
-        </van-popup>
-        <van-popup
-            v-model="filterDialogShow.industry"
-            closeable
-            round
-            position="bottom"
-            close-icon="clear"
-            class="j-popup collection"
-            overlay-class="j-overlay"
-            :lazy-render="false"
-            :style="{ height: '60%' }"
-            get-container="body">
-            <div class="j-container report-popup">
-                <div class="popup-header header-title">选择行业</div>
-                <div class="j-main">
-                    <industry-component
-                        ref="industrySelector"
-                        :selectindustrylist="filters.industry"
-                        @cancel="cancel($event, 'industry')"
-                        @confirm="confirm($event, 'industry')"></industry-component>
+            </van-popup>
+            <van-popup v-model="filterDialogShow.industry" closeable round position="bottom" close-icon="clear"
+                class="j-popup collection" overlay-class="j-overlay" :lazy-render="false" :style="{ height: '60%' }"
+                get-container="body">
+                <div class="j-container report-popup">
+                    <div class="popup-header header-title">选择行业</div>
+                    <div class="j-main">
+                        <industry-component ref="industrySelector" :selectindustrylist="filters.industry"
+                            @cancel="cancel($event, 'industry')"
+                            @confirm="confirm($event, 'industry')"></industry-component>
+                    </div>
                 </div>
-            </div>
-        </van-popup>
-        <van-popup
-            v-model="filterDialogShow.buyerclass"
-            closeable
-            round
-            position="bottom"
-            close-icon="clear"
-            class="j-popup collection"
-            :lazy-render="false"
-            overlay-class="j-overlay"
-            :style="{ height: '60%' }"
-            get-container="body">
-            <div class="j-container report-popup">
-                <div class="popup-header header-title">选择采购单位类型</div>
-                <div class="j-main">
-                    <cate-component
-                        ref="buyerclassSelector"
-                        :selectcatelist="filters.buyerclass"
-                        @cancel="cancel($event, 'buyerclass')"
-                        @confirm="confirm($event, 'buyerclass')"></cate-component>
+            </van-popup>
+            <van-popup v-model="filterDialogShow.buyerclass" closeable round position="bottom" close-icon="clear"
+                class="j-popup collection" :lazy-render="false" overlay-class="j-overlay" :style="{ height: '60%' }"
+                get-container="body">
+                <div class="j-container report-popup">
+                    <div class="popup-header header-title">选择采购单位类型</div>
+                    <div class="j-main">
+                        <cate-component ref="buyerclassSelector" :selectcatelist="filters.buyerclass"
+                            @cancel="cancel($event, 'buyerclass')"
+                            @confirm="confirm($event, 'buyerclass')"></cate-component>
+                    </div>
                 </div>
-            </div>
-        </van-popup>
+            </van-popup>
+        </div>
     </div>
-</div>
 
-<script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
-<!-- <script src=//cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.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=//cdn-common.jianyu360.com/cdn/lib/lodash/4.17.21/lodash.min.js></script>
-<script src=//cdn-common.jianyu360.com/cdn/lib/echarts/4.8.0/echarts.min.js></script>
-<script src=//cdn-common.jianyu360.com/cdn/lib/v-charts/1.19.0/index.min.js></script>
-{{include "/big-member/commonjs.html"}}
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/js/china-map-data.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/keyword-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-city-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/cate-mobile.js?v={{Msg "seo" "version"}}'></script>
-<!-- components -->
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/echarts_option.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/analysis-report-example.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/projectScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketTimeScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketAreaScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketTop3Table.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketUserScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketSegment.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/lineChartScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/project_header.js?v={{Msg "seo" "version"}}'></script>
-<!-- main.js -->
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/report_analysis.js?v={{Msg "seo" "version"}}13'></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+    <!-- <script src=//cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.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=//cdn-common.jianyu360.com/cdn/lib/lodash/4.17.21/lodash.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/echarts/4.8.0/echarts.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/v-charts/1.19.0/index.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
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/js/china-map-data.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/keyword-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-city-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/cate-mobile.js?v={{Msg "seo" "version"}}'></script>
+    <!-- components -->
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/echarts_option.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/analysis-report-example.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/projectScatter.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketTimeScatter.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketAreaScatter.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketTop3Table.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketUserScatter.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketSegment.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/lineChartScatter.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/downloadpopup.js?v={{Msg "seo" "version"}}'></script>
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/project_header.js?v={{Msg "seo" "version"}}'></script>
+    <!-- main.js -->
+    <script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/report_analysis.js?v={{Msg "seo" "version"}}13'></script>
 
 </body>
-</html>
+
+</html>

+ 11 - 3
src/jfw/modules/app/src/web/templates/big-member/page_report_analysis_history.html

@@ -3,12 +3,16 @@
 <head>
     <!--引入公共资源头部-->
     {{include "/big-member/meta.html"}}
-    <title>市场分析报告</title>
+    <title>市场分析定制报告</title>
     <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/report-analysis/css/report_analysis.css?v={{Msg "seo" "version"}}' />
     <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/diy-report/css/report-list.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet"
+    href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/common/css/appDownloadfile.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet"
+    href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/css/downloadpopup.css?v={{Msg "seo" "version"}}' />
 </head>
 
 <body>
@@ -31,8 +35,10 @@
             </van-tabs>
             <section v-show="tabActiveName === 'analysis'" class="j-main analysis-content"></section>
             <section v-show="tabActiveName === 'history'" class="j-main history-content">
-                <report-list-mobile-component ref="list" @go-report="goToAnalysis"  @go-delete="goDelete"></report-list-mobile-component>
+                <report-list-mobile-component ref="list" @go-report="goToAnalysis"  @go-delete="goDelete" @go-down="goDown"></report-list-mobile-component>
             </section>
+            <!-- 下载弹窗 -->
+            <downloadpopup ref="downloadpopup"  @lookmore="lookmore" :data="{buyercount,winnercount,projectTotalMoney,projectCount,balance,getStatus}"></downloadpopup>
         </div>
     </div>
 </div>
@@ -41,8 +47,10 @@
 <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 src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/diy-report/js/report-list.js?v={{Msg "seo" "version"}}'></script>
+<script
+        src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/downloadpopup.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/report_analysis_history.js?v={{Msg "seo" "version"}}'></script>
 
 </body>

+ 7 - 1
src/jfw/modules/app/src/web/templates/big-member/page_unit_portrayal.html

@@ -29,6 +29,9 @@
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/forward-share/css/forward.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/dataExport/css/popup-data-export.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css?v={{Msg "seo" "version"}}'/>
+  <link rel="stylesheet"
+  href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/portrait/css/downloadpopup.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"}}' />
   <style>
     .skeleton {
       height: 100%;
@@ -704,8 +707,10 @@
         </van-tabs>
       </div>
       <popup-data-export ref="popup_dataExport" @next="next_export"></popup-data-export>
+    <!-- 下载弹窗 -->
+    <downloadpopup ref="downloadpopup" :type="'unit'" :data="{'power':!getStatus,'portraitName':buyer.name,'searchcount':dt.total,'allmoney':statistics.buyerScale,'allcount':statistics.buyerCount,'otherone':statistics.winnerCount,'othertwo':statistics.otherWinner,balance}"></downloadpopup>
        <!-- 底部按钮组件 -->
-    <mobile-portrayal-footer ref="portrayalFooter" @monitorclick="changeFollowState('g')" :islogin="userInfo.isLogin"  :monitorshow="true" :monitor="follow" :params="unitParams" :allpower="allpower" :shareshow="isLogin"></mobile-portrayal-footer>
+    <mobile-portrayal-footer ref="portrayalFooter" @monitorclick="changeFollowState('g')" :islogin="userInfo.isLogin"  :monitorshow="true" :downshow="true" :monitor="follow" :params="unitParams" :allpower="allpower" :shareshow="isLogin"></mobile-portrayal-footer>
       <!--客服组件-->
       <customer-corner-component v-show="isLogin" :scroll-status="pageScrollTop < 60" bottom-position="12%"></customer-corner-component>
   </div>
@@ -751,6 +756,7 @@
   <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/visited.js?v={{Msg "seo" "version"}}'>
   </script>
+  <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/portrait/js/downloadpopup.js?v={{Msg "seo" "version"}}'></script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module//mobile-portrayal-footer/js/mobile-portrayal-footer.js?v={{Msg "seo" "version"}}'></script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/unit_portrayal.js?v={{Msg "seo" "version"}}11'>
   </script>

+ 121 - 0
src/jfw/modules/app/src/web/templates/commonPay/enterpriseAnalysis/orderDetail.html

@@ -0,0 +1,121 @@
+<!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-cancel invoke"
+                        v-if="orderStateMap[orderInfo.state].bottomButtonShow.lookInvoice"
+                        @click="lookInvoke('look')">查看发票</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>

+ 121 - 0
src/jfw/modules/app/src/web/templates/commonPay/marketAnalysis/orderDetail.html

@@ -0,0 +1,121 @@
+<!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-cancel invoke"
+                        v-if="orderStateMap[orderInfo.state].bottomButtonShow.lookInvoice"
+                        @click="lookInvoke('look')">查看发票</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>

+ 121 - 0
src/jfw/modules/app/src/web/templates/commonPay/ownerAnalysis/orderDetail.html

@@ -0,0 +1,121 @@
+<!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-cancel invoke"
+                        v-if="orderStateMap[orderInfo.state].bottomButtonShow.lookInvoice"
+                        @click="lookInvoke('look')">查看发票</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>

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

@@ -77,6 +77,18 @@
               <div class="info-item" name="附件下载包" style="display: none">
                   <span>附件下载:<span class="light-text" name="file-num"></span></span>&nbsp;&nbsp;|&nbsp;&nbsp;<span>有效期至:<span class="light-text" name="file-time"></span></span>
               </div>
+              {{else if eq .T.doType "marketAnalysis"}}
+              <div class="info-item" name="市场分析定制报告下载包" style="display: none">
+                  <span>市场分析定制报告下载包:<span class="light-text" name="file-num"></span></span>&nbsp;&nbsp;|&nbsp;&nbsp;<span>有效期至:<span class="light-text" name="file-time"></span></span>
+              </div>
+              {{else if eq .T.doType "enterpriseAnalysis"}}
+              <div class="info-item" name="企业中标分析报告下载包" style="display: none">
+                  <span>企业中标分析报告下载包:<span class="light-text" name="file-num"></span></span>&nbsp;&nbsp;|&nbsp;&nbsp;<span>有效期至:<span class="light-text" name="file-time"></span></span>
+              </div>
+              {{else if eq .T.doType "ownerAnalysis"}}
+              <div class="info-item" name="业主采购分析报告下载包" style="display: none">
+                  <span>业主采购分析报告下载包<span class="light-text" name="file-num"></span></span>&nbsp;&nbsp;|&nbsp;&nbsp;<span>有效期至:<span class="light-text" name="file-time"></span></span>
+              </div>
             {{else if eq .T.doType "buyerPortraitPack"}}
               <div class="info-item" name="采购单位画像包" style="display: none">
                 <span>采购单位画像包:<span class="light-text" name="file-num"></span></span>&nbsp;&nbsp;|&nbsp;&nbsp;<span>有效期至:<span class="light-text" name="file-time"></span></span>
@@ -162,7 +174,34 @@
             获取文档
           </button>
         </div>
-        {{end}}
+        {{else if eq .T.doType "marketAnalysis"}}
+        <div class="bottom_button j-button-group">
+          <button id ="order" class="j-button-cancel" onclick="window.location.href = '/jyapp/common/{{.T.doType}}/orderDetail?order_code={{.T.orderCode}}'">
+              查看订单
+          </button>
+          <button id ="get-ana" class="j-button-confirm" onclick="getAnalysisJumpUrl('marketAnalysis')">
+            下载报告
+          </button>
+        </div>
+      {{else if eq .T.doType "enterpriseAnalysis"}}
+      <div class="bottom_button j-button-group">
+        <button id ="order" class="j-button-cancel" onclick="window.location.href = '/jyapp/common/{{.T.doType}}/orderDetail?order_code={{.T.orderCode}}'">
+            查看订单
+        </button>
+        <button id ="get-ana" class="j-button-confirm" onclick="getAnalysisJumpUrl('enterpriseAnalysis')">
+            下载报告
+        </button>
+      </div>
+    {{else if eq .T.doType "ownerAnalysis"}}
+    <div class="bottom_button j-button-group">
+      <button id ="order" class="j-button-cancel" onclick="window.location.href = '/jyapp/common/{{.T.doType}}/orderDetail?order_code={{.T.orderCode}}'">
+          查看订单
+      </button>
+      <button id ="get-ana" class="j-button-confirm" onclick="getAnalysisJumpUrl('ownerAnalysis')">
+        下载报告
+      </button>
+    </div>
+    {{end}}
         
     </div>
 </div>
@@ -274,6 +313,36 @@
                             $('.header-title').text(document.title)
                             break
                         }
+                        case '市场分析定制报告下载包': {
+                            var tempNode = $('.info-box .info-item[name="市场分析定制报告下载包"]')
+                            var tempInfo = JSON.parse(res.data.order.filter)
+                            tempNode.find('span[name="file-num"]').text('+' + tempInfo.pNum)
+                            tempNode.find('span[name="file-time"]').text(tempInfo.endTime)
+                            tempNode.show()
+                            document.title = '市场分析定制报告下载包充值'
+                            $('.header-title').text(document.title)
+                            break
+                        }
+                        case '企业中标分析报告下载包': {
+                            var tempNode = $('.info-box .info-item[name="企业中标分析报告下载包"]')
+                            var tempInfo = JSON.parse(res.data.order.filter)
+                            tempNode.find('span[name="file-num"]').text('+' + tempInfo.pNum)
+                            tempNode.find('span[name="file-time"]').text(tempInfo.endTime)
+                            tempNode.show()
+                            document.title = '企业中标分析报告下载包充值'
+                            $('.header-title').text(document.title)
+                            break
+                        }
+                        case '业主采购分析报告下载包': {
+                            var tempNode = $('.info-box .info-item[name="业主采购分析报告下载包"]')
+                            var tempInfo = JSON.parse(res.data.order.filter)
+                            tempNode.find('span[name="file-num"]').text('+' + tempInfo.pNum)
+                            tempNode.find('span[name="file-time"]').text(tempInfo.endTime)
+                            tempNode.show()
+                            document.title = '业主采购分析报告下载包充值'
+                            $('.header-title').text(document.title)
+                            break
+                        }
                         case '采购单位画像包': {
                           var tempNode = $('.info-box .info-item[name="采购单位画像包"]')
                           var tempInfo = JSON.parse(res.data.order.filter)
@@ -476,6 +545,24 @@
            location.replace('/page_docs_mobile/home')
        }
     }
+        // 下载跳转逻辑
+    function getAnalysisJumpUrl (type){
+        // var url_ = sessionStorage.getItem('mobile-ana-buy-referrer')
+        if(window.history && window.history.length > 2){
+            window.history.go(-2)
+            return
+        }
+        if(type == 'marketAnalysis'){
+            location.replace('/jyapp/big/page/report_analysis')
+            
+        }else if(type=='enterpriseAnalysis'){
+            location.replace('/jy_mobile/search/middle/company')
+
+        }else if(type == 'ownerAnalysis'){
+            location.replace('/jy_mobile/search/middle/buyer')
+
+        }
+    }
 </script>
 {{include "/common/baiducc.html"}}
 </html>

+ 186 - 0
src/jfw/modules/app/src/web/templates/frontRouter/activity/free/open-mini-program.html

@@ -0,0 +1,186 @@
+<!DOCTYPE html>
+<html lang="zh-CN" style="font-size: 50px;">
+
+<head>
+    <title>打开小程序</title>
+    {{include "/big-member/meta.html"}}
+
+    <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/weui/2.3.0/weui.min.css />
+
+    <style>
+        .hidden {
+            display: none;
+        }
+
+        .full {
+            position: absolute;
+            top: 0;
+            bottom: 0;
+            left: 0;
+            right: 0;
+        }
+
+        .public-web-container {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+        }
+
+        .public-web-container p {
+            position: absolute;
+            top: 40%;
+        }
+
+        .public-web-container a {
+            position: absolute;
+            bottom: 40%;
+        }
+
+        .wechat-web-container {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+        }
+
+        .wechat-web-container p {
+            position: absolute;
+            top: 40%;
+        }
+
+        .wechat-web-container wx-open-launch-weapp {
+            position: absolute;
+            bottom: 40%;
+            left: 0;
+            right: 0;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+        }
+
+        .desktop-web-container {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+        }
+
+        .desktop-web-container p {
+            position: absolute;
+            top: 40%;
+        }
+    </style>
+</head>
+
+<body>
+    <div class="page full">
+        <div id="public-web-container" class="hidden">
+            <p class="">正在打开 “剑鱼招标网小程序”...</p>
+            <a id="public-web-jump-button" href="javascript:" class="weui-btn weui-btn_primary weui-btn_loading" onclick="openWeapp()">
+                <span id="public-web-jump-button-loading" class="weui-primary-loading weui-primary-loading_transparent"><i class="weui-primary-loading__dot"></i></span>
+                打开小程序
+            </a>
+        </div>
+        <div id="wechat-web-container" class="hidden">
+            <p class="">点击以下按钮打开 “剑鱼招标网小程序”</p>
+            <!-- 跳转小程序的开放标签。文档 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html -->
+            <wx-open-launch-weapp id="launch-btn" username="gh_d43f693ca31f" path="/page/component/index">
+                <template>
+                    <button style="width: 200px; height: 45px; text-align: center; font-size: 17px; display: block; margin: 0 auto; padding: 8px 24px; border: none; border-radius: 4px; background-color: #07c160; color:#fff;">打开小程序</button>
+                </template>
+            </wx-open-launch-weapp>
+        </div>
+        <div id="desktop-web-container" class="hidden">
+            <p class="">请在手机打开网页链接</p>
+        </div>
+    </div>
+    <!-- 公众号 JSSDK -->
+    <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+    <script>
+        var config = {
+          appid: {{.T.appid}},
+          path: {{.T.path}},
+          query: {{.T.query}},
+          version: {{.T.env_version}}, //【选填】ENV_VERSION:要打开的小程序版本,正式版为release,体验版为trial,开发版为develop,仅在微信外打开时生效。注意:若不填写,则默认打开正式版小程序。
+        }
+        console.log(config)
+        function docReady(fn) {
+          if (document.readyState === 'complete' || document.readyState === 'interactive') {
+            fn()
+          } else {
+            document.addEventListener('DOMContentLoaded', fn);
+          }
+        }
+
+        docReady(function() {
+          var ua = navigator.userAgent.toLowerCase()
+          var isWXWork = ua.match(/wxwork/i) == 'wxwork'
+          var isWeixin = !isWXWork && ua.match(/MicroMessenger/i) == 'micromessenger'
+          var isMobile = false
+          var isDesktop = false
+          if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) {
+            isMobile = true
+          } else {
+            isDesktop = true
+          }
+          console.warn('ua', ua)
+          console.warn(ua.match(/MicroMessenger/i) == 'micromessenger')
+          var m = ua.match(/MicroMessenger/i)
+          console.warn(m && m[0] === 'micromessenger')
+
+          if (isWeixin) {
+            var containerEl = document.getElementById('wechat-web-container')
+            containerEl.classList.remove('hidden')
+            containerEl.classList.add('full', 'wechat-web-container')
+
+            var launchBtn = document.getElementById('launch-btn')
+            launchBtn.addEventListener('ready', function (e) {
+              console.log('开放标签 ready')
+            })
+            launchBtn.addEventListener('launch', function (e) {
+              console.log('开放标签 success')
+            })
+            launchBtn.addEventListener('error', function (e) {
+              console.log('开放标签 fail', e.detail)
+            })
+
+            wx.config({
+              // debug: true, // 调试时可开启
+              appId: config.appid, // 'wx37f06c38292f7d82',
+              timestamp: 0, // 必填,填任意数字即可
+              nonceStr: 'nonceStr', // 必填,填任意非空字符串即可
+              signature: 'signature', // 必填,填任意非空字符串即可
+              jsApiList: ['chooseImage'], // 安卓上必填一个,随机即可
+              openTagList:['wx-open-launch-weapp'], // 填入打开小程序的开放标签名
+            })
+          } else if (isDesktop) {
+            // 在 pc 上则给提示引导到手机端打开
+            var containerEl = document.getElementById('desktop-web-container')
+            containerEl.classList.remove('hidden')
+            containerEl.classList.add('full', 'desktop-web-container')
+          } else {
+            var containerEl = document.getElementById('public-web-container')
+            containerEl.classList.remove('hidden')
+            containerEl.classList.add('full', 'public-web-container')
+
+            var buttonEl = document.getElementById('public-web-jump-button')
+            var buttonLoadingEl = document.getElementById('public-web-jump-button-loading')
+            openWeapp(() => {
+                buttonEl.classList.remove('weui-btn_loading')
+                buttonLoadingEl.classList.add('hidden')
+            })
+          }
+        })
+
+        function openWeapp(onBeforeJump) {
+            if (onBeforeJump) {
+                onBeforeJump()
+            }
+            // https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/url-scheme.html
+            // location.href = 'weixin://'
+            location.href = `weixin://dl/business/?appid=${config.appid}&path=${config.path}&query=${encodeURIComponent(config.query)}&env_version=${config.version}`
+        }
+    </script>
+    {{include "/common/baiducc.html"}}
+</body>
+
+</html>

+ 500 - 0
src/jfw/modules/bigmember/src/entity/marketAnalysis/analysisPdf.go

@@ -0,0 +1,500 @@
+package marketAnalysis
+
+import (
+	. "app.yhyue.com/moapp/jybase/api"
+	qutil "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
+	. "jy/src/jfw/modules/bigmember/src/config"
+	"jy/src/jfw/modules/bigmember/src/db"
+	"jy/src/jfw/modules/bigmember/src/entity"
+	"jy/src/jfw/modules/bigmember/src/util"
+	"log"
+	"regexp"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	MgoPdfName = "analysis_report_screen"
+)
+
+// FollowProject 大会员关注项目接口
+type AnalysisReportPdf struct {
+	*xweb.Action
+	getPdfDetail xweb.Mapper `xweb:"/analysisReport/getPdfDetail"` //项目分析报告pdf数据api
+	pdfSave      xweb.Mapper `xweb:"/analysisReport/pdfSave"`      //pdf筛选项存储
+	getPdfList   xweb.Mapper `xweb:"/analysisReport/getPdfList"`   //pdf筛选项获取
+	getPdfEmail  xweb.Mapper `xweb:"/analysisReport/getPdfEmail"`  //邮箱回显
+}
+
+var (
+	localNetWorkIp = regexp.MustCompile(`^192\.168\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[0-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[0-9])$`)
+)
+
+// GetPdfDetail 生成pdf文件程序查询接口
+func (this *AnalysisReportPdf) GetPdfDetail() {
+	rData, errMsg := func() (interface{}, error) {
+		//校验是否为合法请求
+		requestIp := this.IP()
+		checkAssess := func() bool { //无身份校验,仅限内网和白名单ip访问
+			if localNetWorkIp.MatchString(requestIp) {
+				return true
+			}
+			if Config.PdfDataApiWhiteList != nil && len(Config.PdfDataApiWhiteList) > 0 {
+				for _, whiteIP := range Config.PdfDataApiWhiteList {
+					if whiteIP == requestIp {
+						return true
+					}
+				}
+			}
+			return false
+		}()
+		if !checkAssess {
+			log.Println("非白名单ip", requestIp)
+			return nil, fmt.Errorf("非法请求")
+		}
+
+		rid := this.GetString("sid") //获取信息id
+		if rid == "" {
+			return nil, fmt.Errorf("缺少参数")
+		}
+		if !mongodb.IsObjectIdHex(rid) {
+			rid = util.DecodeId(rid)
+		}
+		rData, _ := db.Mgo.FindById(MgoPdfName, rid, nil)
+		if rData == nil || len(*rData) == 0 {
+			log.Println("rid==", rid)
+			return nil, fmt.Errorf("未获取数据")
+		}
+		timeRangeMap := make(map[string]int64)
+		timeRange := gconv.String((*rData)["timeRange"])
+		timeRangeArr := strings.Split(timeRange, "_")
+		if len(timeRangeArr) == 2 {
+			start, _ := time.Parse(time.DateOnly, timeRangeArr[0])
+			end, _ := time.Parse(time.DateOnly, timeRangeArr[1])
+			timeRangeMap["start"] = start.Unix()
+			timeRangeMap["end"] = end.Unix()
+		}
+		rMap := make(map[string]interface{})
+		wait := &sync.WaitGroup{}
+		var lock sync.Mutex
+		var err error
+		switch qutil.InterfaceToStr((*rData)["type"]) {
+		case "3":
+			wait.Add(2)
+			pid, _, _ := CheckPowerEquity(this.Session())
+			sessVal := this.Session().GetMultiple()
+			userId := qutil.ObjToString(sessVal["userId"])
+			go func() { //分析数据
+				wait.Done()
+				mae := &MarketAnalysisEntity{MgoRecordId: qutil.InterfaceToStr((*rData)["rid"]), UId: userId, Pid: pid, MgoUserId: qutil.ObjToString(sessVal["mgoUserId"]), PositionId: qutil.IntAll(sessVal["positionId"])}
+				rDataMap, err := mae.GetPdfPageApi()
+				if err != nil {
+					log.Println("GetPdfPageApi", err.Error())
+				}
+				lock.Lock()
+				for s, i := range rDataMap {
+					rMap[s] = i
+				}
+				lock.Unlock()
+			}()
+			go func() { //项目明细
+				defer wait.Done()
+				mae := &MarketAnalysisEntity{MgoRecordId: qutil.InterfaceToStr((*rData)["rid"]), UId: userId, Pid: pid, MgoUserId: qutil.ObjToString(sessVal["mgoUserId"]), PositionId: qutil.IntAll(sessVal["positionId"])}
+				err = mae.GetAnalysisFromMgoDb()
+				if err != nil {
+					log.Println("GetAnalysisFromMgoDb err", err.Error())
+				}
+				err = mae.ForMatData()
+				if err != nil {
+					log.Println("ForMatData err", err.Error())
+				}
+				err = mae.GetProjectInfoList()
+				if err != nil {
+					log.Println("ForMatData err", err.Error())
+				}
+				lock.Lock()
+				rMap["dynamicDetail"] = mae.ProjectInfo.List
+				rMap["dynamicCount"] = mae.ProjectInfo.Count
+				lock.Unlock()
+			}()
+			wait.Wait()
+			(*rData)["rid"] = util.EncodeId(qutil.InterfaceToStr((*rData)["rid"]))
+		case "2": //采购
+			wait.Add(2)
+			go func() { //分析数据
+				defer wait.Done()
+				cepm := &entity.Portrait{}
+				cepm.UserId = qutil.InterfaceToStr((*rData)["user_id"])
+				rDataMap, err := cepm.BuyerPortraitData(&entity.PortraitScreen{
+					Ent:        qutil.InterfaceToStr((*rData)["ent"]),
+					Match:      qutil.InterfaceToStr((*rData)["match"]),
+					ExactMatch: qutil.InterfaceToStr((*rData)["exactMatch"]) == "1",
+					MatchRange: qutil.InterfaceToStr((*rData)["matchRange"]),
+					Area:       qutil.InterfaceToStr((*rData)["area"]),
+					ScopeClass: qutil.InterfaceToStr((*rData)["scopeClass"]),
+					TimeRange:  qutil.InterfaceToStr((*rData)["timeRange"]),
+					HasPower:   true,
+					UserLevel:  1,
+				}, "")
+				if err != nil {
+					log.Println("GetPdfDetail BuyerPortraitData===", err)
+				}
+				lock.Lock()
+				for s, i := range rDataMap {
+					rMap[s] = i
+				}
+				lock.Unlock()
+			}()
+			go func() { //项目明细
+				defer wait.Done()
+				cepm := &entity.Portrait{}
+				cepm.UserId = qutil.InterfaceToStr((*rData)["user_id"])
+				rDataMap, count, _, err := cepm.GetBuyerNewMsg(&entity.PortraitProjectScreen{
+					Screen: &entity.PortraitScreen{
+						Ent:        qutil.InterfaceToStr((*rData)["ent"]),
+						Match:      qutil.InterfaceToStr((*rData)["match"]),
+						ExactMatch: qutil.InterfaceToStr((*rData)["exactMatch"]) == "1",
+						MatchRange: qutil.InterfaceToStr((*rData)["matchRange"]),
+						Area:       qutil.InterfaceToStr((*rData)["area"]),
+						ScopeClass: qutil.InterfaceToStr((*rData)["scopeClass"]),
+						TimeRange:  qutil.InterfaceToStr((*rData)["timeRange"]),
+						HasPower:   true,
+					},
+					Free:     false,
+					PageNum:  1,
+					PageSize: 100,
+				})
+				if err != nil {
+					log.Println("GetPdfDetail GetBuyerNewMsg===", err)
+				}
+				lock.Lock()
+				rMap["dynamicDetail"] = rDataMap
+				rMap["dynamicCount"] = count
+				lock.Unlock()
+			}()
+			wait.Wait()
+			rMap["timeRange"] = timeRangeMap
+		case "1": //中标
+			wait.Add(3)
+			go func() { //分析数据
+				defer wait.Done()
+				cepm := &entity.Portrait{}
+				cepm.UserId = qutil.InterfaceToStr((*rData)["user_id"])
+				rDataMap, err := cepm.WinnerPortraitData(&entity.PortraitScreen{
+					Ent:        qutil.InterfaceToStr((*rData)["ent"]),
+					Match:      qutil.InterfaceToStr((*rData)["match"]),
+					ExactMatch: qutil.InterfaceToStr((*rData)["exactMatch"]) == "1",
+					MatchRange: qutil.InterfaceToStr((*rData)["matchRange"]),
+					Area:       qutil.InterfaceToStr((*rData)["area"]),
+					ScopeClass: qutil.InterfaceToStr((*rData)["scopeClass"]),
+					TimeRange:  qutil.InterfaceToStr((*rData)["timeRange"]),
+					HasPower:   true,
+					BuyerClass: qutil.InterfaceToStr((*rData)["buyerClass"]),
+				})
+				if err != nil {
+					log.Println("GetPdfDetail WinnerPortraitData===", err)
+				}
+				lock.Lock()
+				for s, i := range rDataMap {
+					rMap[s] = i
+				}
+				lock.Unlock()
+			}()
+			go func() { //项目明细
+				defer wait.Done()
+				cepm := &entity.Portrait{}
+				cepm.UserId = qutil.InterfaceToStr((*rData)["user_id"])
+				rDataMap, count, _, err := cepm.GetWinnerNewMsg(&entity.PortraitProjectScreen{
+					Screen: &entity.PortraitScreen{
+						Ent:        qutil.InterfaceToStr((*rData)["ent"]),
+						Match:      qutil.InterfaceToStr((*rData)["match"]),
+						ExactMatch: qutil.InterfaceToStr((*rData)["exactMatch"]) == "1",
+						MatchRange: qutil.InterfaceToStr((*rData)["matchRange"]),
+						Area:       qutil.InterfaceToStr((*rData)["area"]),
+						ScopeClass: qutil.InterfaceToStr((*rData)["scopeClass"]),
+						TimeRange:  qutil.InterfaceToStr((*rData)["timeRange"]),
+						HasPower:   true,
+						BuyerClass: qutil.InterfaceToStr((*rData)["buyerClass"]),
+					},
+					Free:     false,
+					PageNum:  1,
+					PageSize: 100,
+				})
+				if err != nil {
+					log.Println("GetPdfDetail GetWinnerNewMsg===", err)
+				}
+				lock.Lock()
+				rMap["dynamicDetail"] = rDataMap
+				rMap["dynamicCount"] = count
+				lock.Unlock()
+			}()
+			go func() {
+				defer wait.Done()
+				cepm := &entity.Portrait{}
+				entInfo, err := cepm.GetEntInfo(qutil.InterfaceToStr((*rData)["ent"]))
+				if err == nil {
+					lock.Lock()
+					rMap["entInfo"] = entInfo
+					lock.Unlock()
+				}
+			}()
+			wait.Wait()
+
+		}
+		delete(*rData, "_id")
+		rMap["timeRange"] = timeRangeMap
+		rMap["analysis_condition"] = rData
+		return rMap, err
+	}()
+	if errMsg != nil {
+		log.Printf("分析报告pef数据获取异常:%s\n", errMsg.Error())
+	}
+
+	this.ServeJson(NewResult(rData, errMsg))
+}
+
+func (me *MarketAnalysisEntity) GetPdfPageApi() (finalDate map[string]interface{}, err error) {
+	var (
+		wg   = sync.WaitGroup{}
+		lock = &sync.Mutex{}
+	)
+	finalDate = make(map[string]interface{})
+	for i := 1; i <= 5; i++ {
+		wg.Add(1)
+		go func(flag int) {
+			defer wg.Done()
+			mgoData, _ := me.GetMongoData(flag)
+			lock.Lock()
+			for s, i2 := range mgoData {
+				finalDate[s] = i2
+			}
+			lock.Unlock()
+		}(i)
+	}
+	wg.Wait()
+	return
+}
+
+func (this *AnalysisReportPdf) PdfSave() {
+	sessVal := this.Session().GetMultiple()
+	userId := qutil.ObjToString(sessVal["userId"])
+	if userId == "" || userId == "0" {
+		this.ServeJson(NewResult(nil, fmt.Errorf("用户异常")))
+		return
+	}
+	sEmail := this.GetString("s_email")
+	log.Println("s_email", sEmail)
+	if !jy.IsEmail(sEmail) {
+		this.ServeJson(NewResult(nil, fmt.Errorf("邮箱格式不正确")))
+		return
+	}
+	sType := this.GetString("type")
+	var id string
+	res := map[string]interface{}{
+		"type":         sType,
+		"user_id":      userId,
+		"s_email":      sEmail,
+		"l_createTime": time.Now().Unix(),
+	}
+	switch sType {
+	case "3": //定制化分析
+		rid := util.DecodeId(this.GetString("sid")) //获取信息id
+		if rid == "" {
+			this.ServeJson(NewResult(nil, fmt.Errorf("定制化分析异常")))
+			return
+		}
+		pid, _, _ := CheckPowerEquity(this.Session())
+		mae := &MarketAnalysisEntity{MgoRecordId: rid, UId: userId, Pid: pid, MgoUserId: qutil.ObjToString(sessVal["mgoUserId"]), PositionId: qutil.IntAll(sessVal["positionId"])}
+		queryMap := map[string]interface{}{
+			"_id":   mongodb.StringTOBsonId(mae.MgoRecordId),
+			"i_del": map[string]interface{}{"$ne": 1},
+		}
+		if mae.UId == mae.Pid { //主账号
+			queryMap["s_parentId"] = mae.Pid
+		} else {
+			queryMap["s_userId"] = mae.UId
+		}
+		resData, _ := db.Mgo.FindOne(ReportHistoryTable, queryMap)
+		if resData == nil || len(*resData) == 0 {
+			this.ServeJson(NewResult(nil, fmt.Errorf("定制化分析异常")))
+			return
+		}
+		for s, i := range *resData {
+			value := i
+			if _, ok := res[s]; !ok {
+				res[s] = value
+			}
+		}
+		res["rid"] = rid
+	case "2": //采购画像
+		//_, hasPower, err, _ := entity.CreatePortraitManager(this.Session(), "buyerPortrait")
+		//if err != nil {
+		//	return
+		//}
+		entName := this.GetString("buyer")
+		//id转中文
+		if len(entName) > 0 && len([]rune(entName)) == len(entName) {
+			//获取中文名字
+			entName = getBuyerNameById(util.DecodeId(entName))
+		}
+		if entName == "" {
+			this.ServeJson(NewResult(nil, fmt.Errorf("采购单位异常")))
+			return
+		}
+		res["ent"] = entName
+		res["entName"] = entName
+		res["match"] = this.GetString("match")
+		res["exactMatch"] = this.GetString("exactMatch")
+		res["matchRange"] = this.GetString("matchRange")
+		res["area"] = this.GetString("area")
+		res["scopeClass"] = this.GetString("scopeClass")
+		timeRange := this.GetString("timeRange")
+		tRange := strings.Split(timeRange, "_")
+		if len(tRange) != 2 {
+			this.ServeJson(NewResult(util.EncodeId(id), fmt.Errorf("错误时间格式")))
+			return
+		}
+		st := fmt.Sprintf("%s-01-01", tRange[0])
+		et := fmt.Sprintf("%s-12-31", tRange[1])
+		if time.Now().Year() == qutil.IntAll(tRange[1]) {
+			et = fmt.Sprintf("%04d-%02d-%02d", time.Now().Year(), int(time.Now().Month()), time.Now().Day())
+		}
+		res["timeRange"] = fmt.Sprintf("%s_%s", st, et)
+		//res["hasPower"] = hasPower
+	case "1": //中标画像
+		//_, hasPower, err, _ := entity.CreatePortraitManager(this.Session(), "entPortrait")
+		//if err != nil {
+		//	return
+		//}
+		entId := this.GetString("entId")
+		if util.DecodeId(entId) == "" {
+			this.ServeJson(NewResult(util.EncodeId(id), fmt.Errorf("企业名称异常")))
+			return
+		}
+		res["ent"] = util.DecodeId(entId)
+		res["entName"] = this.GetString("entName")
+		res["match"] = this.GetString("match")
+		res["exactMatch"] = this.GetString("exactMatch")
+		res["matchRange"] = this.GetString("matchRange")
+		res["area"] = this.GetString("area")
+		res["scopeClass"] = this.GetString("scopeClass")
+		tRange := strings.Split(this.GetString("timeRange"), "_")
+		if len(tRange) != 2 {
+			this.ServeJson(NewResult(util.EncodeId(id), fmt.Errorf("错误时间格式")))
+			return
+		}
+		st := fmt.Sprintf("%s-01-01", tRange[0])
+		et := fmt.Sprintf("%s-12-31", tRange[1])
+		if time.Now().Year() == qutil.IntAll(tRange[1]) {
+			et = fmt.Sprintf("%04d-%02d-%02d", time.Now().Year(), int(time.Now().Month()), time.Now().Day())
+		}
+		res["timeRange"] = fmt.Sprintf("%s_%s", st, et)
+		res["s_buyerClass"] = this.GetString("buyerClass")
+	}
+	id = db.Mgo.Save(MgoPdfName, res)
+	this.ServeJson(NewResult(util.EncodeId(id), nil))
+	return
+}
+
+func getBuyerNameById(buyerId string) (buyerName string) {
+	rs := db.MysqlGloabl.SelectBySql(`SELECT name  FROM dws_f_ent_baseinfo where name_id=? and (identity_type &(1 << 0)) > 0 limit 1`, buyerId)
+	if rs != nil && len(*rs) > 0 {
+		return qutil.InterfaceToStr((*rs)[0]["name"])
+	}
+	return
+}
+
+func (this *AnalysisReportPdf) GetPdfList() {
+	sessVal := this.Session().GetMultiple()
+	userId := qutil.ObjToString(sessVal["userId"])
+	page, _ := this.GetInt("page")
+	size, _ := this.GetInt("size")
+	if userId == "" || userId == "0" {
+		return
+	}
+	if page < 1 {
+		page = 1
+	}
+	if size < 1 {
+		size = 10
+	}
+	var count int
+	query := map[string]interface{}{
+		"s_pdfUrl": map[string]interface{}{"$exists": true},
+		"user_id":  userId,
+	}
+	if mongodb.IsObjectIdHex(userId) { //个人身份 获取父id
+		main_userId, _, _ := util.MainUserId(this.Session())
+		query = map[string]interface{}{
+			"s_pdfUrl": map[string]interface{}{"$exists": true},
+			"$or": []map[string]interface{}{
+				{"user_id": userId},
+				{"s_pid": main_userId},
+			},
+		}
+	}
+	if page == 1 {
+		count = db.Mgo.Count(MgoPdfName, query)
+	}
+
+	rArr, err := db.Mgo.Find(MgoPdfName, query, `{"l_createTime":-1}`, nil, false, int((page-1)*size), int(size))
+	if !err || rArr == nil || len(*rArr) == 0 {
+		return
+	}
+	for _, m := range *rArr {
+		m["_id"] = util.EncodeId(qutil.InterfaceToStr(m["_id"]))
+		if pdfUrl := m["s_pdfUrl"]; pdfUrl != nil && pdfUrl != "" {
+			m["s_pdfUrl"] = fmt.Sprintf("%s%s", Config.MainWebDomain, pdfUrl)
+			m["s_appPdfUrl"] = pdfUrl
+		}
+		if qutil.IntAll(m["type"]) == 1 && !strings.Contains(qutil.InterfaceToStr(m["ent"]), "ABC") { //企业id加密
+			m["ent"] = util.EncodeId(qutil.InterfaceToStr(m["ent"]))
+		}
+	}
+
+	this.ServeJson(NewResult(map[string]interface{}{
+		"count": count,
+		"list":  rArr,
+	}, nil))
+}
+
+// checkPower 权限校验 增加判断权益 过滤字段
+func CheckPowerEquity(session *httpsession.Session) (string, bool, error) {
+	userid := fmt.Sprint(qutil.Int64All(session.Get("base_user_id")))
+	if userid == "" || userid == "0" {
+		return "", false, fmt.Errorf("未登录")
+	}
+	//仅购买《定制化市场分析报告》的大会员有权限
+	bigMeg := jy.GetBigVipUserBaseMsg(session, *Middleground)
+	return bigMeg.Pid, bigMeg.PowerMap[26], nil
+}
+
+func (this *AnalysisReportPdf) GetPdfEmail() {
+	sessVal := this.Session().GetMultiple()
+	userId := qutil.ObjToString(sessVal["userId"])
+	if userId == "" || userId == "0" {
+		return
+	}
+	var sEmail string
+	rArr, err := db.Mgo.Find(MgoPdfName, map[string]interface{}{"user_id": userId}, `{"l_createTime":-1}`, nil, true, 0, 1)
+	if err && rArr != nil && len(*rArr) > 0 {
+		sEmail = qutil.InterfaceToStr((*rArr)[0]["s_email"])
+	}
+
+	if sEmail == "" {
+		mgoUserId := qutil.ObjToString(sessVal["mgoUserId"])
+		fData := Compatible.Select(mgoUserId, `{"s_myemail":1}`)
+		if fData != nil && len(*fData) > 0 {
+			sEmail = qutil.InterfaceToStr((*fData)["s_myemail"])
+		}
+		//
+	}
+	this.ServeJson(NewResult(sEmail, nil))
+}

+ 4 - 4
src/jfw/modules/bigmember/src/entity/marketAnalysis/customized_analysis.go

@@ -14,12 +14,12 @@ const (
 	query_aggs_sortprice       = `"sortprice_ranges": {"range":{"field":"sortprice","ranges":[%s]},"aggs":{"sum_sortprice":{"sum":{"field":"sortprice"}}}}`
 	aggs_area                  = `"area_distribution": {"terms": {"field": "area","size": 40},"aggs": {"area_amount": {"sum": {"field": "sortprice"}},"area_total": {"filter": {"match_all":{}}},"city_group": {"terms": {"field": "city","size": 40},"aggs": {"city_amount": {"sum": {"field": "sortprice"}}}}}}`
 	query_top10                = `,"sort": [{"sortprice": "desc"}],"from": 0,"size": 10`
-	aggs_area_amounttop3       = `"area_amount_top3":{"terms":{"field":"area","exclude":["全国"],"order":[{"area_amount":"desc"}],"size":3},"aggs":{"area_amount":{"sum":{"field":"sortprice"}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"area_winner_amount":"desc"}],"size":3},"aggs":{"area_winner_amount":{"sum":{"field":"sortprice"}}}}}}`
-	aggs_area_counttop3        = `"area_count_top3":{"terms":{"field":"area","exclude":["全国"],"order":[{"area_count":"desc"}],"size":3},"aggs":{"area_count":{"filter":{"match_all":{}}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"area_winner_count":"desc"}],"size":3},"aggs":{"area_winner_count":{"filter":{"match_all":{}}}}}}}`
+	aggs_area_amounttop3       = `"area_amount_top3":{"terms":{"field":"area","exclude":["全国"],"order":[{"area_amount":"desc"}],"size":34},"aggs":{"area_amount":{"sum":{"field":"sortprice"}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"area_winner_amount":"desc"}],"size":3},"aggs":{"area_winner_amount":{"sum":{"field":"sortprice"}}}}}}`
+	aggs_area_counttop3        = `"area_count_top3":{"terms":{"field":"area","exclude":["全国"],"order":[{"area_count":"desc"}],"size":40},"aggs":{"area_count":{"filter":{"match_all":{}}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"area_winner_count":"desc"}],"size":3},"aggs":{"area_winner_count":{"filter":{"match_all":{}}}}}}}`
 	aggs_buyerclass            = `"buyerclass_scale":{"terms":{"field":"buyerclass","size":2000,"exclude":["其它",""]},"aggs":{"buyerclass_amount":{"sum":{"field":"sortprice"}},"buyerclass_total":{"filter":{"match_all":{}}}}}`
 	aggs_buyerclass_other      = `"buyerclass_scale_other":{"terms":{"field":"buyerclass","include":["其它",""]},"aggs":{"buyerclass_amount":{"sum":{"field":"sortprice"}},"buyerclass_total":{"filter":{"match_all":{}}}}}`
-	aggs_buyerclass_counttop3  = `"buyerclass_count_top3":{"terms":{"field":"buyerclass","exclude":["其它",""],"order":[{"buyerclass_count":"desc"}],"size":3},"aggs":{"buyerclass_count":{"filter":{"match_all":{}}},"bidcount_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"buyer_winner_count":"desc"}],"size":3},"aggs":{"buyer_winner_count":{"filter":{"match_all":{}}}}}}}`
-	aggs_buyerclass_amounttop3 = `"buyerclass_amount_top3":{"terms":{"field":"buyerclass","exclude":["其它",""],"order":[{"buyerclass_amount":"desc"}],"size":3},"aggs":{"buyerclass_amount":{"sum":{"field":"sortprice"}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"buyer_winner_amount":"desc"}],"size":3},"aggs":{"buyer_winner_amount":{"sum":{"field":"sortprice"}}}}}}`
+	aggs_buyerclass_counttop3  = `"buyerclass_count_top3":{"terms":{"field":"buyerclass","exclude":["其它",""],"order":[{"buyerclass_count":"desc"}],"size":70},"aggs":{"buyerclass_count":{"filter":{"match_all":{}}},"bidcount_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"buyer_winner_count":"desc"}],"size":3},"aggs":{"buyer_winner_count":{"filter":{"match_all":{}}}}}}}`
+	aggs_buyerclass_amounttop3 = `"buyerclass_amount_top3":{"terms":{"field":"buyerclass","exclude":["其它",""],"order":[{"buyerclass_amount":"desc"}],"size":70},"aggs":{"buyerclass_amount":{"sum":{"field":"sortprice"}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"buyer_winner_amount":"desc"}],"size":3},"aggs":{"buyer_winner_amount":{"sum":{"field":"sortprice"}}}}}}`
 	sortprice_str              = `{"key":"<10万","from":0.0000000000001,"to":100000},{"key":"10万-50万","from":100000,"to":500000},{"key":"50万-100万","from":500000,"to":1000000},{"key":"100万-500万","from":1000000,"to":5000000},{"key":"500万-1000万","from":5000000,"to":10000000},{"key":"1000万-1亿","from":10000000,"to":100000000},{"key":"≥1亿","from":100000000}`
 	aggs_all_c_m               = `"project_count": {"filter": {"match_all":{}}},"project_count_not0": {"filter": {"range": {"sortprice": {"gt": 0}}}},"project_amount": {"sum": {"field": "sortprice"}}`
 	query_id                   = `{"query": {"bool": {"must": [{"term": {"entidlist": "%s"}}]}},"size": 1}`

+ 29 - 0
src/jfw/modules/bigmember/src/entity/marketAnalysis/marketAnalysisEntity.go

@@ -478,6 +478,26 @@ func (mae *MarketAnalysisEntity) GetRecordList(pageNum, PageSize int, positionTy
 	if res == nil || len(*res) == 0 {
 		return
 	}
+	var ids []string
+	for _, m := range *res {
+		ids = append(ids, qutil.InterfaceToStr(m["_id"]))
+	}
+	idMap := make(map[string]map[string]interface{})
+	tName, _ := GetMongoColl(marketScaleMain)
+	mids, _ := db.Mgo.Find(tName, map[string]interface{}{
+		"s_m_id": map[string]interface{}{
+			"$in": ids,
+		},
+	}, "", `{"market_profile":1,"s_m_id":1}`, false, -1, -1)
+	if mids != nil && len(*mids) > 0 {
+		for _, m := range *mids {
+			marketProfile, _ := m["market_profile"].(map[string]interface{})
+			if qutil.IntAll(marketProfile["project_count"]) > 0 {
+				idMap[qutil.InterfaceToStr(m["s_m_id"])] = marketProfile
+			}
+		}
+	}
+
 	//用户消息开关
 	open := GetMsgOpen(mae.MgoUserId, positionType, entId, entUserId)
 	for _, row := range *res {
@@ -488,6 +508,13 @@ func (mae *MarketAnalysisEntity) GetRecordList(pageNum, PageSize int, positionTy
 				status = ReportStateGenerating // 生成失败对外还是展示为生成中
 			}
 		}
+		var (
+			isDownload bool
+		)
+		marketProfile := make(map[string]interface{})
+		if marketProfile = idMap[mongodb.BsonIdToSId(row["_id"])]; marketProfile != nil && qutil.IntAll(marketProfile["project_count"]) > 0 && status == 1 {
+			isDownload = true
+		}
 		data := map[string]interface{}{
 			"id":               util.EncodeId(mongodb.BsonIdToSId(row["_id"])),
 			"keysItems":        qutil.ObjToString(row["s_keysItems"]),
@@ -501,6 +528,8 @@ func (mae *MarketAnalysisEntity) GetRecordList(pageNum, PageSize int, positionTy
 			"state":            qutil.If(row["i_state"] == nil, nil, status),
 			"updateTime":       qutil.Int64All(row["l_updateTime"]),
 			"msgOpen":          open,
+			"isDownload":       isDownload,
+			"marketProfile":    marketProfile,
 		}
 		list = append(list, data)
 	}

+ 2 - 2
src/jfw/modules/bigmember/src/entity/marketAnalysis/scaleRefineQuery.go

@@ -14,8 +14,8 @@ const (
 	onlyAmount
 	totalAndAmount
 
-	topWinnerLimit = 3 //细分市场展示前x个企业
-	topItemLimit   = 3 //返回前x组关键词
+	topWinnerLimit = 3   //细分市场展示前x个企业
+	topItemLimit   = 300 //返回前x组关键词
 )
 
 type scaleRefineData struct {

+ 3 - 3
src/jfw/modules/bigmember/src/entity/portrait.go

@@ -158,7 +158,7 @@ func CreateSubVipPortraitManager(userid string, pageFlag, searchValue string, is
 		bigMsg := jy.GetBigVipUserBaseMsg(session, *config.Middleground)
 		if bigMsg.VipStatus <= 0 || bigMsg.Vip_BuySet.Upgrade != 1 { //免费用户留资体验
 			if searchValue != "" && jy.Portraitexperience(userid, searchValue, isWinner) {
-				return &Portrait{userid, session}, 3, nil, true
+				return &Portrait{userid, session}, 3, nil, false
 			}
 			return &Portrait{userid, session}, -1, nil, true
 		} else { //超级订阅升级版-校验超级订阅画像浏览次数
@@ -198,13 +198,14 @@ func CreateSubVipPortraitManagerForOpen(userid string, pageFlag, searchValue str
 		}
 		if bigMsg.VipStatus <= 0 || bigMsg.Vip_BuySet.Upgrade != 1 { //免费用户留资体验
 			if searchValue != "" && jy.Portraitexperience(userid, searchValue, isWinner) {
+				free = false
 				return &Portrait{userid, session}, 3, nil, free
 			}
 			return &Portrait{userid, session}, -1, nil, free
 		} else { //超级订阅升级版-校验超级订阅画像浏览次数
 			err := bigMsg.NewSubVipPortrait(db.Mysql, searchValue, isWinner).SubVipPortraitTimesCheck()
 			if err == nil {
-				return &Portrait{userid, session}, 2, nil, free
+				return &Portrait{userid, session}, 2, nil, true
 			} else {
 				log.Printf("用户%s 超级订阅使用画像%s次数异常 %v\n", userid, searchValue, err)
 			}
@@ -452,7 +453,6 @@ func (this *Portrait) BuyerPortraitData(screen *PortraitScreen, flag string) (ma
 		return nil, errors.New("企业名称异常")
 	}
 	buyerPortraitData := map[string]interface{}{}
-
 	if screen.IsEmptySearch() { //空查询读缓存
 		buyerPortraitData = TryFunc(GetPortraitCache, screen.Ent, "buyer", qutil.If(screen.UserLevel == 3, 2, 5).(int), screen.UserLevel)
 	} else if screen.UserLevel != 3 { //3:未登录用户不能使用条件查询,只能进行空搜索

+ 1 - 1
src/jfw/modules/bigmember/src/entity/portraitBuyerSearch.go

@@ -127,7 +127,7 @@ func BuyerPortraitSearch(screen *PortraitScreen) (map[string]interface{}, error)
 	tBegin := time.Now()
 	doSearchSql := fmt.Sprintf(buyerPortraitSearchSql, strings.Join(mustQueryArr, ","), bidamountTimeRange, getMoneyRange(), comminTimeRange, comminTimeRange)
 	res, count := util.GetAggsWithCount("projectset", "projectset", doSearchSql)
-	//log.Println("buyerSearchSql", doSearchSql)
+	log.Println("buyerSearchSql", doSearchSql)
 	if res == nil {
 		return nil, errors.New(fmt.Sprintf("%s采购单位画像查询异常\n", screen.Ent))
 	}

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

@@ -19,7 +19,7 @@ import (
 
 const (
 	matchWordLenLimit                = 50
-	tableShowNumLimit                = 40
+	tableShowNumLimit                = 100 //pdf导出数据修改为100
 	dataExportBatchSearchLimit int64 = 500
 	biddingIndex, biddingType        = "bidding", "bidding"
 	projectIndex, projectType        = "projectset", "projectset"
@@ -109,8 +109,36 @@ func (ps *PortraitScreen) PareMatchType(isProject bool) (items []string) {
 	return
 }
 
+func TimeParse(str string) (st, et time.Time, err error) {
+	tRanges := strings.Split(str, "_")
+	if len(tRanges) == 2 {
+		// 使用 time.Parse 进行校验
+		st, err = time.Parse(time.DateOnly, tRanges[0])
+		if err != nil {
+			return
+		}
+		et, err = time.Parse(time.DateOnly, tRanges[1])
+		if err != nil {
+			return
+		}
+		et = et.AddDate(0, 0, 1)
+	} else {
+		err = fmt.Errorf("时间格式非年月日格式")
+	}
+	return
+}
+
 // PareTimeSelect 格式筛选时间,默认2年
 func (ps *PortraitScreen) PareTimeSelect(checkPower bool) (st, et time.Time) {
+	//检验是否为具体年月日
+	if ps.TimeRange != "" {
+		if stm, etm, err := TimeParse(ps.TimeRange); err == nil { //分析历史数据支持时间格式
+			st = stm
+			et = etm
+			return
+		}
+	}
+
 	now := time.Now()
 	//interval := now.Year() - 4
 	sYear := config.Config.PortraitStartTime //不得早于2018年 p311
@@ -250,7 +278,6 @@ func (pwp *PortraitProjectScreen) GetWinnerListSearch() (list *[]map[string]inte
 	mustQueryArr := pwp.CommonPare(true)
 	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.Screen.HasPower || pwp.Free {
 		return pwp.FreePortraitNews(mustQueryArr, true)
 	}
@@ -267,7 +294,7 @@ func (pwp *PortraitProjectScreen) GetWinnerListSearch() (list *[]map[string]inte
 	}
 	start, limit := (pwp.PageNum-1)*pwp.PageSize, pwp.PageSize
 	fields := `"_id","projectname","bidamount","budget","title","publishtime","subtype","toptype","area"`
-	if start+limit <= tableShowNumLimit { //展示表格数据
+	if start+limit <= tableShowNumLimit { //展示表格数据||pdf导出数据
 		fields += `,"bidopentime","buyer"`
 	}
 	//列表查询

+ 4 - 0
src/jfw/modules/bigmember/src/filter/sessionfilter.go

@@ -51,6 +51,10 @@ func (l *sessionfilter) Do(w http.ResponseWriter, req *http.Request) bool {
 		strings.Contains(req.URL.Path, "/bigmember/analysis/projectInfo") || strings.Contains(req.URL.Path, "/bigmember/project/getPdfDetail") {
 		return true
 	}
+	//pdf数据返回
+	if strings.Contains(req.URL.Path, "/bigmember/analysisReport/getPdfDetail") {
+		return true
+	}
 	//企业画像部分免费功能接口开放
 	if strings.Contains(req.URL.Path, "/bigmember/portrait/subVipPortrait/entDetail") { //超级订阅页面基本信息接口
 		return true

+ 2 - 0
src/jfw/modules/bigmember/src/service/init.go

@@ -1,6 +1,7 @@
 package service
 
 import (
+	"jy/src/jfw/modules/bigmember/src/entity/marketAnalysis"
 	"jy/src/jfw/modules/bigmember/src/service/analysis"
 	"jy/src/jfw/modules/bigmember/src/service/bidfile"
 	"jy/src/jfw/modules/bigmember/src/service/chatShare"
@@ -33,4 +34,5 @@ func init() {
 	xweb.AddAction(&bidfile.Bidfile{})
 	xweb.AddAction(&report.MarketAnalysis{})
 	xweb.AddAction(&chatShare.ChatShareProject{})
+	xweb.AddAction(&marketAnalysis.AnalysisReportPdf{})
 }

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

@@ -194,7 +194,7 @@ func (this *SubVipPortrait) SubVipPortrait() {
 		if err != nil {
 			return nil, err
 		}
-		if power <= 1 {
+		if userId == "" && power <= 1 {
 			return nil, fmt.Errorf("无查看权益")
 		}
 		rData, err := cepm.WinnerPortraitData(&entity.PortraitScreen{
@@ -467,7 +467,7 @@ func (this *SubVipPortrait) BuyerPortrait() {
 			return nil, err
 		}
 		redisKey := fmt.Sprintf("buyerPortraitKey_%s", buyerName)
-		if userId == "" || power <= 1 {
+		if userId == "" && power <= 1 {
 			if bytes, err := redis.GetBytes("other", redisKey); err == nil && bytes != nil {
 				rData := make(map[string]interface{})
 				if err = json.Unmarshal(*bytes, &rData); err != nil {

+ 2 - 2
src/jfw/modules/bigmember/src/service/report/marketAnalysis.go

@@ -124,7 +124,7 @@ func checkPower(session *httpsession.Session) (string, error) {
 }
 
 // checkPower 权限校验 增加判断权益 过滤字段
-func checkPowerEquity(session *httpsession.Session) (string, bool, error) {
+func CheckPowerEquity(session *httpsession.Session) (string, bool, error) {
 	userid := fmt.Sprint(qutil.Int64All(session.Get("base_user_id")))
 	if userid == "" || userid == "0" {
 		return "", false, fmt.Errorf("未登录")
@@ -299,7 +299,7 @@ func (this *MarketAnalysis) GetAnalysisResult() {
 	userId := qutil.ObjToString(sessVal["userId"])
 	positionId := qutil.IntAll(sessVal["positionId"])
 	rData, errMsg := func() (interface{}, error) {
-		pid, isEquity, powerErr := checkPowerEquity(this.Session())
+		pid, isEquity, powerErr := CheckPowerEquity(this.Session())
 		if powerErr != nil {
 			return nil, powerErr
 		}

+ 3 - 0
src/jfw/modules/publicapply/src/detail/config.json

@@ -153,5 +153,8 @@
       "doPool": 5,
       "waitPool": 5
     }
+  },
+  "active": {
+    "url": "https://mp.weixin.qq.com/s?__biz=Mzk0MjIyMzY2Nw==&mid=2247497302&idx=1&sn=a199495eae763f055a23056f66250ec7&chksm=c2c4ce0af5b3471cace36ae9922d57095f76642b828c2ba0765739e23b1893c3ccb0084c04dc#rd"
   }
 }

+ 2 - 0
src/jfw/modules/publicapply/src/detail/consts/consts.go

@@ -27,6 +27,7 @@ const (
 	PIndex                   = "projectset"
 	PType                    = "projectset"
 	AreaLabelLink            = "/list/%s/%s.html"
+	TableActivateBidding     = "jyactivities.activate_count"
 )
 
 var (
@@ -46,6 +47,7 @@ var (
 	SuffixMsgT          = "_SX"
 	NotLoginPage        = "/notin/page"
 	CacheKey            = "jydetail_%s_%s_%s_%s"
+	MinCacheKey         = "jydetail_min_%s_%s"
 	AheadCacheKey       = "jyahead_%s_%s"
 	PSCacheKey          = "jydetail_project_schedule_%s"
 	QyxyEntNameCacheKey = "jydetail_qyxy_%s"

+ 72 - 0
src/jfw/modules/publicapply/src/detail/dao/baseInfo.go

@@ -201,3 +201,75 @@ func (b *BaseInfo) BidBaseInfo() (bi *entity.BidInfo, err error) {
 	}
 	return
 }
+func (b *BaseInfo) MinBidBaseInfo() (bi *entity.BidInfo, err error) {
+	//招标数据基本信息并发过滤
+	if dc.Config.RestrictionSwitch {
+		if err = rest.ReqCheck("baseInfo"); err != nil {
+			return
+		}
+	}
+	//redis 缓存数据
+	detailCacheKey := fmt.Sprintf(consts.MinCacheKey, b.Id, common.If(b.IsMobile, "mobile", "pc"))
+	//数据获取及简单处理
+	var bidInfo = func() {
+		_, obj := GetBiddingData(b.Id)
+		if len(obj) == 0 {
+			err = fmt.Errorf("未查到当前招标信息")
+			log.Println("--未查到数据--:", b.Id)
+			return
+		}
+		//数据格式化
+		bi_ := BiddingDataFormat(obj, b.Id, false)
+		bi = &entity.BidInfo{
+			BaseInfo: bi_.BaseInfo,
+			Abstract: bi_.Abstract,
+		}
+		if !b.IsMobile {
+			//地址 电脑端
+			switch {
+			case bi.BaseInfo.District != "" && db.DistrictMap[bi.BaseInfo.District] != "":
+				bi.BaseInfo.AreaUrl = fmt.Sprintf(consts.AreaLabelLink, "city", db.DistrictMap[bi.BaseInfo.District])
+			case bi.BaseInfo.City != "" && db.CityMap[bi.BaseInfo.City] != "":
+				bi.BaseInfo.AreaUrl = fmt.Sprintf(consts.AreaLabelLink, "city", db.CityMap[bi.BaseInfo.City])
+			case bi.BaseInfo.Area != "" && db.AreaMap[bi.BaseInfo.Area] != "":
+				bi.BaseInfo.AreaUrl = fmt.Sprintf(consts.AreaLabelLink, "area", db.AreaMap[bi.BaseInfo.Area])
+			}
+			bi.BaseInfo.SubTypeUrl = consts.PageTypeUrlMap[bi.BaseInfo.TopType]
+			bi.BaseInfo.IndustryUrl = "" //已取消
+		}
+		if consts.SpecialArea[bi.BaseInfo.Area] {
+			bi.BaseInfo.Area = ""
+		}
+		if bi.BaseInfo.ProjectName != "" {
+			b.Sess.Set("projectname", bi.BaseInfo.ProjectName)
+		}
+		//数字打码
+		if bi.BaseInfo.Site == consts.JyTxt {
+			NumberCodeFormat(bi)
+		}
+		bi.BaseInfo.Description = DescriptionHandle(b.PageType, obj)
+		//存缓存
+		redis.Put(consts.RedisLimitation, detailCacheKey, bi, consts.DetailRedisByFreeTimeOut)
+	}
+	//如果缓存没有数据 查看 是否有权限
+	res, errRids := redis.GetBytes(consts.RedisLimitation, detailCacheKey)
+	if errRids != nil || res == nil || len(*res) == 0 {
+		bidInfo()
+	} else {
+		err = json.Unmarshal(*res, &bi)
+		if err != nil {
+			bidInfo()
+		}
+	}
+	return
+}
+
+// GetBid 获取活动用户的id
+func GetBid(auId string) (bid string) {
+	rs := db.BaseMysql.SelectBySql(fmt.Sprintf("select bidding_id from %s  where  au_id=?", consts.TableActivateBidding), auId)
+	if rs == nil || len(*rs) == 0 {
+		return
+	}
+	bid = common.InterfaceToStr((*rs)[0]["bidding_id"])
+	return
+}

+ 3 - 0
src/jfw/modules/publicapply/src/detail/entity/config.go

@@ -12,6 +12,9 @@ type Config struct {
 	BidServices        []Service
 	RestrictionSwitch  bool
 	Restrictions       map[string]reqLimit
+	Active             struct { // p583 活动
+		Url string `json:"url"` // 推文地址
+	} `json:"active"`
 }
 
 type reqLimit struct {

+ 6 - 5
src/jfw/modules/publicapply/src/detail/service/action.go

@@ -3,9 +3,10 @@ package service
 import "app.yhyue.com/moapp/jybase/go-xweb/xweb"
 
 type Detail struct {
-	*xweb.Action
-	preAgent     xweb.Mapper `xweb:"/detail/preAgent"`     //数据处理 前置代理接口返回 有效token ;get 请求
-	baseInfo     xweb.Mapper `xweb:"/detail/baseInfo"`     //招标数据基本信息接口(公告信息、摘要、正文、原文、附件信息、打赏文案)
-	advancedInfo xweb.Mapper `xweb:"/detail/advancedInfo"` //招标数据进阶信息(招标/采购进度、投标服务、商机推荐、客户推荐)
-	shareInfo    xweb.Mapper `xweb:"/detail/shareInfo"`    //分享所需要的信息
+    *xweb.Action
+    preAgent     xweb.Mapper `xweb:"/detail/preAgent"`     //数据处理 前置代理接口返回 有效token ;get 请求
+    baseInfo     xweb.Mapper `xweb:"/detail/baseInfo"`     //招标数据基本信息接口(公告信息、摘要、正文、原文、附件信息、打赏文案)
+    minBaseInfo  xweb.Mapper `xweb:"/detail/minBaseInfo"`  //招标数据基本信息接口
+    advancedInfo xweb.Mapper `xweb:"/detail/advancedInfo"` //招标数据进阶信息(招标/采购进度、投标服务、商机推荐、客户推荐)
+    shareInfo    xweb.Mapper `xweb:"/detail/shareInfo"`    //分享所需要的信息
 }

+ 49 - 0
src/jfw/modules/publicapply/src/detail/service/service.go

@@ -4,7 +4,10 @@ import (
 	. "app.yhyue.com/moapp/jybase/api"
 	"app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/encrypt"
+	"encoding/json"
+	"jy/src/jfw/modules/publicapply/src/detail/config"
 	"jy/src/jfw/modules/publicapply/src/detail/dao"
+	"jy/src/jfw/modules/publicapply/src/detail/entity"
 	"jy/src/jfw/modules/publicapply/src/detail/util"
 )
 
@@ -133,3 +136,49 @@ func (d *Detail) ShareInfo() {
 	}()
 	d.ServeJson(r)
 }
+
+// MinBaseInfo p583 未关注用户用的
+func (d *Detail) MinBaseInfo() {
+	defer common.Catch()
+	r := func() Result {
+		if d.Method() != "POST" {
+			return Result{Data: nil, Error_msg: Error_msg_1005}
+		}
+		//接收参数
+		// 查询 标讯id
+		if string(d.Body()) == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		param := struct {
+			Id string
+		}{}
+		//接收参数
+		err := json.Unmarshal(d.Body(), &param)
+		if err != nil || param.Id == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		auId := param.Id
+		id := encrypt.SE.DecodeString(auId)
+		if id == "" {
+			return Result{Data: nil, Error_msg: Error_msg_1003}
+		}
+		bid := dao.GetBid(id)
+		if bid == "" {
+			return Result{Data: nil, Error_code: -1, Error_msg: Error_msg_1003}
+		}
+		baseInfo := dao.NewBaseInfo(bid, "", util.SessUserInfo{}, "", d.Session(), d.Request)
+		data, err1 := baseInfo.MinBidBaseInfo()
+		if err1 != nil {
+			return Result{Error_code: -1, Error_msg: err1.Error()}
+		}
+		rs := struct {
+			*entity.BidInfo
+			WxUrl string `json:"wxUrl"`
+		}{
+			data,
+			config.Config.Active.Url,
+		}
+		return util.DataFormat(rs)
+	}()
+	d.ServeJson(r)
+}

+ 45 - 41
src/jfw/modules/publicapply/src/filter/sessionfilter.go

@@ -1,20 +1,20 @@
 package filter
 
 import (
-    . "jy/src/jfw/modules/publicapply/src/config"
-    . "jy/src/jfw/modules/publicapply/src/db"
-    "net/http"
-    "regexp"
+	. "jy/src/jfw/modules/publicapply/src/config"
+	. "jy/src/jfw/modules/publicapply/src/db"
+	"net/http"
+	"regexp"
 
-    . "app.yhyue.com/moapp/jybase/api"
-    util "app.yhyue.com/moapp/jybase/common"
-    "app.yhyue.com/moapp/jybase/go-xweb/xweb"
-    "app.yhyue.com/moapp/jypkg/identity"
+	. "app.yhyue.com/moapp/jybase/api"
+	util "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"app.yhyue.com/moapp/jypkg/identity"
 )
 
 // 登录限制
 type sessionfilter struct {
-    App *xweb.App
+	App *xweb.App
 }
 
 var reg = regexp.MustCompile("^/publicapply/free/.*")
@@ -26,37 +26,41 @@ var regOneClick = regexp.MustCompile("^/publicapply/(oneClick|channel)/.*")
 var regOriginalText = regexp.MustCompile("^/publicapply/userbase/getOriginalText$")
 var regActivityDayInfo = regexp.MustCompile("^/publicapply/activity/day/info$")              // p477天天抢会员活动活动信息接口未登录也可以访问
 var regDeatil = regexp.MustCompile("^/publicapply/detail/(preAgent|baseInfo|advancedInfo)$") // p406 详情页改版 部分类型未登录也可以查看 所以在接口里面在处理
+var regMinDeatil = regexp.MustCompile("^/publicapply/detail/minBaseInfo$")                   // p406 详情页改版 部分类型未登录也可以查看 所以在接口里面在处理
 func (l *sessionfilter) Do(w http.ResponseWriter, req *http.Request) bool {
-    session := l.App.SessionManager.Session(req, w)
-    getSession := session.GetMultiple()
-    if getSession["userId"] != nil && getSession["mgoUserId"] == nil && util.Int64All(getSession["positionType"]) == 0 {
-        session.Set("mgoUserId", getSession["userId"])
-    }
-    if getSession["base_user_id"] != nil && getSession["positionId"] == nil {
-        identity.SwitchToBest(util.Int64All(getSession["base_user_id"]), session, Middleground, &Mgo, false)
-    }
-    if regOneClick.MatchString(req.URL.Path) {
-        return true
-    }
-    if regEntSearch.MatchString(req.URL.Path) || reg.MatchString(req.URL.Path) || reg.MatchString(req.URL.Path) || reg_share.MatchString(req.URL.Path) || reg_nps.MatchString(req.URL.Path) {
-        return true
-    }
-    if regWhiteList.MatchString(req.URL.Path) { // 判断用户是不是白名单接口不拦截
-        return true
-    }
-    if regOriginalText.MatchString(req.URL.Path) { // 查看原文不拦截  在接口里面判断登录
-        return true
-    }
-    if regActivityDayInfo.MatchString(req.URL.Path) { // p477 天天抢会员活动 活动信息未登录也可以访问
-        return true
-    }
-    if regDeatil.MatchString(req.URL.Path) { // p406 详情页改版
-        return true
-    }
-    userId, ok := getSession["userId"].(string)
-    if !ok || userId == "" {
-        R.ServeJson(w, req, &Result{Error_code_1004, Error_msg_1004, nil})
-        return false
-    }
-    return true
+	session := l.App.SessionManager.Session(req, w)
+	getSession := session.GetMultiple()
+	if getSession["userId"] != nil && getSession["mgoUserId"] == nil && util.Int64All(getSession["positionType"]) == 0 {
+		session.Set("mgoUserId", getSession["userId"])
+	}
+	if getSession["base_user_id"] != nil && getSession["positionId"] == nil {
+		identity.SwitchToBest(util.Int64All(getSession["base_user_id"]), session, Middleground, &Mgo, false)
+	}
+	if regOneClick.MatchString(req.URL.Path) {
+		return true
+	}
+	if regEntSearch.MatchString(req.URL.Path) || reg.MatchString(req.URL.Path) || reg.MatchString(req.URL.Path) || reg_share.MatchString(req.URL.Path) || reg_nps.MatchString(req.URL.Path) {
+		return true
+	}
+	if regWhiteList.MatchString(req.URL.Path) { // 判断用户是不是白名单接口不拦截
+		return true
+	}
+	if regOriginalText.MatchString(req.URL.Path) { // 查看原文不拦截  在接口里面判断登录
+		return true
+	}
+	if regActivityDayInfo.MatchString(req.URL.Path) { // p477 天天抢会员活动 活动信息未登录也可以访问
+		return true
+	}
+	if regDeatil.MatchString(req.URL.Path) { // p406 详情页改版
+		return true
+	}
+	if regMinDeatil.MatchString(req.URL.Path) {
+		return true
+	}
+	userId, ok := getSession["userId"].(string)
+	if !ok || userId == "" {
+		R.ServeJson(w, req, &Result{Error_code_1004, Error_msg_1004, nil})
+		return false
+	}
+	return true
 }

+ 9 - 0
src/jfw/modules/publicapply/src/test/detail_test.http

@@ -59,3 +59,12 @@ client.assert(response.body.error_code===0, "response.body.error_code!==0");
 });
 %}
 
+
+### p583未关注详情页接口信息
+
+POST {{addr}}/publicapply/detail/minBaseInfo
+Content-Type: application/json
+
+{
+  "id":"RQ=="
+}

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

@@ -78,6 +78,7 @@ func init() {
 	xweb.AddRouter("/subscribepay", &service.DataExportPack{})
 	//省份流量包
 	xweb.AddRouter("/jypay", &service.AreaPack{})
+	xweb.AddRouter("/jypay", &service.PdfExportPackService{})
 	//公共资源包
 	xweb.AddRouter("/jypay", &service.ResourcePack{})
 

+ 7 - 7
src/jfw/modules/subscribepay/src/baseApi.json

@@ -1,12 +1,12 @@
 {
   "appId": "10000",
   "apiList": {
-    "buyBalance": "http://127.0.0.1:8889/resources/purchaseUserBalance",
-    "useBalance": "http://127.0.0.1:8889/resources/useUserDetailed",
-    "findPreview": "http://127.0.0.1:8889/resources/findPreview",
-    "findBalance": "http://127.0.0.1:8889/resources/findBalance",
-    "findRecord": "http://127.0.0.1:8889/resources/findRecord",
-    "entdedupUrl": "http://127.0.0.1:8889/data/deduplication",
-    "updateVipTime":"http://127.0.0.1:8889/resources/updateVipTime"
+    "buyBalance": "http://192.168.3.128:8889/resources/purchaseUserBalance",
+    "useBalance": "http://192.168.3.128:8889/resources/useUserDetailed",
+    "findPreview": "http://192.168.3.128:8889/resources/findPreview",
+    "findBalance": "http://192.168.3.128:8889/resources/findBalance",
+    "findRecord": "http://192.168.3.128:8889/resources/findRecord",
+    "entdedupUrl": "http://192.168.3.128:8888/data/deduplication",
+    "updateVipTime":"http://192.168.3.128:8889/resources/updateVipTime"
   }
 }

+ 4 - 1
src/jfw/modules/subscribepay/src/config.json

@@ -133,7 +133,10 @@
     "采购单位画像包": true,
     "数据报告": true,
     "中标必听课": true,
-    "剑鱼文库会员":true
+    "剑鱼文库会员":true,
+    "市场分析定制报告下载包":true,
+    "业主采购分析报告下载包":true,
+    "企业中标分析报告下载包":true
   },
   "smsServiceRpc": "127.0.0.1:932",
   "nsq": "192.168.3.240:4260",

+ 26 - 0
src/jfw/modules/subscribepay/src/config.yaml

@@ -13,3 +13,29 @@ clickhouse:
   DbName: information
   MaxIdleConns: 5
   MaxOpenConns: 5
+
+pdfCreateServer:
+  addr: http://192.168.3.149:8079/api/to-pdf/%s?delay=15000&check=true&dir=%s&url=%s
+  pool: 5
+  pdfPageUrl:
+    winner: https://jybx2-webtest.jydev.jianyu360.com/page_big_pc/report/pdf/ent?pid=%s #企业画像报告
+    buyer: https://jybx2-webtest.jydev.jianyu360.com/page_big_pc/report/pdf/prop?pid=%s #采购单位报告
+    analysis: https://jybx2-webtest.jydev.jianyu360.com/page_big_pc/report/pdf/market?pid=%s #定制化分析报告
+pdfPackPrice:
+  企业中标分析报告下载包:
+    - num: 5
+      price: 44900
+    - num: 10
+      price: 79900
+    - num: 20
+      price: 138900
+  业主采购分析报告下载包:
+    - num: 5
+      price: 44900
+    - num: 10
+      price: 79900
+    - num: 20
+      price: 138900
+  市场分析定制报告下载包:
+    - num: 1
+      price: 199900

+ 2 - 2
src/jfw/modules/subscribepay/src/entity/basePack.go

@@ -262,7 +262,7 @@ func SupplyInfoFile(fileName, msgId string) (r map[string]interface{}) {
 
 // 兑换作废
 func JyexchangeCance(userId, product, platform, queryTime string, pageSize, pageNum int) (list []map[string]interface{}, total int, err error) {
-	RStruct := InitFindRecord(userId, product, queryTime, platform, pageSize, pageNum, 2)
+	RStruct := InitFindRecord(userId, userId, product, queryTime, platform, pageSize, pageNum, 2)
 	list, total = RStruct.DefaultData()
 	return list, total, nil
 }
@@ -285,7 +285,7 @@ func JyConsumePack(userId, product, platform string, remarks map[string]interfac
 
 // 流水
 func JyFindRecordPack(userId, productName, queryTime, platform string, pageSize, pageNum int) (list []map[string]interface{}, total int, err error) {
-	RStruct := InitFindRecord(userId, productName, queryTime, platform, pageSize, pageNum, 0)
+	RStruct := InitFindRecord(userId, userId, productName, queryTime, platform, pageSize, pageNum, 0)
 	switch productName {
 	case "附件下载包":
 		list, total = RStruct.FindJyConsumePackAllRecord()

+ 69 - 0
src/jfw/modules/subscribepay/src/entity/commodity.go

@@ -3,6 +3,7 @@ package entity
 import (
 	"encoding/json"
 	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/modules/subscribepay/src/config"
 	"jy/src/jfw/modules/subscribepay/src/util"
 	"log"
@@ -69,6 +70,8 @@ func (this *commodityStruct) Product(productId, orderType int64, userid string,
 		productInfoList, msg = dataReportProduct(productId, userid, productType, spec)
 	case DocMemberProductName:
 		productInfoList, msg = docMemberProduct(productId, orderType, userid, spec, productType, types, sess)
+	case PDFPACK_MARKET, PDFPACK_BUYER, PDFPACK_WINNER: //pdf下载包
+		productInfoList, msg = pdfExportPackProduct(productId, userid, productType)
 	default:
 		productInfoList, msg = nil, "产品类型有误"
 	}
@@ -233,6 +236,66 @@ func dataexportPackProduct(productId int64, userid string, title []string, produ
 	return
 }
 
+// pdf下载包
+func pdfExportPackProduct(productId int64, userid string, productType string) (productInfolist *[]ProductInfo, msg string) {
+	productInfolist = &[]ProductInfo{}
+
+	productInfo := &ProductInfo{}
+	productInfo.ProductTitle = productType
+	productInfo.ProductDesc = productType
+	proList := GetAllProduct(productId, 1, productType)
+	productInfo.ProductId = productId
+	sku := []*Sku{}
+	//子产品
+	allLottery := util.UserAllLottery(0, 1, 0, strconv.Itoa(int(productId)), userid, config.CouponConfig.AppId)
+	for _, v_ := range proList {
+		v := qu.Int64All(v_)
+		name, unit, num := GetProductNameById(v) //商品名称
+		desc := fmt.Sprintf("%v %s", num, unit)
+		choosed := false
+		productIdStr := strconv.Itoa(int(productId))
+		if isIn(v, config.CouponConfig.ChoosedProductId[productIdStr]) {
+			choosed = true
+		}
+		spec := &map[string]interface{}{}
+		// 计算所选择规格的价格
+		(*spec)["packId"] = v
+		(*spec)["productType"] = productType
+		(*spec)["num"] = num
+
+		detail, err := JyPdfExportPack.GetPdfPackDetail(gconv.String(v))
+		if err != nil {
+			log.Println(err.Error())
+		}
+		originalPrice := detail.Price // 获取原价
+
+		//获取用户下的奖券
+		//获取需要领取的优惠券
+		productCode := strconv.Itoa(int(v))
+		activityLotteryInfo := allLottery[productCode]
+		//计算优惠券
+		activityLotteryInfo, skuDiscountPrice, skuDiscountAmount, lotterId, activityId := activityHandle(activityLotteryInfo, int64(originalPrice), productType, nil, name, name)
+		//获取活动信息
+		productSku := &Sku{
+			ProductId:      v,
+			Info:           desc,
+			Name:           name,
+			Choosed:        choosed,
+			Activity:       activityLotteryInfo,
+			OriginalPrice:  int64(originalPrice),
+			DiscountPrice:  skuDiscountPrice,
+			DiscountAmount: skuDiscountAmount,
+			LotterId:       lotterId,
+			ActivityId:     activityId,
+		}
+		sku = append(sku, productSku)
+	}
+	productInfo.Sku = sku
+	productInfo.Extend = GetExtend(productId, PDFPACK_SOURCENAME, productType)
+	*productInfolist = append(*productInfolist, *productInfo)
+	return
+}
+
 // 历史数据导出
 func dataexportProduct(productId int64, userid string, productType string, spec *map[string]interface{}) (productInfolist *[]ProductInfo, msg string) {
 	productInfolist = &[]ProductInfo{}
@@ -870,6 +933,12 @@ func GetExtend(productCode int64, types string, id string) map[int64]map[string]
 				"specsUnit":     "条", //产品单位  天/条..,
 			},
 		}
+	case PDFPACK_SOURCENAME:
+		data = map[string]interface{}{
+			"validityYear": 3, //有效期限
+			//"priceUnit":    "元", //价格单位  元/分...
+			"specsUnit": "个", //产品单位  天/条..,
+		}
 	}
 	retData := map[int64]map[string]interface{}{}
 	if types != "" {

+ 5 - 5
src/jfw/modules/subscribepay/src/entity/commonApi.go

@@ -187,7 +187,7 @@ type FindRecordStruct struct {
 }
 
 // 定义结构体
-func InitFindRecord(userId, resourceType, queryTime, platform string, pageSize, pageNum, state int) *FindRecordStruct {
+func InitFindRecord(userId, accountId, resourceType, queryTime, platform string, pageSize, pageNum, state int) *FindRecordStruct {
 	if pageSize == 0 {
 		pageSize = 10
 	}
@@ -198,11 +198,11 @@ func InitFindRecord(userId, resourceType, queryTime, platform string, pageSize,
 		platform = "PC"
 	}
 	return &FindRecordStruct{
-		AccountId:    userId,
+		AccountId:    accountId,
 		UserId:       userId,
 		PageSize:     pageSize,
 		Page:         pageNum,
-		State:        state, //0 查消耗记录 1 查充值记录
+		State:        state, //-1全部记录 0 查消耗记录 1 查充值记录 2兑换作废
 		ResourceType: resourceType,
 		Name:         resourceType,
 		QueryTime:    queryTime,
@@ -215,11 +215,11 @@ func InitFindRecord(userId, resourceType, queryTime, platform string, pageSize,
 // @return list列表 , int数量 , error
 func (this *FindRecordStruct) FindRecord() ([]interface{}, int, error) {
 	resMap, err := middleGround.CommonPost(middleGround.JyApiConfig.ApiList.FindRecord, url.Values{
-		"accountId":    []string{this.UserId},                      //账户标识
+		"accountId":    []string{this.AccountId},                   //账户标识
 		"userId":       []string{this.UserId},                      //用户标识
 		"pageSize":     []string{fmt.Sprintf("%d", this.PageSize)}, //每页多少条
 		"page":         []string{fmt.Sprintf("%d", this.Page)},     //当前页
-		"state":        []string{fmt.Sprintf("%d", this.State)},    // 0 查消耗记录 1 查充值记录
+		"state":        []string{fmt.Sprintf("%d", this.State)},    //-1全部记录 0 查消耗记录 1 查充值记录 2兑换作废
 		"resourceType": []string{this.ResourceType},
 		"queryTime":    []string{this.QueryTime}, //格式 2022-01
 	})

+ 1 - 1
src/jfw/modules/subscribepay/src/entity/equityCode.go

@@ -436,7 +436,7 @@ func (e *EquityCode) UseEquityCodeAndAuthority() (m string, flag bool) {
 				positionType := qu.Int64All(sessVal["positionType"])
 				entId := qu.Int64All(sessVal["entId"])
 				entUserId := qu.Int64All(sessVal["entUserId"])
-				normal_member(level, endDate, e.UserId, positionType, entId, entUserId)
+				normal_member(level, endDate, e.UserId, positionType, entId, entUserId, cycle)
 			}
 			//取消其他订单
 			go PayCancel(e.UserId, "大会员", "")

+ 73 - 44
src/jfw/modules/subscribepay/src/entity/member.go

@@ -5,11 +5,11 @@ import (
 	"database/sql"
 	"encoding/json"
 	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/modules/subscribepay/src/config"
 	"jy/src/jfw/modules/subscribepay/src/util"
 	"log"
 	"strconv"
-	"strings"
 	"time"
 
 	"bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
@@ -66,13 +66,18 @@ func (m *memberStruct) PayCallBack(param *CallBackParam) bool {
 			orderCode := qutil.InterfaceToStr((*orderdata)["order_code"])
 			cycle := qutil.IntAll(filter["cycle"])
 			level := qutil.IntAll(filter["level"])
-			var enddate = time.Now()
+			var (
+				enddate = time.Now()
+				yearNum int
+			)
+
 			if level == 4 { //试用用户 试用七天
 				enddate = time.Date(now.Year(), now.Month(), now.Day()+cycle, 23, 59, 59, 0, time.Local)
 			} else {
+				yearNum = cycle
 				enddate = time.Date(now.Year()+cycle, now.Month(), now.Day(), 23, 59, 59, 0, time.Local)
 			}
-			normal_member(level, enddate, userId, 0, 0, 0)
+			normal_member(level, enddate, userId, 0, 0, 0, yearNum)
 			update := util.Mysql.Update("dataexport_order", map[string]interface{}{
 				"id": (*orderdata)["id"],
 			}, map[string]interface{}{
@@ -112,7 +117,7 @@ func (m *memberStruct) PayCallBack(param *CallBackParam) bool {
 	return true
 }
 
-func normal_member(level int, enddate time.Time, userId string, positionType, entId, entUserId int64) {
+func normal_member(level int, enddate time.Time, userId string, positionType, entId, entUserId int64, yearNum int) {
 	//修改用户表权限
 	set := map[string]interface{}{}
 	set = map[string]interface{}{
@@ -145,46 +150,70 @@ func normal_member(level int, enddate time.Time, userId string, positionType, en
 		serviceCode = list["s_servers"].(string)
 	}
 	if serviceCode != "" {
-		for _, v := range strings.Split(serviceCode, ",") {
-			var s_serviceid = v
-			var frequency = 0
-			sid, _ := strconv.Atoi(v)
-			if Bigmember_serice[sid] != nil {
-				for k, v := range Bigmember_serice[sid] {
-					s_serviceid = strconv.Itoa(k)
-					frequency = v
-				}
-			}
-			if util.Mysql.CountBySql(`select count(*) from `+jy.BigmemberUserPowerTable+` where s_userid=? and s_serviceid=?`, userId, v) == 0 {
-				insert := map[string]interface{}{
-					"s_userid":     userId,
-					"s_serviceid":  s_serviceid,
-					"i_frequency":  frequency,
-					"l_starttime":  NowFormat(Date_Full_Layout),
-					"l_endtime":    FormatDate(&enddate, Date_Full_Layout),
-					"i_status":     0,
-					"l_createtime": NowFormat(Date_Full_Layout),
-					"l_updatetime": NowFormat(Date_Full_Layout),
-					"s_smainid":    v,
-				}
-				order_id := util.Mysql.Insert(jy.BigmemberUserPowerTable, insert)
-				if order_id == 0 {
-					log.Println("保存出错:", userId, "---", v)
-				}
-			} else {
-				query := map[string]interface{}{
-					"s_userid":    userId,
-					"s_serviceid": s_serviceid,
-				}
-				update := map[string]interface{}{
-					"i_status":     0,
-					"i_frequency":  frequency,
-					"l_updatetime": NowFormat(Date_Full_Layout),
-					"l_endtime":    FormatDate(&enddate, Date_Full_Layout),
-					"s_smainid":    v,
-				}
-				if !util.Mysql.Update(jy.BigmemberUserPowerTable, query, update) {
-					log.Println("更新大会员用户服务表出错:", userId, v)
+		res := util.Mysql.SelectBySql(fmt.Sprintf("SELECT * FROM bigmember_service where id in (%s) ", serviceCode))
+		if res != nil && len(*res) > 0 {
+			for _, m := range *res {
+				serverName := qutil.ObjToString(m["s_new_name"])
+				//pdf下载包服务
+				if productCode, ok := bigMemberNameCodeMapping[serverName]; ok && productCode != 0 {
+					var num int = yearNum * qutil.IntAll(m["s_count_year"])
+					_, err := JyPdfExportPack.RechargePack(userId, &PdfPackDetail{
+						EndTime:  FormatDate(&enddate, Date_Short_Layout),
+						PackNum:  num,
+						PackType: productCode,
+						Source:   fmt.Sprintf("大会员产品套餐有%d份“%s”权益", num, serverName),
+					})
+					if err != nil {
+						log.Printf("%s 大会员开通pdf下载包服务异常 %v \n", userId, err)
+					}
+				} else {
+					var (
+						v           = gconv.String(m["id"])
+						sid         = gconv.Int(m["id"])
+						s_serviceid = v
+						frequency   = 0
+					)
+					if v == "" {
+						continue
+					}
+					if Bigmember_serice[sid] != nil {
+						for k, v := range Bigmember_serice[sid] {
+							s_serviceid = strconv.Itoa(k)
+							frequency = v
+						}
+					}
+					if util.Mysql.CountBySql(`select count(*) from `+jy.BigmemberUserPowerTable+` where s_userid=? and s_serviceid=?`, userId, v) == 0 {
+						insert := map[string]interface{}{
+							"s_userid":     userId,
+							"s_serviceid":  s_serviceid,
+							"i_frequency":  frequency,
+							"l_starttime":  NowFormat(Date_Full_Layout),
+							"l_endtime":    FormatDate(&enddate, Date_Full_Layout),
+							"i_status":     0,
+							"l_createtime": NowFormat(Date_Full_Layout),
+							"l_updatetime": NowFormat(Date_Full_Layout),
+							"s_smainid":    v,
+						}
+						order_id := util.Mysql.Insert(jy.BigmemberUserPowerTable, insert)
+						if order_id == 0 {
+							log.Println("保存出错:", userId, "---", v)
+						}
+					} else {
+						query := map[string]interface{}{
+							"s_userid":    userId,
+							"s_serviceid": s_serviceid,
+						}
+						update := map[string]interface{}{
+							"i_status":     0,
+							"i_frequency":  frequency,
+							"l_updatetime": NowFormat(Date_Full_Layout),
+							"l_endtime":    FormatDate(&enddate, Date_Full_Layout),
+							"s_smainid":    v,
+						}
+						if !util.Mysql.Update(jy.BigmemberUserPowerTable, query, update) {
+							log.Println("更新大会员用户服务表出错:", userId, v)
+						}
+					}
 				}
 			}
 		}

+ 55 - 0
src/jfw/modules/subscribepay/src/entity/order.go

@@ -127,6 +127,8 @@ func (this *commonOrderStruct) InserMap(product, productId, userid, lotteryId, d
 		orderinfo, msg = courseOnlineOrder(m, userid)
 	case DocMemberProductName:
 		orderinfo, msg = docMemberOrder(m, userid, session)
+	case PDFPACK_MARKET, PDFPACK_BUYER, PDFPACK_WINNER: //pdf下载包
+		orderinfo, msg = pdfExportPackOrder(m, userid, product, productId)
 	default:
 		orderinfo, msg = nil, "产品类型有误"
 	}
@@ -1020,6 +1022,59 @@ func dataexportPackOrder(m map[string]interface{}, userId string) (*OrderInfo, s
 	}, ""
 }
 
+// pdf下载包
+func pdfExportPackOrder(m map[string]interface{}, userId, product, productId string) (*OrderInfo, string) {
+	// 获取用户分销口令
+	disWordStr := ""
+	// 查询用户携带的分销口令
+	userfilter, ok := util.MQFW.FindById("user", userId, "")
+	if ok && userfilter != nil {
+		startTime := qu.Int64All((*userfilter)["startTime"])
+		endTime := qu.Int64All((*userfilter)["endTime"])
+		if startTime != 0 {
+			if startTime <= time.Now().Unix() && endTime >= time.Now().Unix() {
+				disWordStr = qu.ObjToString((*userfilter)["disWords"])
+			}
+		}
+	}
+	//根据id查询流量包价格
+	packDetail, err := JyPdfExportPack.GetPdfPackDetail(productId)
+	if err != nil {
+		return nil, err.Error()
+	}
+	productName, err := JyPdfExportPack.GetNameByCode(packDetail.PackType)
+	if err != nil {
+		return nil, err.Error()
+	}
+	if productName != product {
+		return nil, "参数异常"
+	}
+	packDetail.GiveCycle = 0
+	packDetail.DisCountId = 0
+
+	packDetail.Source = qu.ObjToString(m["source"]) //来源(活动)
+	//卡券折扣
+
+	orderCode := pay.GetOrderCode()
+	filter, err := json.Marshal(packDetail)
+	if err != nil {
+		return nil, "数据异常"
+	}
+	return &OrderInfo{
+		OrderMoney:    packDetail.Price, //订单金额
+		OrderStatus:   0,
+		ServiceStatus: 0,
+		UserPhone:     qu.ObjToString(m["order_phone"]),
+		OrderCode:     orderCode,
+		ProductType:   product,
+		CreateTime:    NowFormat(Date_Full_Layout),
+		OriginalPrice: packDetail.Price,
+		Filter:        string(filter),
+		UserId:        userId,
+		DisWord:       disWordStr,
+	}, ""
+}
+
 // 省份订阅包
 func areaPackOrder(m map[string]interface{}, userId string, session *httpsession.Session) (*OrderInfo, string) {
 	orderType := qu.IntAll(m["orderType"])

+ 510 - 0
src/jfw/modules/subscribepay/src/entity/pdfExportPack.go

@@ -0,0 +1,510 @@
+package entity
+
+import (
+	qutil "app.yhyue.com/moapp/jybase/common"
+	. "app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/middleGround"
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/util/gconv"
+	"github.com/google/uuid"
+	"io"
+	"jy/src/jfw/modules/subscribepay/src/util"
+	"log"
+	"net"
+	"net/http"
+	"net/url"
+	"strings"
+	"time"
+)
+
+const (
+	PDFPACK_WINNER_CODE = iota + 1
+	PDFPACK_BUYER_CODE
+	PDFPACK_MARKET_CODE
+
+	PDFPACK_SOURCENAME = "pdf下载包"
+	PDFPACK_WINNER     = "企业中标分析报告下载包"
+	PDFPACK_BUYER      = "业主采购分析报告下载包"
+	PDFPACK_MARKET     = "市场分析定制报告下载包"
+
+	ParentResourceIdPrefix = "p_share_"
+)
+
+var (
+	pdfPackPriceMap = map[string]map[int]int{}
+	JyPdfExportPack pdfExportPackStruct
+	ClientPool      chan *http.Client
+
+	bigMemberNameCodeMapping = map[string]int{
+		"企业中标分析报告下载":  PDFPACK_WINNER_CODE,
+		"业主采购分析报告下载":  PDFPACK_BUYER_CODE,
+		"市场分析定制报告下载":  PDFPACK_MARKET_CODE,
+		"企业中标分析报告下载包": PDFPACK_WINNER_CODE,
+		"业主采购分析报告下载包": PDFPACK_BUYER_CODE,
+		"市场分析定制报告下载包": PDFPACK_MARKET_CODE,
+	}
+)
+
+func init() {
+	var (
+		PoolLimit = g.Cfg().MustGet(context.TODO(), "pdfCreateServer.pool", 5).Int() //默认5个
+		NewClient = func() *http.Client {
+			//不保持连接
+			transport := &http.Transport{
+				Dial: func(netw, addr string) (net.Conn, error) {
+					deadline := time.Now().Add(25 * time.Second)
+					c, err := net.DialTimeout(netw, addr, 5*time.Second)
+					if err != nil {
+						return nil, err
+					}
+					tcp_conn := c.(*net.TCPConn)
+					tcp_conn.SetKeepAlive(false)
+					tcp_conn.SetDeadline(deadline)
+					return tcp_conn, nil
+				},
+				DisableKeepAlives: true,
+			}
+			return &http.Client{Transport: transport}
+		}
+	)
+	ClientPool = make(chan *http.Client, PoolLimit)
+	for i := 0; i < PoolLimit; i++ {
+		ClientPool <- NewClient()
+	}
+}
+
+type (
+	//PdfPackDetail *列表展示使用
+	PdfPackDetail struct {
+		Source    string `json:"source"`              //*来源
+		EndTime   string `json:"endTime"`             //*有效期 「账户合并过来的资源为-1」
+		PackType  int    `json:"pType,omitempty"`     //数据包类型 1,企业中标分析报告下载包、2业主采购分析报告下载包、3市场分析定制报告下载包
+		PackNum   int    `json:"pNum,omitempty"`      //数据包数量
+		ValidYear int    `json:"validYear,omitempty"` //有效年份 「账户合并过来的资源为-1」
+		Price     int    `json:"price,omitempty"`     //数据包价格 「账户合并过来的资源为-1」
+		//活动参数
+		GiveCycle     int    `json:"give_cycle,omitempty"`     //赠送条数
+		OriginalPrice int    `json:"original_price,omitempty"` //双十一活动原价价格
+		DisCountId    int    `json:"discountId,omitempty"`     //赠送的id
+		Badge         string `json:"badge,omitempty"`          //活动标识
+	}
+	pdfExportPackStruct struct{}
+
+	AccountPdfPackItem struct {
+		WINNER AccountPdfPack `json:"winner"` //企业中标分析报告下载包
+		BUYER  AccountPdfPack `json:"buyer"`  //业主采购分析报告下载包
+		MARKET AccountPdfPack `json:"market"` //市场分析定制报告下载包
+	}
+	AccountPdfPack struct {
+		Total      int    `json:"total"`
+		MinEndTime string `json:"minEndTime"`
+		FirstUse   string `json:"-"` //优先使用账号
+	}
+
+	PdfPackUseRemark struct {
+		QueryId         string `json:"queryId"`         //查询条件
+		PdfUrl          string `json:"pdfUrl"`          //下载地址
+		ExportTimeStamp int64  `json:"exportTimeStamp"` //导出时间
+	}
+)
+
+func init() {
+	type priceSpe struct {
+		Num   int `json:"num"`
+		Price int `json:"price"`
+	}
+	for productName, detail := range g.Cfg().MustGet(context.TODO(), "pdfPackPrice").Map() {
+		var (
+			arr     []priceSpe
+			mapping = map[int]int{}
+		)
+		if gconv.Struct(detail, &arr) == nil {
+			for _, spe := range arr {
+				mapping[spe.Num] = spe.Price
+			}
+		}
+		pdfPackPriceMap[productName] = mapping
+	}
+	g.Dump(pdfPackPriceMap)
+}
+
+// PayCallBack 支付完成回调
+func (this *pdfExportPackStruct) PayCallBack(param *CallBackParam) bool {
+	orderData := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,order_code,order_status,user_id,product_type,order_money,d_relation_id", "")
+	if orderData == nil || len(*orderData) == 0 {
+		return false
+	}
+	if order_status := qutil.IntAll((*orderData)["order_status"]); order_status == 0 {
+		var (
+			now         = time.Now()
+			payTime     = FormatDate(&now, Date_Full_Layout)
+			productType = qutil.ObjToString((*orderData)["product_type"])
+			filter      = qutil.ObjToString((*orderData)["filter"])
+			orderCode   = qutil.ObjToString((*orderData)["order_code"])
+			userId      = qutil.ObjToString((*orderData)["user_id"])
+		)
+		packDetail := new(PdfPackDetail)
+		if err := json.Unmarshal([]byte(filter), &packDetail); err != nil {
+			log.Printf("获取用户%s已购买pdf数据包内容异常:%v", userId, err)
+			return false
+		}
+		if packDetail.GiveCycle > 0 { //赠品
+			packDetail.PackNum += packDetail.GiveCycle
+		}
+		packDetail.EndTime = time.Now().AddDate(packDetail.ValidYear, 0, 0).Format(Date_Short_Layout)
+		packDetail.Source = fmt.Sprintf("购买“%s”", productType)
+		update := util.Mysql.Update("dataexport_order", map[string]interface{}{
+			"id": (*orderData)["id"],
+		}, map[string]interface{}{
+			"pay_money":    param.CashFee,
+			"pay_time":     payTime,
+			"order_status": 1,
+			"out_trade_no": param.OutTradeno,
+			"filter":       gconv.String(packDetail),
+		})
+		if update {
+			//卡卷使用
+			userLotteryId := qutil.ObjToString((*orderData)["d_relation_id"])
+			if userLotteryId != "" {
+				go func(userId, userLotteryId, order_code string) {
+					phone, name := util.GetMyPhoneAndName(userId)
+					if !util.UpdateCouponState(userId, userLotteryId, name, phone, order_code, "数据流量包", "", 1, 0) {
+						log.Println(fmt.Sprintf("单号 %s-消费失败-卡卷%s", order_code, userLotteryId))
+					}
+				}(userId, userLotteryId, orderCode)
+			}
+			//调用中台 增加数据包
+			if _, err := this.RechargePack(userId, packDetail); err != nil {
+				log.Println(fmt.Sprintf("%s 资源账户更改异常 %v", userId, err))
+				return false
+			}
+			if dis_word := qutil.ObjToString((*orderData)["dis_word"]); dis_word != "" && len(dis_word) > 3 {
+				//分销系统 分销记录
+				suffix := dis_word[len(dis_word)-3:]
+				if suffix == "_GX" {
+					go DisWordRecode(qutil.IntAll((*orderData)["id"]), qutil.IntAll((*orderData)["order_money"]), qutil.ObjToString((*orderData)["product_type"]), dis_word, userId)
+				}
+			}
+			return true
+		}
+	}
+	return false
+}
+
+// GetPdfPackDetail 中台交互-获取单个数据流量包价格
+func (this *pdfExportPackStruct) GetPdfPackDetail(packId string) (PdfPackDetail, error) {
+	productType, _, num := GetProductNameById(packId)
+	packType, err := this.GetCodeByName(productType)
+	if err != nil {
+		return PdfPackDetail{}, err
+	}
+	productPricesMap, ok := pdfPackPriceMap[productType]
+	if !ok || productPricesMap == nil || len(productPricesMap) == 0 {
+		return PdfPackDetail{}, fmt.Errorf("未知产品类型")
+	}
+	price, ok := productPricesMap[num]
+	if !ok || price == 0 {
+		return PdfPackDetail{}, fmt.Errorf("未知规格")
+	}
+
+	//TODO:获取计价
+	return PdfPackDetail{
+		PackType:      packType,
+		PackNum:       num,
+		ValidYear:     3,
+		Price:         price,
+		OriginalPrice: price,
+	}, nil
+}
+
+// RechargePack 流量包充值
+func (this *pdfExportPackStruct) RechargePack(userId string, detail *PdfPackDetail) (bool, error) {
+	if detail.EndTime == "" || userId == "" || detail.PackNum == 0 || detail.PackType == 0 {
+		return false, fmt.Errorf("参数异常")
+	}
+	remarkBytes, err := json.Marshal(detail)
+	if err != nil {
+		return false, fmt.Errorf("remark pase error")
+	}
+	packName, err := this.GetNameByCode(detail.PackType)
+	if err != nil {
+		return false, err
+	}
+	_, err = middleGround.CommonPost(middleGround.JyApiConfig.ApiList.BuyBalance, url.Values{
+		"accountId":    []string{userId},                            //账户标识*
+		"name":         []string{PDFPACK_SOURCENAME},                //资源名称*
+		"resourceType": []string{packName},                          //资源类型*
+		"number":       []string{fmt.Sprintf("%d", detail.PackNum)}, //数量*
+		"spec":         []string{"个"},                               //规格*
+		"endTime":      []string{detail.EndTime},                    //截止时间
+		"remarks":      []string{string(remarkBytes)},               //备注
+	})
+	if err != nil {
+		return false, err
+	}
+	return true, nil
+}
+
+// UsePack 流量包使用
+func (this *pdfExportPackStruct) UsePack(userId, accountId string, deduct, resourceType int, remark *PdfPackUseRemark) (int, error) {
+	remarkBytes, err := json.Marshal(remark)
+	if err != nil {
+		return -1, fmt.Errorf("remark pase error")
+	}
+	resourceName, err := this.GetNameByCode(resourceType)
+	if err != nil {
+		return -1, err
+	}
+	resMap, err := middleGround.CommonPost(middleGround.JyApiConfig.ApiList.UseBalance, url.Values{
+		"accountId":        []string{accountId},                 //账户标识
+		"name":             []string{PDFPACK_SOURCENAME},        //资源名称
+		"resourceType":     []string{resourceName},              //资源类型
+		"number":           []string{fmt.Sprintf("%d", deduct)}, //扣除数量
+		"ruleId":           []string{""},                        //规则标识
+		"userId":           []string{userId},                    //用户标识
+		"remarks":          []string{string(remarkBytes)},       //备注 查询条件、下载地址、导出时间、导出条数
+		"infoId":           []string{},                          //数据Id,多个以逗号隔开
+		"duplicateRemoval": []string{fmt.Sprintf("%d", 0)},      //是否去重0不去1去重
+	})
+	if err != nil {
+		return -1, err
+	}
+	return qutil.IntAll(resMap["deductionNumb"]), nil
+}
+
+// PackQuery 查询账户和主账号数据流量包余额
+func (this *pdfExportPackStruct) PackQuery(accountId string, vip *jy.BigVipBaseMsg) (*AccountPdfPackItem, error) {
+	account, err := JyPdfExportPack.accountQuery(accountId)
+	if err != nil {
+		return nil, err
+	}
+	//查询个人版本共享账户
+	shareAccount := fmt.Sprintf("%s%s", ParentResourceIdPrefix, accountId)
+	if vip != nil && vip.Pid != "" {
+		shareAccount = fmt.Sprintf("%s%s", ParentResourceIdPrefix, vip.Pid)
+	}
+	shareAccountRes, err := JyPdfExportPack.accountQuery(shareAccount)
+	if err != nil {
+		return nil, err
+	}
+	//合并自账号和祝账号
+	account = account.merge(shareAccountRes)
+	return account, nil
+}
+
+// accountQuery 查询账户数据流量包余额
+func (this *pdfExportPackStruct) accountQuery(accountId string) (*AccountPdfPackItem, error) {
+	resMap, err := middleGround.CommonPost(middleGround.JyApiConfig.ApiList.FindBalance, url.Values{
+		"accountId":      []string{accountId}, //账户标识*
+		"resourceName":   []string{"pdf下载包"},
+		"showMinEndTime": []string{"1"},
+	})
+
+	if err != nil {
+		log.Println(err)
+		return nil, fmt.Errorf("账户查询异常")
+	}
+	listObj, ok := resMap["data"].([]interface{})
+	if !ok {
+		return nil, fmt.Errorf("参数异常")
+	}
+	account := new(AccountPdfPackItem)
+	for _, obj := range listObj {
+		packMap := qutil.ObjToMap(obj)
+		if packMap == nil || len(*packMap) == 0 {
+			continue
+		}
+		if packType := qutil.ObjToString((*packMap)["name"]); packType != PDFPACK_SOURCENAME {
+			continue
+		}
+
+		packDetail := AccountPdfPack{
+			Total:      qutil.IntAll((*packMap)["number"]),
+			MinEndTime: qutil.ObjToString((*packMap)["minEndTime"]),
+			FirstUse:   accountId,
+		}
+
+		switch qutil.ObjToString((*packMap)["resourceType"]) {
+		case PDFPACK_WINNER:
+			account.WINNER = packDetail
+		case PDFPACK_BUYER:
+			account.BUYER = packDetail
+		case PDFPACK_MARKET:
+			account.MARKET = packDetail
+		}
+	}
+	return account, nil
+}
+
+// Merge 合并主账号资源
+func (appi *AccountPdfPackItem) merge(pAccount *AccountPdfPackItem) *AccountPdfPackItem {
+	var (
+		winnerMinEndTime = qutil.If(pAccount.WINNER.MinEndTime == "" || (appi.WINNER.MinEndTime != "" && appi.WINNER.MinEndTime < pAccount.WINNER.MinEndTime), appi.WINNER.MinEndTime, pAccount.WINNER.MinEndTime).(string)
+		buyerMinEndTime  = qutil.If(pAccount.BUYER.MinEndTime == "" || (appi.BUYER.MinEndTime != "" && appi.BUYER.MinEndTime < pAccount.BUYER.MinEndTime), appi.BUYER.MinEndTime, pAccount.BUYER.MinEndTime).(string)
+		marketMinEndTime = qutil.If(pAccount.MARKET.MinEndTime == "" || (appi.MARKET.MinEndTime != "" && appi.MARKET.MinEndTime < pAccount.MARKET.MinEndTime), appi.MARKET.MinEndTime, pAccount.MARKET.MinEndTime).(string)
+	)
+	return &AccountPdfPackItem{
+		WINNER: AccountPdfPack{
+			Total:      appi.WINNER.Total + pAccount.WINNER.Total,
+			MinEndTime: winnerMinEndTime,
+			FirstUse:   qutil.If(winnerMinEndTime == appi.WINNER.MinEndTime, appi.WINNER.FirstUse, pAccount.WINNER.FirstUse).(string),
+		},
+		BUYER: AccountPdfPack{
+			Total:      appi.BUYER.Total + pAccount.BUYER.Total,
+			MinEndTime: buyerMinEndTime,
+			FirstUse:   qutil.If(buyerMinEndTime == appi.BUYER.MinEndTime, appi.BUYER.FirstUse, pAccount.BUYER.FirstUse).(string),
+		},
+		MARKET: AccountPdfPack{
+			Total:      appi.MARKET.Total + pAccount.MARKET.Total,
+			MinEndTime: marketMinEndTime,
+			FirstUse:   qutil.If(marketMinEndTime == appi.MARKET.MinEndTime, appi.MARKET.FirstUse, pAccount.MARKET.FirstUse).(string),
+		},
+	}
+}
+
+// GetNameByCode  1,企业中标分析报告下载包、2业主采购分析报告下载包、3市场分析定制报告下载包
+func (this *pdfExportPackStruct) GetNameByCode(resourceType int) (string, error) {
+	var resourceName string
+	switch resourceType {
+	case PDFPACK_WINNER_CODE:
+		resourceName = PDFPACK_WINNER
+	case PDFPACK_BUYER_CODE:
+		resourceName = PDFPACK_BUYER
+	case PDFPACK_MARKET_CODE:
+		resourceName = PDFPACK_MARKET
+	default:
+		return "", fmt.Errorf("未知pdf下载包类型")
+	}
+	return resourceName, nil
+}
+
+func (this *pdfExportPackStruct) GetCodeByName(resourceName string) (int, error) {
+	var resourceType int
+	switch resourceName {
+	case PDFPACK_WINNER:
+		resourceType = PDFPACK_WINNER_CODE
+	case PDFPACK_BUYER:
+		resourceType = PDFPACK_BUYER_CODE
+	case PDFPACK_MARKET:
+		resourceType = PDFPACK_MARKET_CODE
+	default:
+		return -1, fmt.Errorf("未知pdf下载包类型")
+	}
+	return resourceType, nil
+}
+
+func (this *pdfExportPackStruct) GetDownLoadPdf(userId string, vip *jy.BigVipBaseMsg, filterId string) (string, error) {
+	filterMap, _ := util.MQFW.FindOne("analysis_report_screen", map[string]interface{}{
+		"user_id": userId,
+		"_id":     mongodb.StringTOBsonId(filterId),
+	})
+	if filterMap == nil || len(*filterMap) == 0 {
+		return "", fmt.Errorf("未知报告")
+	}
+
+	var (
+		usage       int //流量包余额
+		pdfPageUrl  string
+		fileDir     string
+		pdfUrl      string
+		productCode = qutil.IntAll((*filterMap)["type"])
+		accountId   string
+		entName     string
+	)
+	account, err := this.PackQuery(userId, vip)
+	if err != nil {
+		return "", err
+	}
+
+	switch productCode {
+	case 1:
+		usage = account.WINNER.Total
+		accountId = account.WINNER.FirstUse
+		entName = gconv.String((*filterMap)["entName"])
+		fileDir = url.QueryEscape(time.Now().Format(fmt.Sprintf("winnerPdf/%s", "20060102")))
+		pdfPageUrl = g.Cfg().MustGet(context.TODO(), "pdfCreateServer.pdfPageUrl.winner").String()
+	case 2:
+		usage = account.BUYER.Total
+		accountId = account.BUYER.FirstUse
+		entName = gconv.String((*filterMap)["entName"])
+		fileDir = url.QueryEscape(time.Now().Format(fmt.Sprintf("buyerPdf/%s", "20060102")))
+		pdfPageUrl = g.Cfg().MustGet(context.TODO(), "pdfCreateServer.pdfPageUrl.buyer").String()
+	case 3:
+		usage = account.MARKET.Total
+		accountId = account.MARKET.FirstUse
+		fileDir = url.QueryEscape(time.Now().Format(fmt.Sprintf("markerPdf/%s", "20060102")))
+		pdfPageUrl = g.Cfg().MustGet(context.TODO(), "pdfCreateServer.pdfPageUrl.analysis").String()
+	}
+	if usage < 1 {
+		return "", fmt.Errorf("流量包余额不足")
+	}
+	//生成pdf
+	pfdData, err := func() (map[string]interface{}, error) {
+		c := <-ClientPool
+		defer func() {
+			ClientPool <- c
+		}()
+		var (
+			fileName = fmt.Sprintf("%s_%s", entName, uuid.New().String())
+			reqUrl   = fmt.Sprintf(pdfPageUrl, filterId)
+		)
+		res, reqErr := g.Client().Timeout(time.Minute).Get(context.TODO(), fmt.Sprintf(g.Cfg().MustGet(context.TODO(), "pdfCreateServer.addr").String(), fileName, fileDir, reqUrl))
+		if reqErr != nil {
+			log.Printf("%s 调用生成pdf服务异常 %v\n", filterId, reqErr)
+			return nil, fmt.Errorf("pdf服务异常")
+		}
+		defer res.Close()
+		b, redErr := io.ReadAll(res.Body)
+		if redErr != nil {
+			log.Printf("%s 生成pdf服务返回异常 %v\n", filterId, redErr)
+			return nil, fmt.Errorf("pdf服务异常")
+		}
+		rMap := map[string]interface{}{}
+		if jsonErr := json.Unmarshal(b, &rMap); jsonErr != nil {
+			log.Printf("%s 生成pdf服务返回异常 %v\n", filterId, jsonErr)
+			return nil, fmt.Errorf("返回异常")
+		}
+		return rMap, nil
+	}()
+	if ok, _ := pfdData["status"].(bool); ok {
+		if dataMap := gconv.Map(pfdData["data"]); len(dataMap) > 0 {
+			pdfUrl = qutil.ObjToString(dataMap["path"])
+		}
+	}
+	if pdfUrl == "" {
+		return "", fmt.Errorf("生成文件异常")
+	}
+	//扣减
+	if _, err := this.UsePack(userId, accountId, 1, productCode, &PdfPackUseRemark{
+		QueryId:         filterId,
+		PdfUrl:          pdfUrl,
+		ExportTimeStamp: time.Now().Unix(),
+	}); err != nil {
+		log.Printf("%s pdfExportPackStruct GetDownLoadPdf err:%v\n", userId, err)
+		return "", err
+	}
+	//更新导出记录pdf地址
+	go func() {
+		//更新下载地址
+		upMap := map[string]interface{}{
+			"s_pdfUrl": pdfUrl,
+		}
+		if strings.HasPrefix(accountId, ParentResourceIdPrefix) {
+			upMap["s_pid"] = strings.ReplaceAll(accountId, ParentResourceIdPrefix, "")
+		}
+		util.MQFW.UpdateById("analysis_report_screen", filterId, map[string]interface{}{
+			"$set": upMap,
+		})
+		//发送邮件
+		(*filterMap)["s_pdfUrl"] = pdfUrl
+		if sendMailErr := util.PdfSendEmail(*filterMap); sendMailErr != nil {
+			log.Printf("发送邮件异常 %v\n", sendMailErr)
+		}
+	}()
+	return pdfUrl, nil
+}

+ 3 - 15
src/jfw/modules/subscribepay/src/go.mod

@@ -4,11 +4,10 @@ go 1.20
 
 require (
 	app.yhyue.com/moapp/jybase v0.0.0-20240626030750-115a3c0929fb
-	app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545
-	app.yhyue.com/moapp/jypkg v1.21.10
+	app.yhyue.com/moapp/jypkg v1.21.11
 	bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2
 	bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20230911091604-2faa31032743
-	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.16
+	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.18
 	github.com/ClickHouse/clickhouse-go/v2 v2.2.0
 	github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67
 	github.com/gogf/gf/v2 v2.7.0
@@ -26,7 +25,7 @@ require (
 	app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736 // indirect
 	app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 // indirect
 	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20231226074509-942d80dc34eb // indirect
-	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240603091545-83ceaad11e6b // indirect
+	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843 // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 // indirect
 	filippo.io/edwards25519 v1.1.0 // indirect
 	github.com/BurntSushi/toml v1.2.0 // indirect
@@ -60,7 +59,6 @@ require (
 	github.com/gorilla/websocket v1.5.0 // indirect
 	github.com/grokify/html-strip-tags-go v0.0.1 // indirect
 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/howeyc/fsnotify v0.9.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.1 // indirect
@@ -73,7 +71,6 @@ require (
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.15 // indirect
 	github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
-	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
@@ -93,14 +90,7 @@ require (
 	github.com/prometheus/procfs v0.12.0 // indirect
 	github.com/redis/go-redis/v9 v9.4.0 // indirect
 	github.com/rivo/uniseg v0.2.0 // indirect
-	github.com/sirupsen/logrus v1.8.3 // indirect
 	github.com/spaolacci/murmur3 v1.1.0 // indirect
-	github.com/spf13/afero v1.9.3 // indirect
-	github.com/spf13/cast v1.5.0 // indirect
-	github.com/spf13/jwalterweatherman v1.1.0 // indirect
-	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/spf13/viper v1.15.0 // indirect
-	github.com/subosito/gotenv v1.4.2 // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/scram v1.1.2 // indirect
 	github.com/xdg-go/stringprep v1.0.4 // indirect
@@ -140,8 +130,6 @@ require (
 	google.golang.org/protobuf v1.33.0 // indirect
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
-	gopkg.in/ini.v1 v1.67.0 // indirect
-	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gorm.io/driver/mysql v1.0.5 // indirect

+ 6 - 29
src/jfw/modules/subscribepay/src/go.sum

@@ -18,10 +18,8 @@ app.yhyue.com/moapp/jybase v0.0.0-20231025021840-2f91c944ecdd/go.mod h1:Hv9U/7oH
 app.yhyue.com/moapp/jybase v0.0.0-20240626030750-115a3c0929fb h1:LstR4tQbICqo2MO0A6za4rci4Y/lw+Nf898GlImARZM=
 app.yhyue.com/moapp/jybase v0.0.0-20240626030750-115a3c0929fb/go.mod h1:XHNATN6tsJKHdCB0DbUtFdPPHXexTUFyB3RlO+lUUoM=
 app.yhyue.com/moapp/jyfs v0.0.0-20231024061508-480c270480d4/go.mod h1:61hzZ3dZHXL28BNl8BOgZsvM2S5UVY5YFzOkEUPrSu4=
-app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545 h1:+Lak4m1zgsigQloOsvp8AJ+0XeX/+PGp9QP550xlbBQ=
-app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545/go.mod h1:uFrsdUBFbETiJlEmr4PtJWPsZlUpPj2bHQRhryu6ggk=
-app.yhyue.com/moapp/jypkg v1.21.4 h1:NApb2EOlUkncX9yjMjKDFyOXKK66vOMJ3HprzMx8alc=
-app.yhyue.com/moapp/jypkg v1.21.4/go.mod h1:wyJeNc8I9R5799tqch7n8SEZrB0s8nmNou0brBh91w4=
+app.yhyue.com/moapp/jypkg v1.21.11 h1:DcBNvSXKvoTNbjGu2ZgVcJowVz2Ls+iveCBekYD7UO0=
+app.yhyue.com/moapp/jypkg v1.21.11/go.mod h1:FylaC4MJ4G36WndktgeZfc8jTq3uvBGWIwbk02xfdQI=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 h1:WGi4OEIoqw6NpNFGioUEBZnjK9aBa+xJqf/5WY+QyhM=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161/go.mod h1:0Oj8SB4pVjdCLD28sy2zyM3hS0WHGpNuVcakLW43GmI=
 bp.jydev.jianyu360.cn/BP/jynsq v0.0.0-20220222052708-ebc43af90698/go.mod h1:ojo/AUH9Yr1wzarEjOaNMkj1Cet/9r8IgLyba64Z52E=
@@ -31,8 +29,8 @@ bp.jydev.jianyu360.cn/BaseService/gateway v0.0.0-20220419090715-88ddb32961be/go.
 bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4/go.mod h1:BMLd/5wb3BIEGhnEgF9y1sJN9P5/Dw9kYsoiE9V8I9g=
 bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2 h1:Qi8C7gZeR7+kjOtSl9ilR5HwbjCe8GO1RuotFb4+kFA=
 bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2/go.mod h1:v8y7FCbkKEIRP4Ie9ZM8NtoRP+Fk4O3C1hnexNusYIQ=
-bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240603091545-83ceaad11e6b h1:6f/if8nVoR89n7RbgFEniiUqt4QpqJNQX2kS2JJHDEM=
-bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240603091545-83ceaad11e6b/go.mod h1:rCCaOSWBYfQabf/yIvSVheSPtN2THnHeTl2J5/RrcuU=
+bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843 h1:u+8k/T0D6EUjj9BhI5RJdRa+8v4FZbyZhaNcm66L6Vs=
+bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843/go.mod h1:rCCaOSWBYfQabf/yIvSVheSPtN2THnHeTl2J5/RrcuU=
 bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20230911091604-2faa31032743 h1:7IaukyEAbMvgEv3/TiHlw7lzWPoksE4tVa1ap16RC9Q=
 bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20230911091604-2faa31032743/go.mod h1:1SQIPPL5Ya5BzQdByFKtTkXrXTWBv+PDqWIhNknLnZw=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.0-20220418005748-8ba5d936dd53/go.mod h1:E5lcDI3k4FESLxiAetCfWQTq8qfpy9cv0yN1oKoEO34=
@@ -42,8 +40,8 @@ bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 h1:lk3he0hY+8VK1/Hm+ZSlc
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3/go.mod h1:rRiGzKG4F/fmkNxXQCxrkxNWc8yf1SmW8qWCKfGIQSM=
 bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20220418072311-2062bed1e700/go.mod h1:KjcrxTzM96tBc6G4B8tlLBn1lrVy5UJYF8+eTdP4xAE=
 bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20220421015128-4a36f3eac5c5/go.mod h1:GT0QC4aaKDuXxAvaU4G02XjCc31TU1ctqBGqxQYOfC4=
-bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.16 h1:CckcpZZs1jb76sn8b7YDJZTh30py1RymWzuj3FVO6iI=
-bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.16/go.mod h1:2V4LPtebYd1sN0xFoWF0OC8M2PCzKubVxXA0f5+stnY=
+bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.18 h1:aJNS24p6SOAOsCMvdOF0togsiO6HxmLIExVyTjog8Io=
+bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.18/go.mod h1:03bxckJBVCjal3uQ1loJmupbYHWRnaRC3V5LG4bgg6Y=
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
@@ -1000,7 +998,6 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
 github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
 github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
-github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
@@ -1292,8 +1289,6 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
 github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
-github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 github.com/howeyc/fsnotify v0.9.0 h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY=
 github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -1482,8 +1477,6 @@ github.com/memcachier/mc v2.0.1+incompatible/go.mod h1:7bkvFE61leUBvXz+yxsOnGBQS
 github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
 github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
-github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615/go.mod h1:Ad7oeElCZqA1Ufj0U9/liOF4BtVepxRcTvr2ey7zTvM=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -1671,8 +1664,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/sirupsen/logrus v1.8.3 h1:DBBfY8eMYazKEJHb3JKpSPfpgd2mBCoNFlQx6C5fftU=
-github.com/sirupsen/logrus v1.8.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
 github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
 github.com/smartystreets/gunit v1.4.2/go.mod h1:ZjM1ozSIMJlAz/ay4SG8PeKF00ckUp+zMHZXV9/bvak=
@@ -1683,19 +1674,11 @@ github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd
 github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
-github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
-github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
-github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
-github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
-github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
 github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -1720,8 +1703,6 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
-github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
 github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
 github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
@@ -2231,7 +2212,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -2751,11 +2731,8 @@ gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaD
 gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
-gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
-gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
 gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

+ 12 - 3
src/jfw/modules/subscribepay/src/pay/aliPay.go

@@ -126,9 +126,11 @@ const (
 	ALI_DOCMEMBER_APP    = "ALID" // 剑鱼文库会员-app支付
 	ALI_DOCMEMBER_NATIVE = "alid" //剑鱼文库会员 -pc支付
 
+	ALI_PDFEXPORT_APP    = "ALIE" // 剑鱼pdf导出包-app支付
+	ALI_PDFEXPORT_NATIVE = "alie" //剑鱼pdf导出包 -pc支付
 )
 
-func (w *aliPayStruct) GetTradeno(tradenoSign string) (string, string) {
+func (w *aliPayStruct) GetTradeno(tradenoSign string, productType ...string) (string, string) {
 	tradeno, subject := "", ""
 	if tradenoSign == ALI_DATAEXPORT_NATIVE || tradenoSign == ALI_DATAEXPORT_APP {
 		subject = w.Subject_sjdc
@@ -160,7 +162,14 @@ func (w *aliPayStruct) GetTradeno(tradenoSign string) (string, string) {
 		subject = w.Subject_buyerPortraitPack
 	} else if tradenoSign == ALI_DOCMEMBER_APP || tradenoSign == ALI_DOCMEMBER_NATIVE {
 		subject = w.Subject_docMember
+	} else if tradenoSign == ALI_PDFEXPORT_APP || tradenoSign == ALI_PDFEXPORT_NATIVE {
+		t := "剑鱼标讯-pdf下载包"
+		if len(productType) > 0 {
+			t = fmt.Sprintf("剑鱼标讯-%s", productType[0])
+		}
+		subject = t
 	}
+
 	lenRandom := 6 - len([]rune(tradenoSign)) //控制长度
 	tradeno = fmt.Sprintf("%s_%d%s%s", tradenoSign, time.Now().UnixNano(), qutil.GetRandom(lenRandom), qutil.GetLetterRandom(6))
 	tradeno = processTradeno(tradeno)
@@ -168,13 +177,13 @@ func (w *aliPayStruct) GetTradeno(tradenoSign string) (string, string) {
 }
 
 // 获取网页支付二维码地址
-func (a *aliPayStruct) GetOrderPayParam(order_money float64, tradenoSign string) (string, string, error) {
+func (a *aliPayStruct) GetOrderPayParam(order_money float64, tradenoSign string, msg ...string) (string, string, error) {
 	//测试环境,1分钱
 	if config.Config.AllPayMoney > 0 {
 		order_money = float64(config.Config.AllPayMoney)
 	}
 	//支付标题
-	tradeno, subject := a.GetTradeno(tradenoSign)
+	tradeno, subject := a.GetTradeno(tradenoSign, msg...)
 	var bizByte []byte
 	methodStr := ""
 	if strings.ToUpper(tradenoSign) == tradenoSign { //app支付

+ 17 - 5
src/jfw/modules/subscribepay/src/pay/util.go

@@ -158,6 +158,14 @@ var (
 		"ali_app": ALI_DOCMEMBER_APP,
 		"ali_pc":  ALI_DOCMEMBER_NATIVE,
 	}
+	//pdf导出包
+	pdfExportMap = map[string]string{
+		"wx_js":   WX_PDFEXPORT_JSAPI,
+		"wx_app":  WX_PDFEXPORT_APP,
+		"wx_pc":   WX_PDFEXPORT_NATIVE,
+		"ali_app": ALI_PDFEXPORT_APP,
+		"ali_pc":  ALI_PDFEXPORT_NATIVE,
+	}
 	PayWayAndSign = map[string]map[string]string{
 		"subvip":            vipMap,
 		"entniche":          entnicheMap,
@@ -188,6 +196,9 @@ var (
 		"附件下载包":             filePackMap,
 		"采购单位画像包":           buyerPortraitPackMap,
 		"剑鱼文库会员":            docMemberMap,
+		"市场分析定制报告下载包":       pdfExportMap,
+		"业主采购分析报告下载包":       pdfExportMap,
+		"企业中标分析报告下载包":       pdfExportMap,
 	}
 	varOrderCode *orderCode
 
@@ -257,13 +268,14 @@ payWay 支付方式
 ⚠️ 需缓存tradeno
 */
 func CreateOrderPay(price int, productSign, ip, openid, appid, payWay, orderCode string, msg ...string) (tradeno, prepayid, payParam string, err error) {
+	var detailMsg string
+	if len(msg) > 0 {
+		detailMsg = msg[0]
+	}
 	switch payWay {
 	case "wx_js", "wx_app", "wx_pc": //微信公众号支付,微信app支付,微信扫码支付
 		var ret *map[string]string
-		var detailMsg string
-		if len(msg) > 0 {
-			detailMsg = msg[0]
-		}
+
 		tradeno, ret = WxStruct.CreatePrepayOrder(productSign, ip, openid, appid, detailMsg, price)
 		log.Println(tradeno, ret)
 		if ret == nil {
@@ -289,7 +301,7 @@ func CreateOrderPay(price int, productSign, ip, openid, appid, payWay, orderCode
 			payParam = (*ret)["codeurl"]
 		}
 	case "ali_app", "ali_pc": //支付宝app支付,支付宝扫码支付
-		payParam, tradeno, err = Alipay.GetOrderPayParam(qutil.Float64All(price), productSign)
+		payParam, tradeno, err = Alipay.GetOrderPayParam(qutil.Float64All(price), productSign, detailMsg)
 		if err != nil {
 			err = errors.New("创建支付宝订单出错")
 			return

+ 11 - 4
src/jfw/modules/subscribepay/src/pay/wxPay.go

@@ -69,6 +69,10 @@ const (
 	WX_DOCMEMBER_JSAPI = "WJD" //剑鱼文库会员 微信js支付
 	WX_DOCMEMBER_APP   = "WAD" //剑鱼文库会员 app微信支付
 	WX_DOCMBER_NATIVE  = "WPD" //剑鱼文库会员 微信pc支付
+
+	WX_PDFEXPORT_JSAPI  = "WEJ"
+	WX_PDFEXPORT_APP    = "WEA"
+	WX_PDFEXPORT_NATIVE = "WEN"
 )
 
 var WxStruct *WeixinStruct
@@ -152,14 +156,15 @@ func (w *WeixinStruct) CreatePrepayOrder(tradeno, ip, openid, appid, detailmsg s
 	attachmsg, bodymsg, detailmsg = w.getPayShwoMsg(tradeno, detailmsg)
 	//支付类型分类
 	tradeType := ""
-	if tradeno == WX_REWARD_JSAPI || tradeno == WX_DATAEXPORT_JSAPI || tradeno == WX_DATAREPORT_JSAPI || tradeno == WX_SUBVIP_JSAPI || tradeno == WX_COURSE_JSAPI || tradeno == WX_COURSEONLINE_JSAPI || tradeno == WX_MEMBER_JSAPI || tradeno == WX_AIFORECASTPACK_JSAPI || tradeno == WX_BIDFILE_JSAPI || tradeno == WX_INTEGRAL_JSAPI || tradeno == WX_DATAPACK_JSAIP || tradeno == WX_AREAPACK_JSAPI || tradeno == WX_FILEPACK_JSAPI || tradeno == WX_BUYERPORTRAITPACK_JSAPI || tradeno == WX_DOCMEMBER_JSAPI || tradeno == WX_DENRISPRODUCT { //微信js支付
+	if tradeno == WX_REWARD_JSAPI || tradeno == WX_DATAEXPORT_JSAPI || tradeno == WX_DATAREPORT_JSAPI || tradeno == WX_SUBVIP_JSAPI || tradeno == WX_COURSE_JSAPI || tradeno == WX_COURSEONLINE_JSAPI || tradeno == WX_MEMBER_JSAPI || tradeno == WX_AIFORECASTPACK_JSAPI || tradeno == WX_BIDFILE_JSAPI || tradeno == WX_INTEGRAL_JSAPI || tradeno == WX_DATAPACK_JSAIP || tradeno == WX_AREAPACK_JSAPI || tradeno == WX_FILEPACK_JSAPI || tradeno == WX_BUYERPORTRAITPACK_JSAPI || tradeno == WX_DOCMEMBER_JSAPI || tradeno == WX_DENRISPRODUCT || tradeno == WX_PDFEXPORT_JSAPI { //微信js支付
 		tradeType = "JSAPI"
-	} else if tradeno == WX_DATAEXPORT_APP || tradeno == WX_DATAREPORT_APP || tradeno == WX_SUBVIP_APP || tradeno == WX_COURSE_APP || tradeno == WX_ENTNICHE_APP || tradeno == WX_COURSEONLINE_APP || tradeno == WX_MEMBER_APP || tradeno == WX_AIFORECASTPACK_APP || tradeno == WX_BIDFILE_APP || tradeno == WX_INTEGRAL_APP || tradeno == WX_DATAPACK_APP || tradeno == WX_AREAPACK_APP || tradeno == WX_FILEPACK_APP || tradeno == WX_BUYERPORTRAITPACK_APP || tradeno == WX_DOCMEMBER_APP { //app支付
+	} else if tradeno == WX_DATAEXPORT_APP || tradeno == WX_DATAREPORT_APP || tradeno == WX_SUBVIP_APP || tradeno == WX_COURSE_APP || tradeno == WX_ENTNICHE_APP || tradeno == WX_COURSEONLINE_APP || tradeno == WX_MEMBER_APP || tradeno == WX_AIFORECASTPACK_APP || tradeno == WX_BIDFILE_APP || tradeno == WX_INTEGRAL_APP || tradeno == WX_DATAPACK_APP || tradeno == WX_AREAPACK_APP || tradeno == WX_FILEPACK_APP || tradeno == WX_BUYERPORTRAITPACK_APP || tradeno == WX_DOCMEMBER_APP || tradeno == WX_PDFEXPORT_APP { //app支付
 		tradeType = "APP"
 		appid = w.Appid_app
-	} else if tradeno == WX_DATAEXPORT_NATIVE || tradeno == WX_COURSE_NATIVE || tradeno == WX_COURSEONLINE_NATIVE || tradeno == WX_DATAREPORT_NATIVE || tradeno == WX_ENTNICHE_NATIVE || tradeno == WX_SUBVIP_NATIVE || tradeno == WX_MEMBER_NATIVE || tradeno == WX_AIFORECASTPACK_NATIVE || tradeno == WX_BIDFILE_NATIVE || tradeno == WX_INTEGRAL_NATIVE || tradeno == WX_DATAPACK_NATIVE || tradeno == WX_AREAPACK_NATIVE || tradeno == WX_FILEPACK_NATIVE || tradeno == WX_BUYERPORTRAITPACK_NATIVE || tradeno == WX_DOCMBER_NATIVE { //扫码支付
+	} else if tradeno == WX_DATAEXPORT_NATIVE || tradeno == WX_COURSE_NATIVE || tradeno == WX_COURSEONLINE_NATIVE || tradeno == WX_DATAREPORT_NATIVE || tradeno == WX_ENTNICHE_NATIVE || tradeno == WX_SUBVIP_NATIVE || tradeno == WX_MEMBER_NATIVE || tradeno == WX_AIFORECASTPACK_NATIVE || tradeno == WX_BIDFILE_NATIVE || tradeno == WX_INTEGRAL_NATIVE || tradeno == WX_DATAPACK_NATIVE || tradeno == WX_AREAPACK_NATIVE || tradeno == WX_FILEPACK_NATIVE || tradeno == WX_BUYERPORTRAITPACK_NATIVE || tradeno == WX_DOCMBER_NATIVE || tradeno == WX_PDFEXPORT_NATIVE { //扫码支付
 		tradeType = "NATIVE"
 	}
+
 	tradeno = w.GetTradeno(tradeno)
 	//测试环境微信支付需要转换对应的正式环境的openid
 	if w.OpenidSwitch != nil {
@@ -222,6 +227,9 @@ func (w *WeixinStruct) getPayShwoMsg(tradeno, msg string) (attachmsg, bodymsg, d
 		attachmsg, bodymsg, detailmsg = w.BuyerPortraitPack_msg, w.BuyerPortraitPack_msg, w.BuyerPortraitPack_msg
 	} else if tradeno == WX_DOCMEMBER_APP || tradeno == WX_DOCMEMBER_JSAPI || tradeno == WX_DOCMBER_NATIVE {
 		attachmsg, bodymsg, detailmsg = w.DocMember_msg, w.DocMember_msg, w.DocMember_msg
+	} else if tradeno == WX_PDFEXPORT_NATIVE || tradeno == WX_PDFEXPORT_APP || tradeno == WX_PDFEXPORT_JSAPI {
+		t := fmt.Sprintf("剑鱼标讯-%s", msg)
+		attachmsg, bodymsg, detailmsg = t, t, t
 	}
 
 	if attachmsg == "" {
@@ -230,7 +238,6 @@ func (w *WeixinStruct) getPayShwoMsg(tradeno, msg string) (attachmsg, bodymsg, d
 		} else {
 			attachmsg = "剑鱼标讯"
 		}
-
 	}
 	if bodymsg == "" {
 		if msg != "" {

+ 3 - 2
src/jfw/modules/subscribepay/src/service/commonAction.go

@@ -382,12 +382,13 @@ func (this *CommonAction) GetCommonPayParam() {
 				}
 			}
 		}
+		var product_type = qutil.ObjToString((*oData)["product_type"])
 		//重新生成支付串
-		productFlag, ok := pay.PayWayAndSign[qutil.ObjToString((*oData)["product_type"])][payway_req]
+		productFlag, ok := pay.PayWayAndSign[product_type][payway_req]
 		if !ok {
 			return &entity.FuncResult{false, errors.New("未知支付类型:" + payway_req), nil}
 		}
-		tradeno, prepayid, payParam, err := pay.CreateOrderPay(totalfee, productFlag, this.IP(), qutil.ObjToString(this.GetSession("s_m_openid")), "", payway_req, orderCode)
+		tradeno, prepayid, payParam, err := pay.CreateOrderPay(totalfee, productFlag, this.IP(), qutil.ObjToString(this.GetSession("s_m_openid")), "", payway_req, orderCode, product_type)
 		if err != nil {
 			return &entity.FuncResult{false, errors.New(fmt.Sprintf("创建支付失败[%v]", err)), nil}
 		}

+ 13 - 0
src/jfw/modules/subscribepay/src/service/payCallback.go

@@ -128,6 +128,10 @@ func (this *PayCallBackAction) TestPay() {
 			if entity.JyDocMember.PayCallBack(thisParam) {
 				success = true
 			}
+		case entity.PDFPACK_WINNER, entity.PDFPACK_BUYER, entity.PDFPACK_MARKET:
+			if entity.JyPdfExportPack.PayCallBack(thisParam) {
+				success = true
+			}
 		default:
 			//碎片化程序
 			if typeFlag == "综合服务" || strings.Index(typeFlag, "采购意向") > -1 || strings.Index(typeFlag, "最新采购") > -1 ||
@@ -258,6 +262,11 @@ func (a *PayCallBackAction) AliPayCallback() {
 				log.Printf("支付宝剑鱼文库会员支付回调更新执行出错 %+v\n", thisParam)
 				return false
 			}
+		} else if strings.HasPrefix(outTradeno, pay.ALI_PDFEXPORT_NATIVE) || strings.HasPrefix(outTradeno, pay.ALI_PDFEXPORT_APP) { //pdf下载包回调
+			if !entity.JyPdfExportPack.PayCallBack(thisParam) {
+				log.Printf("支付宝pdf下载包支付回调更新执行出错 %+v\n", thisParam)
+				return false
+			}
 		} else {
 			log.Printf("支付宝支付完成回调 未知订单类型%s\n", thisParam.OutTradeno)
 		}
@@ -369,6 +378,10 @@ func (p *PayCallBackAction) WxPayCallback() {
 			if update = entity.JyDocMember.PayCallBack(thisParam); !update {
 				log.Printf("微信剑鱼文库会员支付回调更新执行出错 %+v\n", thisParam)
 			}
+		} else if strings.HasPrefix(outTradeno, pay.WX_PDFEXPORT_NATIVE) || strings.HasPrefix(outTradeno, pay.WX_PDFEXPORT_APP) || strings.HasPrefix(outTradeno, pay.WX_PDFEXPORT_JSAPI) { //pdf下载包回调
+			if update = entity.JyPdfExportPack.PayCallBack(thisParam); !update {
+				log.Printf("微信下载包支付回调更新执行出错 %+v\n", thisParam)
+			}
 		} else {
 			log.Printf("微信支付完成回调 未知订单类型%s\n", thisParam.OutTradeno)
 		}

+ 106 - 0
src/jfw/modules/subscribepay/src/service/pdfExportPack.go

@@ -0,0 +1,106 @@
+package service
+
+import (
+	. "app.yhyue.com/moapp/jybase/api"
+	qutil "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"fmt"
+	"jy/src/jfw/modules/subscribepay/src/config"
+	"jy/src/jfw/modules/subscribepay/src/entity"
+	"log"
+	"time"
+)
+
+type PdfExportPackService struct {
+	*xweb.Action
+	account    xweb.Mapper `xweb:"/pdfExportPack/account"`    //pdf下载包账户余额
+	recordList xweb.Mapper `xweb:"/pdfExportPack/recordList"` //pdf下载包使用记录
+	download   xweb.Mapper `xweb:"/pdfExportPack/download"`   //pdf下载
+}
+
+// Account pdf下载包账户余额
+func (this *PdfExportPackService) Account() {
+	userId, _ := this.GetSession("userId").(string)
+	rData, errMsg := func() (interface{}, error) {
+		vip := jy.GetBigVipUserBaseMsg(this.Session(), *config.Middleground)
+		account, err := entity.JyPdfExportPack.PackQuery(userId, vip)
+		if err != nil {
+			return nil, err
+		}
+		return account, nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s 查询pdf下载包余额异常Account 异常:%s\n", userId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}
+
+// RecordList pdf下载包流水记录
+func (this *PdfExportPackService) RecordList() {
+	userId, _ := this.GetSession("userId").(string)
+	productCode, _ := this.GetInteger("productCode")
+	pageSize, _ := this.GetInteger("pageSize")
+	pageNum, _ := this.GetInteger("pageNum")
+	rData, errMsg := func() (interface{}, error) {
+		productName, err := entity.JyPdfExportPack.GetNameByCode(productCode)
+		if err != nil {
+			return nil, err
+		}
+		var (
+			accountId, queryUserId string
+		)
+		vip := jy.GetBigVipUserBaseMsg(this.Session(), *config.Middleground)
+		if vip.Pid != "" {
+			//自账号查询使用人是自己 账户主张号和当前账号
+			accountId = fmt.Sprintf("%s,%s", fmt.Sprintf("%s%s", entity.ParentResourceIdPrefix, vip.Pid), userId)
+		} else {
+			accountId = fmt.Sprintf("%s,%s", fmt.Sprintf("%s%s", entity.ParentResourceIdPrefix, userId), userId)
+		}
+		returnList, total := entity.InitFindRecord(queryUserId, accountId, productName, "", "", pageSize, pageNum, -1).DefaultData()
+
+		for i := 0; i < len(returnList); i++ {
+			createTime, createtimeParseErr := time.Parse(time.RFC3339, qutil.ObjToString(returnList[i]["createTime"]))
+			if createtimeParseErr == nil {
+				returnList[i]["createTime"] = createTime.Unix()
+			}
+		}
+
+		returnData := map[string]interface{}{
+			"list": returnList,
+		}
+		returnData["total"] = total
+		return returnData, nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s %d PdfExportPackService.RecordList 异常:%s\n", userId, productCode, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}
+
+func (this *PdfExportPackService) Download() {
+	var (
+		filterEid = this.GetString("filterId")
+		filterId  string
+		userId, _ = this.GetSession("userId").(string)
+	)
+	rData, errMsg := func() (interface{}, error) {
+		if tArr := encrypt.DecodeArticleId2ByCheck(filterEid); len(tArr) > 0 {
+			filterId = tArr[0]
+		}
+		if filterId == "" {
+			return nil, fmt.Errorf("未知报告")
+		}
+		vip := jy.GetBigVipUserBaseMsg(this.Session(), *config.Middleground)
+		pdfUrl, err := entity.JyPdfExportPack.GetDownLoadPdf(userId, vip, filterId)
+		if err != nil {
+			return nil, err
+		}
+		return pdfUrl, nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s %s PdfExportPackService.Download 异常:%s\n", userId, filterId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}

+ 1 - 1
src/jfw/modules/subscribepay/src/service/resourcePack.go

@@ -19,7 +19,7 @@ import (
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 )
 
-//资源包相关(数据流量包,附件下载包,采购单位流量包...
+//资源包相关(数据流量包,附件下载包,采购单位流量包)
 
 type ResourcePack struct {
 	*xweb.Action

+ 338 - 338
src/jfw/modules/subscribepay/src/util/dataExportExcel.go

@@ -2,381 +2,381 @@ package util
 
 //数据导出excel
 import (
-    "errors"
-    "fmt"
-    "io"
-    "jy/src/jfw/modules/subscribepay/src/config"
-    "log"
-    "os"
-    "strings"
-    "time"
+	"errors"
+	"fmt"
+	"io"
+	"jy/src/jfw/modules/subscribepay/src/config"
+	"log"
+	"os"
+	"strings"
+	"time"
 
-    qutil "app.yhyue.com/moapp/jybase/common"
-    "github.com/gogf/gf/v2/util/gconv"
+	qutil "app.yhyue.com/moapp/jybase/common"
+	"github.com/gogf/gf/v2/util/gconv"
 
-    "github.com/tealeg/xlsx"
+	"github.com/tealeg/xlsx"
 )
 
 var (
-    defaultExcelBorder = xlsx.Border{ //边框样式
-        Left:        "dotted",
-        LeftColor:   "00000000",
-        Right:       "dotted",
-        RightColor:  "00000000",
-        Top:         "dotted",
-        TopColor:    "00000000",
-        Bottom:      "dotted",
-        BottomColor: "00000000",
-    }
+	defaultExcelBorder = xlsx.Border{ //边框样式
+		Left:        "dotted",
+		LeftColor:   "00000000",
+		Right:       "dotted",
+		RightColor:  "00000000",
+		Top:         "dotted",
+		TopColor:    "00000000",
+		Bottom:      "dotted",
+		BottomColor: "00000000",
+	}
 
-    defaultExcelAlignment = xlsx.Alignment{ //对其方式
-        Horizontal: "left",
-        Vertical:   "center",
-        WrapText:   true,
-    }
-    defaultFont = xlsx.NewFont(12, "等线")
-    blueFont    = xlsx.Font{
-        Size:  12,
-        Name:  "等线",
-        Color: "00376092",
-    }
+	defaultExcelAlignment = xlsx.Alignment{ //对其方式
+		Horizontal: "left",
+		Vertical:   "center",
+		WrapText:   true,
+	}
+	defaultFont = xlsx.NewFont(12, "等线")
+	blueFont    = xlsx.Font{
+		Size:  12,
+		Name:  "等线",
+		Color: "00376092",
+	}
 )
 
 // Information 情报
 type Information struct {
-    Id         string  `ch:"id" json:"id"`
-    Title      string  `ch:"title" json:"title"`
-    Summary    string  `ch:"summary" json:"summary"`
-    Content    string  `ch:"content" json:"content"`
-    Basis      string  `ch:"basis" json:"basis"`
-    Area       string  `ch:"area" json:"area"`
-    City       string  `ch:"city" json:"city"`
-    DataJson   string  `ch:"datajson" json:"datajson"`
-    Class      string  `ch:"class" json:"class"`
-    DataJsonId string  `ch:"datajson_id" json:"datajson_id"`
-    Buyer      string  `json:"buyer"`
-    Amount     float64 `json:"amount"`
-    Href       string  `json:"href"`
+	Id         string  `ch:"id" json:"id"`
+	Title      string  `ch:"title" json:"title"`
+	Summary    string  `ch:"summary" json:"summary"`
+	Content    string  `ch:"content" json:"content"`
+	Basis      string  `ch:"basis" json:"basis"`
+	Area       string  `ch:"area" json:"area"`
+	City       string  `ch:"city" json:"city"`
+	DataJson   string  `ch:"datajson" json:"datajson"`
+	Class      string  `ch:"class" json:"class"`
+	DataJsonId string  `ch:"datajson_id" json:"datajson_id"`
+	Buyer      string  `json:"buyer"`
+	Amount     float64 `json:"amount"`
+	Href       string  `json:"href"`
 }
 
 // 获取
 func GetExcelFilePath(orderCode string, num int) string {
-    now := time.Now()
-    filename := fmt.Sprintf("%s.xlsx", fmt.Sprintf("%s_%d_%s_%s", now.Format("20060102"), num, orderCode, qutil.GetLetterRandom(5)))
-    return fmt.Sprintf("/dataexport/%s/%s/%s", now.Format("2006"), now.Format("01"), filename)
+	now := time.Now()
+	filename := fmt.Sprintf("%s.xlsx", fmt.Sprintf("%s_%d_%s_%s", now.Format("20060102"), num, orderCode, qutil.GetLetterRandom(5)))
+	return fmt.Sprintf("/dataexport/%s/%s/%s", now.Format("2006"), now.Format("01"), filename)
 }
 
 // 获取excel导出数据长度
 func GetDataExportFileDataLen(path string) (int, error) {
-    xFile, err := xlsx.OpenFile(path)
-    if err != nil {
-        return -1, err
-    }
-    sheet1, ok := xFile.Sheet["Sheet1"]
-    if !ok {
-        return -1, fmt.Errorf("not find sheet1")
-    }
-    if len(sheet1.Rows) == 0 {
-        return -1, fmt.Errorf("sheet1 hasn't Rows data ")
-    }
-    //避免最后一行为合并单元格数据
-    for l := len(sheet1.Rows) - 1; l > 0; l-- {
-        if sheet1.Rows[l].Cells[0].Value != "" {
-            return sheet1.Rows[l].Cells[0].Int()
-        }
-    }
-    return -1, fmt.Errorf("sheet1 get error")
+	xFile, err := xlsx.OpenFile(path)
+	if err != nil {
+		return -1, err
+	}
+	sheet1, ok := xFile.Sheet["Sheet1"]
+	if !ok {
+		return -1, fmt.Errorf("not find sheet1")
+	}
+	if len(sheet1.Rows) == 0 {
+		return -1, fmt.Errorf("sheet1 hasn't Rows data ")
+	}
+	//避免最后一行为合并单元格数据
+	for l := len(sheet1.Rows) - 1; l > 0; l-- {
+		if sheet1.Rows[l].Cells[0].Value != "" {
+			return sheet1.Rows[l].Cells[0].Int()
+		}
+	}
+	return -1, fmt.Errorf("sheet1 get error")
 }
 
 // 生成数据导出excel
 func CreateDataExportExcelFile(list *[]map[string]interface{}, isSenior bool, filePath string) error {
-    file, err := ExportExcelFile(list, isSenior)
-    if err != nil {
-        return err
-    }
-    if err := FolderCheck(filePath); err != nil {
-        return err
-    }
-    return file.Save(filePath)
+	file, err := ExportExcelFile(list, isSenior)
+	if err != nil {
+		return err
+	}
+	if err := FolderCheck(filePath); err != nil {
+		return err
+	}
+	return file.Save(filePath)
 }
 func ExportExcelFile(list *[]map[string]interface{}, isSenior bool) (*xlsx.File, error) {
-    //if list == nil || len(*list) == 0 {
-    //	return errors.New("未查询到数据")
-    //}
-    //创建excel文件
-    file := xlsx.NewFile()
-    sheet, err := file.AddSheet("Sheet1")
-    if err != nil {
-        return nil, errors.New("创建Sheet1失败")
-    }
-    var row *xlsx.Row
-    var cell *xlsx.Cell
-    var excelHead []*config.ExeclCell
-    //添加头部标题
-    if !isSenior {
-        row = sheet.AddRow()
-        row.SetHeight(20)
-        excelHead = config.ExConf.Standard_Fields
-        for index, excel := range excelHead {
-            cell = row.AddCell()
-            cell.SetString(excel.Name)
-            style := &xlsx.Style{
-                Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
-                Alignment: defaultExcelAlignment,
-                Font:      *defaultFont,
-                Border:    defaultExcelBorder,
-            }
-            cell.SetStyle(style)
-            sheet.Col(index).Width = excel.Width
-        }
-    } else {
-        excelHead = config.ExConf.Senior_Fields
-        //铺设第一层title
-        row = sheet.AddRow()
-        row.SetHeight(20)
-        lastF := false //合并行时标识
-        for _, excel := range excelHead {
-            if excel.VMerge != 1 && excel.HMerge == 0 {
-                if lastF { //不可读取内容
-                    lastF = false
-                    continue
-                }
-                cell = row.AddCell()
-            } else {
-                lastF = true
-                cell = row.AddCell()
-                cell.SetString(excel.Name)
-                cell.VMerge = excel.VMerge
-                cell.HMerge = excel.HMerge
-            }
-            if excel.HMerge != 0 {
-                lastF = true
-            }
-            style := &xlsx.Style{
-                Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
-                Alignment: defaultExcelAlignment,
-                Font:      *defaultFont,
-                Border:    defaultExcelBorder,
-            }
-            cell.SetStyle(style)
-        }
-        //铺设第二层title并设置宽度
-        row = sheet.AddRow()
-        row.SetHeight(20)
-        cNum := 0
-        for _, excel := range excelHead {
-            if excel.HMerge != 0 {
-                continue
-            }
-            cell = row.AddCell()
-            if excel.VMerge != 1 {
-                cell.SetString(excel.Name)
-            }
-            sheet.Col(cNum).Width = excel.Width
-            cNum++
-            cell.SetStyle(&xlsx.Style{
-                Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
-                Border:    defaultExcelBorder,
-                Alignment: defaultExcelAlignment,
-                Font:      *defaultFont,
-            })
-        }
-    }
-    if list != nil && len(*list) > 0 {
-        //填充数据
-        for k, data := range *list {
-            winnerMaps := gconv.Maps(data["winnerMaps"])
-            winnerTotal := len(winnerMaps)
-            data["index"] = k + 1
-            if winnerTotal > 0 {
-                for index, winnerDatas := range winnerMaps {
-                    row = sheet.AddRow()
-                    row.SetHeight(20)
-                    for _, v := range excelHead {
-                        if v.Filed == "" {
-                            continue
-                        }
-                        cell = row.AddCell()
-                        style := &xlsx.Style{
-                            Border:    defaultExcelBorder,
-                            Alignment: defaultExcelAlignment,
-                        }
-                        if v.Filed != "legal_person" && v.Filed != "company_phone" && v.Filed != "company_email" && v.Filed != "company_name" {
-                            if index == 0 {
-                                cell.VMerge = winnerTotal - 1
-                                if v.Filed == "title" || v.Filed == "url" {
-                                    cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["url_jump"], data[v.Filed]))
-                                } else if v.Filed == "href" {
-                                    cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["href"], data[v.Filed]))
-                                } else {
-                                    cell.SetValue(data[v.Filed])
-                                }
-                            }
-                        } else {
-                            cell.SetValue(winnerDatas[v.Filed])
-                        }
-                        if v.Filed == "title" {
-                            style.Font = blueFont
-                        }
-                        cell.SetStyle(style)
-                    }
-                }
-            } else {
-                row = sheet.AddRow()
-                row.SetHeight(20)
-                for _, v := range excelHead {
-                    if v.Filed == "" {
-                        continue
-                    }
-                    cell = row.AddCell()
-                    style := &xlsx.Style{
-                        Border:    defaultExcelBorder,
-                        Alignment: defaultExcelAlignment,
-                    }
-                    if v.Filed == "title" || v.Filed == "url" {
-                        cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["url_jump"], data[v.Filed]))
-                    } else if v.Filed == "href" {
-                        cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["href"], data[v.Filed]))
-                    } else {
-                        cell.SetValue(data[v.Filed])
-                    }
-                    if v.Filed == "title" {
-                        style.Font = blueFont
-                    }
-                    cell.SetStyle(style)
-                }
-            }
-        }
-    }
-    return file, nil
+	//if list == nil || len(*list) == 0 {
+	//	return errors.New("未查询到数据")
+	//}
+	//创建excel文件
+	file := xlsx.NewFile()
+	sheet, err := file.AddSheet("Sheet1")
+	if err != nil {
+		return nil, errors.New("创建Sheet1失败")
+	}
+	var row *xlsx.Row
+	var cell *xlsx.Cell
+	var excelHead []*config.ExeclCell
+	//添加头部标题
+	if !isSenior {
+		row = sheet.AddRow()
+		row.SetHeight(20)
+		excelHead = config.ExConf.Standard_Fields
+		for index, excel := range excelHead {
+			cell = row.AddCell()
+			cell.SetString(excel.Name)
+			style := &xlsx.Style{
+				Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
+				Alignment: defaultExcelAlignment,
+				Font:      *defaultFont,
+				Border:    defaultExcelBorder,
+			}
+			cell.SetStyle(style)
+			sheet.Col(index).Width = excel.Width
+		}
+	} else {
+		excelHead = config.ExConf.Senior_Fields
+		//铺设第一层title
+		row = sheet.AddRow()
+		row.SetHeight(20)
+		lastF := false //合并行时标识
+		for _, excel := range excelHead {
+			if excel.VMerge != 1 && excel.HMerge == 0 {
+				if lastF { //不可读取内容
+					lastF = false
+					continue
+				}
+				cell = row.AddCell()
+			} else {
+				lastF = true
+				cell = row.AddCell()
+				cell.SetString(excel.Name)
+				cell.VMerge = excel.VMerge
+				cell.HMerge = excel.HMerge
+			}
+			if excel.HMerge != 0 {
+				lastF = true
+			}
+			style := &xlsx.Style{
+				Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
+				Alignment: defaultExcelAlignment,
+				Font:      *defaultFont,
+				Border:    defaultExcelBorder,
+			}
+			cell.SetStyle(style)
+		}
+		//铺设第二层title并设置宽度
+		row = sheet.AddRow()
+		row.SetHeight(20)
+		cNum := 0
+		for _, excel := range excelHead {
+			if excel.HMerge != 0 {
+				continue
+			}
+			cell = row.AddCell()
+			if excel.VMerge != 1 {
+				cell.SetString(excel.Name)
+			}
+			sheet.Col(cNum).Width = excel.Width
+			cNum++
+			cell.SetStyle(&xlsx.Style{
+				Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
+				Border:    defaultExcelBorder,
+				Alignment: defaultExcelAlignment,
+				Font:      *defaultFont,
+			})
+		}
+	}
+	if list != nil && len(*list) > 0 {
+		//填充数据
+		for k, data := range *list {
+			winnerMaps := gconv.Maps(data["winnerMaps"])
+			winnerTotal := len(winnerMaps)
+			data["index"] = k + 1
+			if winnerTotal > 0 {
+				for index, winnerDatas := range winnerMaps {
+					row = sheet.AddRow()
+					row.SetHeight(20)
+					for _, v := range excelHead {
+						if v.Filed == "" {
+							continue
+						}
+						cell = row.AddCell()
+						style := &xlsx.Style{
+							Border:    defaultExcelBorder,
+							Alignment: defaultExcelAlignment,
+						}
+						if v.Filed != "legal_person" && v.Filed != "company_phone" && v.Filed != "company_email" && v.Filed != "company_name" {
+							if index == 0 {
+								cell.VMerge = winnerTotal - 1
+								if v.Filed == "title" || v.Filed == "url" {
+									cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["url_jump"], data[v.Filed]))
+								} else if v.Filed == "href" {
+									cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["href"], data[v.Filed]))
+								} else {
+									cell.SetValue(data[v.Filed])
+								}
+							}
+						} else {
+							cell.SetValue(winnerDatas[v.Filed])
+						}
+						if v.Filed == "title" {
+							style.Font = blueFont
+						}
+						cell.SetStyle(style)
+					}
+				}
+			} else {
+				row = sheet.AddRow()
+				row.SetHeight(20)
+				for _, v := range excelHead {
+					if v.Filed == "" {
+						continue
+					}
+					cell = row.AddCell()
+					style := &xlsx.Style{
+						Border:    defaultExcelBorder,
+						Alignment: defaultExcelAlignment,
+					}
+					if v.Filed == "title" || v.Filed == "url" {
+						cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["url_jump"], data[v.Filed]))
+					} else if v.Filed == "href" {
+						cell.SetFormula(fmt.Sprintf("=HYPERLINK(\"%s\",\"%s\")", data["href"], data[v.Filed]))
+					} else {
+						cell.SetValue(data[v.Filed])
+					}
+					if v.Filed == "title" {
+						style.Font = blueFont
+					}
+					cell.SetStyle(style)
+				}
+			}
+		}
+	}
+	return file, nil
 }
 
 // 校验文件夹是否存在;
 // 若不存在则创建;
 func FolderCheck(path string) error {
-    pathCheck := path[:strings.LastIndex(path, "/")]
-    //校验文件夹是否存在
-    _, pathError := os.Stat(pathCheck)
-    if pathError != nil && os.IsNotExist(pathError) {
-        // 创建文件夹
-        return os.MkdirAll(pathCheck, os.ModePerm)
-    }
-    return nil
+	pathCheck := path[:strings.LastIndex(path, "/")]
+	//校验文件夹是否存在
+	_, pathError := os.Stat(pathCheck)
+	if pathError != nil && os.IsNotExist(pathError) {
+		// 创建文件夹
+		return os.MkdirAll(pathCheck, os.ModePerm)
+	}
+	return nil
 }
 
 // 移动文件至指定目录
 func MoveFile(src, dst string) (int64, error) {
-    srcFile, err := os.Open(src)
-    if err != nil {
-        return 0, err
-    }
-    defer srcFile.Close()
-    //文件夹
-    err = FolderCheck(dst)
-    if err != nil {
-        return 0, err
-    }
-    dstFile, err := os.Create(dst)
-    if err != nil {
-        return 0, err
-    }
-    defer dstFile.Close()
-    return io.Copy(dstFile, srcFile)
+	srcFile, err := os.Open(src)
+	if err != nil {
+		return 0, err
+	}
+	defer srcFile.Close()
+	//文件夹
+	err = FolderCheck(dst)
+	if err != nil {
+		return 0, err
+	}
+	dstFile, err := os.Create(dst)
+	if err != nil {
+		return 0, err
+	}
+	defer dstFile.Close()
+	return io.Copy(dstFile, srcFile)
 }
 
 // 人脉通导出情报信息
 func ExportExcelFileForNw(list map[string][]Information) (*xlsx.File, error) {
-    //创建excel文件
-    file := xlsx.NewFile()
-    for s, information := range list {
-        sheet, err := file.AddSheet(s)
-        if err != nil {
-            log.Println("sheet创建失败: ", s)
-            return nil, errors.New(s + "创建Sheet1失败")
-        }
-        var row *xlsx.Row
-        var cell *xlsx.Cell
-        excelHead := config.ExConf.NetWork_Fields
-        //铺设第一层title
-        row = sheet.AddRow()
-        row.SetHeight(20)
-        lastF := false //合并行时标识
-        for _, excel := range excelHead {
-            if excel.VMerge != 1 && excel.HMerge == 0 {
-                if lastF { //不可读取内容
-                    lastF = false
-                    continue
-                }
-                cell = row.AddCell()
-            } else {
-                lastF = true
-                cell = row.AddCell()
-                cell.SetString(excel.Name)
-                cell.VMerge = excel.VMerge
-                cell.HMerge = excel.HMerge
-            }
-            if excel.HMerge != 0 {
-                lastF = true
-            }
-            style := &xlsx.Style{
-                Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
-                Alignment: defaultExcelAlignment,
-                Font:      *defaultFont,
-                Border:    defaultExcelBorder,
-            }
-            cell.SetStyle(style)
-        }
-        //铺设第二层title并设置宽度
-        row = sheet.AddRow()
-        row.SetHeight(20)
-        cNum := 0
-        for _, excel := range excelHead {
-            if excel.HMerge != 0 {
-                continue
-            }
-            cell = row.AddCell()
-            if excel.VMerge != 1 {
-                cell.SetString(excel.Name)
-            }
-            sheet.Col(cNum).Width = excel.Width
-            cNum++
-            cell.SetStyle(&xlsx.Style{
-                Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
-                Border:    defaultExcelBorder,
-                Alignment: defaultExcelAlignment,
-                Font:      *defaultFont,
-            })
-        }
+	//创建excel文件
+	file := xlsx.NewFile()
+	for s, information := range list {
+		sheet, err := file.AddSheet(s)
+		if err != nil {
+			log.Println("sheet创建失败: ", s)
+			return nil, errors.New(s + "创建Sheet1失败")
+		}
+		var row *xlsx.Row
+		var cell *xlsx.Cell
+		excelHead := config.ExConf.NetWork_Fields
+		//铺设第一层title
+		row = sheet.AddRow()
+		row.SetHeight(20)
+		lastF := false //合并行时标识
+		for _, excel := range excelHead {
+			if excel.VMerge != 1 && excel.HMerge == 0 {
+				if lastF { //不可读取内容
+					lastF = false
+					continue
+				}
+				cell = row.AddCell()
+			} else {
+				lastF = true
+				cell = row.AddCell()
+				cell.SetString(excel.Name)
+				cell.VMerge = excel.VMerge
+				cell.HMerge = excel.HMerge
+			}
+			if excel.HMerge != 0 {
+				lastF = true
+			}
+			style := &xlsx.Style{
+				Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
+				Alignment: defaultExcelAlignment,
+				Font:      *defaultFont,
+				Border:    defaultExcelBorder,
+			}
+			cell.SetStyle(style)
+		}
+		//铺设第二层title并设置宽度
+		row = sheet.AddRow()
+		row.SetHeight(20)
+		cNum := 0
+		for _, excel := range excelHead {
+			if excel.HMerge != 0 {
+				continue
+			}
+			cell = row.AddCell()
+			if excel.VMerge != 1 {
+				cell.SetString(excel.Name)
+			}
+			sheet.Col(cNum).Width = excel.Width
+			cNum++
+			cell.SetStyle(&xlsx.Style{
+				Fill:      *xlsx.NewFill("solid", excel.Color, excel.Color),
+				Border:    defaultExcelBorder,
+				Alignment: defaultExcelAlignment,
+				Font:      *defaultFont,
+			})
+		}
 
-        if information != nil && len(information) > 0 {
-            //填充数据
-            for i, info := range information {
-                m := make(map[string]interface{})
-                m = gconv.Map(info)
-                row = sheet.AddRow()
-                row.SetHeight(20)
-                for _, v := range excelHead {
-                    if v.Filed == "" {
-                        continue
-                    }
-                    cell = row.AddCell()
-                    style := &xlsx.Style{
-                        Border:    defaultExcelBorder,
-                        Alignment: defaultExcelAlignment,
-                    }
-                    if v.Filed == "index" {
-                        cell.SetValue(i + 1)
-                    } else {
-                        cell.SetValue(m[v.Filed])
-                        if v.Filed == "title" {
-                            style.Font = blueFont
-                        }
-                    }
+		if information != nil && len(information) > 0 {
+			//填充数据
+			for i, info := range information {
+				m := make(map[string]interface{})
+				m = gconv.Map(info)
+				row = sheet.AddRow()
+				row.SetHeight(20)
+				for _, v := range excelHead {
+					if v.Filed == "" {
+						continue
+					}
+					cell = row.AddCell()
+					style := &xlsx.Style{
+						Border:    defaultExcelBorder,
+						Alignment: defaultExcelAlignment,
+					}
+					if v.Filed == "index" {
+						cell.SetValue(i + 1)
+					} else {
+						cell.SetValue(m[v.Filed])
+						if v.Filed == "title" {
+							style.Font = blueFont
+						}
+					}
 
-                    cell.SetStyle(style)
-                }
-            }
-        }
-    }
-    return file, nil
+					cell.SetStyle(style)
+				}
+			}
+		}
+	}
+	return file, nil
 }

+ 271 - 0
src/jfw/modules/subscribepay/src/util/pdfSendEmail.go

@@ -0,0 +1,271 @@
+package util
+
+import (
+	qutil "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"encoding/json"
+	"fmt"
+	. "jy/src/jfw/modules/subscribepay/src/config"
+	"log"
+	"strings"
+	"time"
+)
+
+type MarketAnalysisEntity struct {
+	FormatParam AnalysisRequestFormat
+}
+
+// AnalysisRequestFormat 格式化后参数
+type AnalysisRequestFormat struct {
+	KeysItems    []keyWordGroup
+	Area, City   []string //省份城市
+	STime, ETime int64    //开始结束时间
+	Industry     []string //行业
+	BuyerClass   []string //采购单位类型
+	Buyer        string   //采购单位
+	Winner       string   //中标单位
+	Sort         int      //排序:默认0:成交时间倒序;1:项目金额倒序
+	PageSize     int      //默认每页10条
+	PageNum      int      //默认当前第一页
+}
+
+// keyWordGroup 订阅词结构体
+type keyWordGroup struct {
+	A_Key      []viewKeyWord `json:"a_key"`
+	ItemName   string        `json:"s_item"`
+	UpdateTime int64         `json:"updatetime"`
+}
+
+type viewKeyWord struct {
+	Keyword  []string `json:"key"`       //关键词
+	Appended []string `json:"appendkey"` //附加词
+	Exclude  []string `json:"notkey"`    //排除词
+	MatchWay int      `json:"matchway"`  //匹配模式
+}
+
+var (
+	AnalyzePdfEmailContent = `<div style="width:1200px;background-color:#F5F4FA;padding:15px;">
+  <div style="padding:5px 50px 50px 50px;background-color:#fff;width:1000px;margin:auto;border-top: 5px solid #2cb7ca;">
+    <img src="https://www.jianyu360.com/images/swordfish/sf_01.png" style="display:block;width:150px;margin: 10px auto 30px auto;">
+    <div style="padding-bottom: 30px;margin-bottom: 30px;border-bottom: 1px dashed #ddd;">尊敬的剑鱼标讯用户:
+      <div style="font-size:14px;text-indent: 32px;margin-top: 5px;">您好,感谢您购买剑鱼标讯%s,您的报告已发送到您的邮箱,请查收!如有问题,可拨打客服热线:400-108-6670。</div>
+    </div>
+    <a href="%s" download="%s" style="margin: 0 auto;display: block;width: 150px;height: 30px;line-height: 30px;background: #2cb7ca;text-decoration: none;text-align: center;color: #fff;border-radius: 5px;margin-bottom: 25px;">%s下载</a>
+    <div style="box-sizing: border-box; border-width: 2px 1px 1px; border-style: solid; border-color: rgb(204, 204, 204); margin-bottom: 20px; font-family: 'Microsoft YaHei'; orphans: 2; widows: 2;">
+      <div style="height: 35px; line-height: 35px; background: rgb(245, 245, 251); font-size: 14px; color: rgb(29, 29, 29); padding-left: 30px;">报告详情</div>
+      <div style="padding: 18px 0px; overflow: hidden;">
+        <div style="box-sizing: border-box; padding-left: 30px; float: left; width: %s;">
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">分析内容:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">匹配方式:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">成交时间:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">项目地区:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">行业:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">采购单位类型:%s</p>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>`
+	BuyerPdfEmailContent = `<div style="width:1200px;background-color:#F5F4FA;padding:15px;">
+  <div style="padding:5px 50px 50px 50px;background-color:#fff;width:1000px;margin:auto;border-top: 5px solid #2cb7ca;">
+    <img src="https://www.jianyu360.com/images/swordfish/sf_01.png" style="display:block;width:150px;margin: 10px auto 30px auto;">
+    <div style="padding-bottom: 30px;margin-bottom: 30px;border-bottom: 1px dashed #ddd;">尊敬的剑鱼标讯用户:
+      <div style="font-size:14px;text-indent: 32px;margin-top: 5px;">您好,感谢您购买剑鱼标讯%s,您的报告已发送到您的邮箱,请查收!如有问题,可拨打客服热线:400-108-6670。</div>
+    </div>
+    <a href="%s" download="%s" style="margin: 0 auto;display: block;width: 150px;height: 30px;line-height: 30px;background: #2cb7ca;text-decoration: none;text-align: center;color: #fff;border-radius: 5px;margin-bottom: 25px;">%s下载</a>
+    <div style="box-sizing: border-box; border-width: 2px 1px 1px; border-style: solid; border-color: rgb(204, 204, 204); margin-bottom: 20px; font-family: 'Microsoft YaHei'; orphans: 2; widows: 2;">
+      <div style="height: 35px; line-height: 35px; background: rgb(245, 245, 251); font-size: 14px; color: rgb(29, 29, 29); padding-left: 30px;">报告详情</div>
+      <div style="padding: 18px 0px; overflow: hidden;">
+        <div style="box-sizing: border-box; padding-left: 30px; float: left; width: %s;">
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">目标业主:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">成交时间:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">关键词:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">搜索范围:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">项目地区:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">行业:%s</p>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>`
+	EndPdfEmailContent = `<div style="width:1200px;background-color:#F5F4FA;padding:15px;">
+  <div style="padding:5px 50px 50px 50px;background-color:#fff;width:1000px;margin:auto;border-top: 5px solid #2cb7ca;">
+    <img src="https://www.jianyu360.com/images/swordfish/sf_01.png" style="display:block;width:150px;margin: 10px auto 30px auto;">
+    <div style="padding-bottom: 30px;margin-bottom: 30px;border-bottom: 1px dashed #ddd;">尊敬的剑鱼标讯用户:
+      <div style="font-size:14px;text-indent: 32px;margin-top: 5px;">您好,感谢您购买剑鱼标讯%s,您的报告已发送到您的邮箱,请查收!如有问题,可拨打客服热线:400-108-6670。</div>
+    </div>
+    <a href="%s" download="%s" style="margin: 0 auto;display: block;width: 150px;height: 30px;line-height: 30px;background: #2cb7ca;text-decoration: none;text-align: center;color: #fff;border-radius: 5px;margin-bottom: 25px;">%s下载</a>
+    <div style="box-sizing: border-box; border-width: 2px 1px 1px; border-style: solid; border-color: rgb(204, 204, 204); margin-bottom: 20px; font-family: 'Microsoft YaHei'; orphans: 2; widows: 2;">
+      <div style="height: 35px; line-height: 35px; background: rgb(245, 245, 251); font-size: 14px; color: rgb(29, 29, 29); padding-left: 30px;">报告详情</div>
+      <div style="padding: 18px 0px; overflow: hidden;">
+        <div style="box-sizing: border-box; padding-left: 30px; float: left; width: %s;">
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">目标企业:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">成交时间:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">关键词:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">搜索范围:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">项目地区:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">行业:%s</p>
+          <p style="margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);">采购单位类型:%s</p>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>`
+)
+
+// GetPdfDetail 生成pdf文件程序查询接口
+func PdfSendEmail(rData map[string]interface{}) error {
+	sEmail := qutil.InterfaceToStr(rData["s_email"])
+	pdfUrl := qutil.InterfaceToStr(rData["s_pdfUrl"])
+	sType := qutil.InterfaceToStr(rData["type"])
+	if !jy.IsEmail(sEmail) {
+		return fmt.Errorf("邮箱格式不正确")
+	}
+	if pdfUrl == "" {
+		return fmt.Errorf("无效下载地址")
+	}
+	pdfUrl = fmt.Sprintf("%s%s", Config.WebDomain, pdfUrl)
+	var (
+		keyWords                                                                   []string
+		mailContent, packageName, matchingMode, rangeTime, area, industry, entName string
+	)
+	switch sType {
+	case "3":
+		packageName = "市场分析定制报告"
+		//格式化订阅词
+		var (
+			mae MarketAnalysisEntity
+		)
+		if err := json.Unmarshal([]byte(qutil.InterfaceToStr(rData["s_keysItems"])), &mae.FormatParam.KeysItems); err == nil {
+			for _, item := range mae.FormatParam.KeysItems {
+				var keyGroup []string
+				for _, word := range item.A_Key {
+					matchWayStr := "(精准)"
+					if word.MatchWay == 1 {
+						matchWayStr = "(模糊)"
+					}
+					keyGroup = append(keyGroup, word.Keyword...)
+					keyGroup = append(keyGroup, word.Appended...)
+					keyGroup = append(keyGroup, matchWayStr)
+				}
+				keyWords = append(keyWords, strings.Join(keyGroup, " "))
+			}
+		}
+		if keyWords == nil {
+			keyWords = append(keyWords, "-")
+		}
+		matchingMode = qutil.If(qutil.InterfaceToStr(rData["s_matchingMode"]) == "title", "【按标题匹配】", "【按全文匹配】").(string)
+		sRangeTime := strings.Split(qutil.InterfaceToStr(rData["s_rangeTime"]), "-")
+		var (
+			sTime, eTime string
+		)
+		if sRangeTime[0] != "" && sRangeTime[0] != "0" {
+			sTime = time.Unix(qutil.Int64All(sRangeTime[0]), 0).Format("2006-01-02")
+		}
+		if sRangeTime[1] != "" && sRangeTime[1] != "0" {
+			eTime = time.Unix(qutil.Int64All(sRangeTime[1]), 0).Format("2006-01-02")
+		}
+		rangeTime = fmt.Sprintf("%s至%s", sTime, eTime)
+		if areaStr := strings.TrimSpace(qutil.InterfaceToStr(rData["s_area"])); areaStr != "" {
+			imap := map[string][]string{}
+			if err := json.Unmarshal([]byte(qutil.InterfaceToStr(rData["s_area"])), &imap); err == nil {
+				var areas []string
+				for name, v := range imap {
+					if len(v) == 0 {
+						areas = append(areas, name)
+					} else {
+						areas = append(areas, fmt.Sprintf("%s:%s", name, strings.Join(v, ",")))
+					}
+				}
+				area = strings.Join(areas, ",")
+			}
+		}
+		if area == "" {
+			area = "全国"
+		}
+		sIndustry, _ := rData["s_industry"].(string)
+		industryMap := qutil.ObjToMap(sIndustry)
+
+		if industryMap == nil {
+			industry = "全行业"
+		} else {
+			var industryArr []string
+			for key := range *industryMap {
+				//is, _ := i.([]interface{})
+				industryArr = append(industryArr, key)
+			}
+			industry = strings.Join(industryArr, ",")
+		}
+		if industry == "" {
+			industry = "全行业"
+		}
+		sBuyerClass, _ := rData["s_buyerClass"].(string)
+		if sBuyerClass == "" {
+			sBuyerClass = "全部"
+		}
+		mailContent = fmt.Sprintf(AnalyzePdfEmailContent, packageName, pdfUrl,
+			fmt.Sprintf("剑鱼标讯-%s-%s.pdf", packageName, time.Unix(qutil.Int64All(rData["l_createTime"]), 0).Format("20060102")),
+			packageName, `97%`, strings.Join(keyWords, ","), matchingMode, rangeTime, area, industry, sBuyerClass)
+	case "2", "1":
+		entName = qutil.InterfaceToStr(rData["entName"])
+		packageName = "业主采购分析报告"
+		match, _ := rData["match"].(string)
+		matching := "(模糊)"
+		if qutil.InterfaceToStr(rData["exactMatch"]) == "1" {
+			matching = "(精准)"
+		}
+		if match != "" {
+			keyWords = append(keyWords, fmt.Sprintf("%s %s", match, matching))
+		} else {
+			keyWords = append(keyWords, "-")
+		}
+
+		matchRange, _ := rData["matchRange"].(string)
+		var matchingModes []string
+		if strings.Contains(matchRange, "purchasing") {
+			matchingModes = append(matchingModes, "项目名称/标的物")
+		}
+		if strings.Contains(matchRange, "agency") {
+			matchingModes = append(matchingModes, "招标代理机构")
+		}
+		if strings.Contains(matchRange, "winner") {
+			matchingModes = append(matchingModes, "中标企业")
+		}
+		if strings.Contains(matchRange, "buyer") {
+			matchingModes = append(matchingModes, "采购单位")
+		}
+		matchingMode = strings.Join(matchingModes, ",")
+		if matchingMode == "" {
+			matchingMode = "-"
+		}
+		timeRange, _ := rData["timeRange"].(string)
+		rangeTime = strings.ReplaceAll(timeRange, "_", "至")
+		area, _ = rData["area"].(string)
+		if area == "" {
+			area = "全国"
+		}
+		industry, _ = rData["scopeClass"].(string)
+		if industry == "" {
+			industry = "全行业"
+		}
+
+		if sType == "1" { //中标企业分析有采购单位类型筛选
+			packageName = "企业中标分析报告"
+			sBuyerClass, _ := rData["s_buyerClass"].(string)
+			if sBuyerClass == "" {
+				sBuyerClass = "全部"
+			}
+			mailContent = fmt.Sprintf(EndPdfEmailContent, packageName, pdfUrl,
+				fmt.Sprintf("剑鱼标讯-%s-%s.pdf", packageName, time.Unix(qutil.Int64All(rData["l_createTime"]), 0).Format("20060102")),
+				packageName, `97%`, entName, rangeTime, strings.Join(keyWords, ","), matchingMode, area, industry, sBuyerClass)
+		} else {
+			mailContent = fmt.Sprintf(BuyerPdfEmailContent, packageName, pdfUrl,
+				fmt.Sprintf("剑鱼标讯-%s-%s.pdf", packageName, time.Unix(qutil.Int64All(rData["l_createTime"]), 0).Format("20060102")),
+				packageName, `97%`, entName, rangeTime, strings.Join(keyWords, ","), matchingMode, area, industry)
+		}
+	}
+	if SendRetryMail(3, sEmail, qutil.If(entName != "", fmt.Sprintf("%s(%s)", packageName, entName), packageName).(string), mailContent, "", nil, GmailAuth) {
+		log.Printf("PdfSendEmail SendMailToPayUser %s 邮件%s发送成功!", packageName, sEmail)
+	}
+	return nil
+}

+ 5 - 2
src/web/staticres/big-member/js/unit_portrayal.js

@@ -5,7 +5,8 @@ var vNode = {
       hisproComponent: hisproComponent,
       buyerExample: buyerExample,
       forwardshare: vmForward,
-      mobilePortrayalFooter:mobilePortrayalFooter
+      mobilePortrayalFooter:mobilePortrayalFooter,
+      downloadpopup: downloadpopup,
     },
     data() {
         // 修改柱状条颜色为渐变色
@@ -175,7 +176,9 @@ var vNode = {
             unitParams: {},
             follow:false, // 是否监控,
             allpower:{},
-          pageScrollTop: 0
+          pageScrollTop: 0,
+                // 下载弹窗需要用的参数
+        balance:0, //定制下载余额
         }
     },
     computed: {

+ 1 - 1
src/web/staticres/big-member/weixin/css/ent_portrait.css

@@ -592,7 +592,7 @@
   bottom: 0;
   width: 0.8rem;
   border-bottom: 1.5px solid #2ABED1;
-  z-index: 99999999;
+  z-index: 99;
 }
 
 .top-switch div:not(active) {

+ 4 - 2
src/web/staticres/common-module/big-member/js/client_portrayal.js

@@ -7,7 +7,8 @@ var vNode = {
     hisproComponent: hisproComponent,
     buyerExample: buyerExample,
     forwardshare: vmForward,
-    mobilePortrayalFooter:mobilePortrayalFooter
+    mobilePortrayalFooter:mobilePortrayalFooter,
+    downloadpopup: downloadpopup,
   },
   data() {
       // 修改柱状条颜色为渐变色
@@ -180,7 +181,8 @@ var vNode = {
           // 招标动态筛选条件缓存,用来判断是否正在使用筛选项进行请求
           buyerHighSet: '',
           clientParams: {},
-          pageScrollTop: 0
+          pageScrollTop: 0,
+          balance:0, //定制下载余额
       }
   },
   computed: {

+ 13 - 0
src/web/staticres/common-module/chart-module/js/chart-common.js

@@ -55,6 +55,18 @@
 // `
 var chartTemplate = "\n  <template>\n      <ve-histogram\n        v-if='type===\"ve-histogram\"'\n        :id=\"type\"\n        :colors=\"histogramChart.options.colors\"\n        :width=\"histogramChart.options.width\"\n        :height=\"histogramChart.options.height\"\n        :data=\"chartData\"\n        :settings=\"histogramChart.options.settings\"\n        :after-config=\"histogramChart.options.config\"\n        :after-set-option=\"extend\"\n        :extend=\"histogramChart.defaultOptions\"\n        >\n      </ve-histogram>\n      <ve-histogram\n        v-else-if='type===\"ve-finehistogram\"'\n        :id=\"type\"\n        :height=\"barLineChart.options.height\"\n        :width=\"barLineChart.options.width ? barLineChart.options.width : null\"\n        :colors=\"barLineChart.options.colors\"\n        :data=\"chartData\"\n        :settings=\"barLineChart.options.settings\"\n        :after-config=\"barLineChart.options.config\"\n        :after-set-option=\"barExtend\"\n        :extend=\"barLineChart.defaultOptions\"\n        >\n      </ve-histogram>\n      <div v-else-if='type===\"ve-treemap\"' class=\"rect-tree-map-chart\" style=\"height: 100%\"></div>\n      <ve-line\n        v-else-if='type===\"ve-line\"'\n        :data=\"chartData\"\n        :height=\"lineChart.options.height\"\n        :after-config=\"lineChart.options.config\"\n        :extend=\"lineChart.defaultOption\"\n        >\n      </ve-line>\n  </template>\n";
 var vComponentChart = function (el, chartData, config, type) {
+
+  try {
+    if (!Vue.prototype._watchers) {
+      Vue.prototype._watchers = []
+    }
+    if (!Vue._watchers) {
+      Vue._watchers = Vue.prototype._watchers
+    }
+  } catch (e) {
+    console.log(e)
+  }
+
   new Vue({
     delimiters: ['${', '}'],
     el: el,
@@ -76,6 +88,7 @@ var vComponentChart = function (el, chartData, config, type) {
     },
     created () {
       this.chartData = chartData
+      this.getChartConfig()
     },
     mounted () {
       this.getChartConfig()

+ 6 - 3
src/web/staticres/common-module/collection/js/ent_portrait.js

@@ -4,7 +4,9 @@ var vNode = {
   components: {
     vipComponent: vipComponent,
     hisproComponent: hisproComponent,
-    forwardshare: vmForward
+    forwardshare: vmForward,
+    mobilePortrayalFooter:mobilePortrayalFooter,
+    downloadpopup: downloadpopup,
   },
   data () {
     // 修改柱状条颜色为渐变色
@@ -188,7 +190,8 @@ var vNode = {
       // 用户是否登录
       isLogin: true,
       // 是否是免费用户
-      isFree: false
+      isFree: false,
+      balance:0
     }
   },
   created: function () {
@@ -565,7 +568,7 @@ var vNode = {
       var _this = this
       var urls = ''
       // 判断专家版、智慧版; 商机版和自定义版时判断是不是超级订阅
-      if (_this.powerInfo.memberStatus > 0 && _this.powerInfo.power.indexOf(13) > -1) {
+      if (_this.powerInfo.memberStatus > 0 && (_this.powerInfo.power.indexOf(13) > -1 || _this.powerInfo.power.indexOf(4) > -1)) {
         urls = '/bigmember/portrait/winner/getNewMsg'
       }
       // else if (_this.powerInfo.memberStatus > 2) {

+ 19 - 0
src/web/staticres/common-module/common/css/appDownloadfile.css

@@ -0,0 +1,19 @@
+
+.attachment-content {
+    padding: 0.2rem 0.4rem 0.4rem;
+  }
+  .attachment-tip-text {
+    margin-bottom: 0.2rem;
+    font-size: 0.24rem;
+    line-height: 0.36rem;
+    color: #9b9ca3;
+    text-align: center;
+  }
+  .attachment-email-input {
+    border: 0.02rem solid rgb(0 0 0 / 10%);
+    border-radius: 0.16rem;
+  }
+  .appdownload-dialog .van-dialog__confirm{
+    color: #2ABED1;
+
+  }

+ 214 - 0
src/web/staticres/common-module/common/js/appDownloadfile.js

@@ -0,0 +1,214 @@
+var appdownloadfileTemplate = `
+    <van-dialog
+    class="appdownload-dialog"
+      v-model="attachment.emailSendDialog"
+      title="发送邮箱地址"
+      show-cancel-button
+      get-container="body"
+      :before-close="beforeEmailDialogClose"
+    >
+      <div class="attachment-content">
+        <div class="attachment-tip-text">报告将以邮件的形式发送至您的邮箱</div>
+        <van-field
+          class="attachment-email-input"
+          v-model="attachment.email"
+          placeholder="输入邮箱地址"
+        />
+      </div>
+    </van-dialog>
+`
+var appdownloadfile = {
+  name: 'appDownloadfile',
+  template: appdownloadfileTemplate,
+  props: {
+
+  },
+  data: function () {
+    return {
+      attachment: {
+        fileUrl: '', // 附件真实url
+        file: {}, // 当前需要下载的附件信息
+        email: '',
+        downloaded: false,
+        emailSendDialog: false,
+      },
+      id:'' ,
+      type:'',
+      userInfo:'',
+      timer: true
+    }
+  },
+  computed: {},
+  created() { },
+  methods: {
+    downloadFile(fileUrl){
+      this.getEmail()
+      this.attachment.fileUrl = fileUrl        
+      this.attachment.emailSendDialog = true
+    },
+    async beforeEmailDialogClose(action, done) {
+      if (action === 'cancel') {
+        return done()
+      }
+      const { email } = this.attachment
+      const emailRegExp = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/
+      if (!emailRegExp.test(email)) {
+        done(false)
+        return this.$toast('邮箱地址格式错误')
+      } else {
+        const { file , fileUrl} = this.attachment
+        // const { fileUrl } = await this.getAttachmentInfo(file)
+        if (fileUrl) {
+          // this.attachment.fileUrl = fileUrl
+        } else {
+          return this.$toast('获取附件失败')
+        }
+        await this.sendEmailConfirm(done)
+      }
+    },
+    async sendEmailConfirm(done) {
+      let that = this
+      const { email, fileUrl } = this.attachment
+      const params = {
+        downurl: fileUrl,
+        email
+      }
+      $.ajax({
+        type:'POST',
+        url:'/bigmember/attachment/email',
+        data:params,
+        success:function(res){
+          if (res.code === 0 && res.data.status) {
+            done && done()
+            that.$toast(`已发送至 ${email}`)
+          } else {
+            done && done(false)
+            that.$toast('发送失败')
+          }
+         
+        }
+    })
+    },
+    getEmail() {
+      let that = this
+      $.ajax({
+        type:'POST',
+        url:'/jypay/user/getAccountInfo',
+        success:function(res){
+          that.userInfo = res.data
+          if (that.userInfo && that.userInfo.email) {
+            that.attachment.email = that.userInfo.email
+          }
+        }
+    })
+    },
+ // 以下流程暂时弃用
+    // async downloadFile(file,id,type) {
+    //   this.attachment.file = file
+    //   this.id = id || ''
+    //   this.type = type || ''
+    //   const { platform, platformOS, appVersion } = utils.$env
+
+    //   // IOS APP端特殊流程处理,先提示填写邮箱后扣次数
+    //   // IOS APP端 老客户端仍走 填写邮箱逻辑,新客户端增加下载附件方法,调用下载附件
+    //   if (platform === 'app' && platformOS === 'ios') {
+    //     const newIOSApp = appVersion && compareVersion(appVersion, '3.0.4') > 0
+    //     if (newIOSApp) {
+    //       // 新APP客户端,调用下载附件的方法
+    //       const { downUrl, fileName, size } = await this.getAttachmentInfo(file)
+    //       // 获取前缀
+    //       const name = fileName
+    //         ? fileName.substring(0, fileName.lastIndexOf('.'))
+    //         : ''
+    //       // 获取后缀
+    //       const types = fileName
+    //         ? fileName.substring(fileName.lastIndexOf('.') + 1)
+    //         : ''
+    //       calldownLoadFile(name, types, downUrl, size)
+    //     } else {
+    //       // 老APP客户端,调用邮箱相关逻辑
+    //       this.getEmail()
+    //       this.attachment.emailSendDialog = true
+    //     }
+    //   } else {
+    //     // downUrl: 原始url
+    //     // fileUrl: 下载地址
+    //     const { downUrl, fileUrl } = await this.getAttachmentInfo(file)
+    //     if (downUrl && fileUrl) {
+    //       if (platform === 'wx') {
+    //         // 跳转中转页
+    //         location.href = `${window.location.origin}/jy_mobile/static/open_in_browser?type=report&target=${encodeURIComponent(fileUrl)}`
+    //       } else {
+    //         location.href = fileUrl
+    //       }
+    //     } else {
+    //       console.log('获取失败')
+    //     }
+    //   }
+    // },
+    async getAttachmentInfo(file) {
+      let that = this
+      const platform = utils.$env.platform.toUpperCase()
+      const params = {
+        id: this.id, // 附件详情页id
+        fileName: file.filename, // 附件名称
+        infoType:  this.type, // 信息类型:默认为空; 供应信息:S
+        productName: '报告下载包',
+        platform, // 平台:PC;APP;WX
+        title: document.title || '' // 附件详情页标题附件详情页标题
+      }
+      if(that.timer){
+        that.timer = false
+        $.ajax({
+          type: 'post',
+          url: '/jypay/resourcePack/consumePack',
+          data: params,
+          success: function (res) {
+            that.timer = true
+            const data = res.r
+            const msg = res.m
+            if (data) {
+              const downUrl = data.downUrl
+              const fileUrl = downUrl
+                ? `${downUrl}?response-content-type=application/octet-stream`
+                : ''
+              return {
+                ...data,
+                fileUrl // 真实下载地址
+              }
+            } else {
+              that.$toast(msg)
+            }
+  
+          }})
+      }
+    },
+
+     calldownLoadFile(filename, filetype, fileurl, filesize) {
+      const inApp = utils.$envs.inApp
+      if (inApp) {
+        appDownLoadFile(filename, filetype, fileurl, filesize)
+      } else {
+        downLoadFileH5(filename, fileurl)
+      }
+    },
+    appDownLoadFile(filename, filetype, fileurl, filesize) {
+      try {
+        JyObj.downLoadFile(filename, filetype, fileurl, filesize)
+      } catch (e) {
+        console.warn('error: app ios download file failed')
+      }
+    },
+     downLoadFileH5(name, url) {
+      const a = document.createElement('a')
+      const filename = name
+      a.href = url
+      a.target = '_blank'
+      if (filename) {
+        a.download = filename
+      }
+      a.click()
+    }
+
+  }
+}

+ 14 - 0
src/web/staticres/common-module/diy-report/css/report-list.css

@@ -123,4 +123,18 @@
 .j-button-group button{
   border-radius: 0.12rem;
   height: .72rem;
+}
+.j-button-down{
+  background-color: #fff;
+  color: #2ABED1;
+  border: 0.02rem solid #2ABED1;
+  display: flex;
+    align-items: center;
+    justify-content: center;
+    flex: 1;
+    width: 100%;
+    font-size: 0.32rem;
+    line-height: inherit;
+    text-align: center;
+    margin-left: 0.26rem;
 }

+ 5 - 1
src/web/staticres/common-module/diy-report/js/report-list.js

@@ -49,7 +49,7 @@ var reportListTemplate = `
                         </div>
                     </div>
                     <div class="info-flex-r-box filters">
-                        <span class="info-content-label">时间:</span>
+                        <span class="info-content-label">成交时间:</span>
                         <div class="info-content-box" :class="{'van-ellipsis': !item.open}">
                             @@item.rangeTimeStart|formatTime('yyyy.MM.dd')@@-@@item.rangeTimeEnd|formatTime('yyyy.MM.dd')@@
                         </div>
@@ -76,6 +76,7 @@ var reportListTemplate = `
                 <div class="j-button-group" v-if="item.state === 1 || item.state === null">
                   <button class="j-button-cancel" @click="goDelete(item.id)">删除</button>
                   <button class="j-button-confirm" @click="goReport(item.id)">查看</button>
+                  <button class="j-button-down" v-if="item.isDownload" @click="goDown(item)">下载</button>
                 </div>
                 <div class="j-button-group" v-else>
                   <button class="j-button-confirm" @click="goDelete(item.id)">删除</button>
@@ -162,6 +163,9 @@ var reportListMobileComponent = {
         this.getList()
     },
     methods: {
+        goDown: function (item) {
+            this.$emit('go-down', item)
+        },
         goReport: function (id) {
             this.$emit('go-report', id)
         },

+ 7 - 0
src/web/staticres/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css

@@ -119,6 +119,13 @@ color: #9B9CA3;
   background-image: url('../images/fx.png');
   margin: auto;
 }
+.m-footer-box .footer-item .footer-xz{
+  width: 0.48rem;
+  height: 0.48rem;
+  background-size: 100% 100%;
+  background-image: url('../images/xz.png');
+  margin: auto;
+}
 .m-footer-box .footer-item .footer-jk{
   width: 0.48rem;
   height: 0.48rem;

+ 40 - 31
src/web/staticres/common-module/mobile-portrayal-footer/js/mobile-portrayal-footer.js

@@ -21,10 +21,10 @@ var mobileportrayalfootertemp = `
         </div>
         <p class="footer-text">分享</p>
       </div>
-      <div class="footer-item" v-if="downshow">
+      <div class="footer-item" @click="downLoad" v-if="downshow">
         <div class="footer-xz">
         </div>
-        <p class="footer-text">下载</p>
+        <p class="footer-text">下载报告</p>
       </div>
       <div class="monitor-box" v-show="monitorboxShow">
         <div class="monitor-box-item">
@@ -47,49 +47,49 @@ var mobilePortrayalFooter = {
   name: 'mobilePortrayalFooter',
   template: mobileportrayalfootertemp,
   props: {
-    params: {
+    params: { // 转给同事需要参数
       type: Object,
       default: function (){
         return {}
       }
     },
-    islogin:{
+    islogin:{ // 是否登录
       type: Boolean,
       default: false
     },
-    downshow:{
+    downshow:{ // 下载按钮是否展示
       type: Boolean,
       default: false
     },
-    monitor:{
+    monitor:{ // 监控状态
       type: Boolean,
       default: false
     },
-    claim:{
+    claim:{ // 认领状态
       type: Boolean,
       default: false
     },
-    monitorshow:{
+    monitorshow:{ // 监控按钮是否展示
       type: Boolean,
       default: false
     },
-    customMonitor:{
+    customMonitor:{ // 是否自定义监控点击
       type: Boolean,
       default: false
     },
-    claimshow:{
+    claimshow:{ // 认领按钮是否展示
       type: Boolean,
       default: false
     },
-    shareshow:{
+    shareshow:{ // 转给同事按钮
       type: Boolean,
       default: false
     },
-    showMiniAppShare: {
+    showMiniAppShare: { // 小程序分享按钮
       type: Boolean,
       default: false
     },
-    allpower:{
+    allpower:{ // 权限状态
 
     }
 
@@ -121,11 +121,17 @@ var mobilePortrayalFooter = {
       if (u) {
         u.style.paddingBottom = "1.06rem";
       }
+      let en = document.getElementById("ent-portrait")
+      if (en) {
+        en.style.paddingBottom = "1.06rem";
+      }
     }
   }
  },
   methods: {
-
+    downLoad(){
+      this.$parent.$refs.downloadpopup.show() //触发引用此组件父级组件的下载弹框
+    },
     monitorClick: utils.debounce(function(){
       let this_ = this
       let params = {
@@ -141,11 +147,11 @@ var mobilePortrayalFooter = {
             contentType: 'application/json',
             data: JSON.stringify(params),
             success: function(res) {
-              this_.yes_monitor(res.data)
+              this_.yes_monitor(res.data) // 弹出取消监控弹窗
             }
           })
         }
-      } else{
+      } else{ //未监控 去监控
         this.$emit('monitorclick')
       }
     },300),
@@ -163,7 +169,7 @@ var mobilePortrayalFooter = {
         cancelButtonText: '我再想想',
         cancelButtonColor: '#2ABED1'
       }).then(() =>{
-        this.$emit('monitorclick')
+        this.$emit('monitorclick',true)
         this.monitorboxShow = false
       })
     },
@@ -176,6 +182,7 @@ var mobilePortrayalFooter = {
       }catch(e){
       }
     },
+    //  采购单位监控点击相关
     lookList (){
       // 跳转至监控列表页
       if(utils.$envs.inWX){
@@ -218,20 +225,6 @@ var mobilePortrayalFooter = {
         })
       }
     },
-    onCallback (data) {
-      if (data.type === 'close') {
-        this.showIframe = false
-      }
-    },
-    setShareEvent () {
-      console.info('xxx')
-      let params = this.params
-      sessionStorage.setItem('share-query--login-clear', JSON.stringify(params))
-      this.showIframe = false
-      this.$nextTick(() => {
-        this.showIframe = true
-      })
-    },
     yes_monitor (data, isInit){
       this.surplus = data.count.surplus
       this.use = data.count.use
@@ -325,6 +318,22 @@ var mobilePortrayalFooter = {
         window.location.href = href_
       }
 
+    },
+       //  采购单位监控点击相关结束
+   // 转给同事相关
+  onCallback (data) {
+    if (data.type === 'close') {
+      this.showIframe = false
     }
+  },
+  setShareEvent () {
+    console.info('xxx')
+    let params = this.params
+    sessionStorage.setItem('share-query--login-clear', JSON.stringify(params))
+    this.showIframe = false
+    this.$nextTick(() => {
+      this.showIframe = true
+    })
+  },
   }
 }

BIN
src/web/staticres/common-module/order-list/image/enterpriseAnalysis.png


BIN
src/web/staticres/common-module/order-list/image/marketAnalysis.png


BIN
src/web/staticres/common-module/order-list/image/ownerAnalysis.png


+ 33 - 0
src/web/staticres/common-module/order-list/js/order-detail.js

@@ -538,6 +538,13 @@ var vm = new Vue({
           infoList = this.getDocMemberInfo(order)
           break
         }
+        case '市场分析定制报告下载包': 
+        case '企业中标分析报告下载包':
+        case '业主采购分析报告下载包':
+        {
+          infoList = this.getAnalysisInfo(order)
+          break
+        }
         default: {
           break
         }
@@ -565,6 +572,32 @@ var vm = new Vue({
 
       return [numInfo, date]
     },
+    //市场分析定制报告下载包 企业中标分析报告下载包 业主采购分析报告下载包
+    getAnalysisInfo: function (order) {
+      var filterInfo = JSON.parse(order.filter)
+      var payNum = filterInfo.pNum + '份'
+
+      var numInfo = {
+        label: '报告下载份数',
+        split: ':',
+        text: payNum
+      }
+      var time = {
+        label: '使用有效期',
+        split: ':',
+        text: filterInfo.validYear? filterInfo.validYear + '年' : '3年'
+      }
+      var date = {
+        label: '有效期至',
+        split: ':',
+        text: filterInfo.endTime
+      }
+      let itemlist =  [numInfo,time]
+      if(order.order_status === 1 && filterInfo.endTime){ // 已完成订单才展示有效期
+        itemlist.push(date)
+      }
+      return itemlist
+    },
     getBuyerPortraitPackInfo: function (order) {
       var filterInfo = JSON.parse(order.filter)
       var payNum = filterInfo.num + '个'

+ 77 - 4
src/web/staticres/common-module/order-list/js/order-list-config.js

@@ -11,7 +11,10 @@ var assetsConf = {
     '采购单位画像包': 'buyerPortraitPackLink',
     '数据文件': 'dataFileLink',
     '医械通': 'medicalLink',
-    '剑鱼文库会员': 'docMemberLink'
+    '剑鱼文库会员': 'docMemberLink',
+    '市场分析定制报告下载包':'marketAnalysisLink',
+    '企业中标分析报告下载包':'enterpriseAnalysisLink',
+    '业主采购分析报告下载包':'ownerAnalysisLink'
   },
   // 产品集合
   productionTypeList: [
@@ -33,7 +36,10 @@ var assetsConf = {
     '省份订阅包',
     '采购单位画像包',
     '数据文件',
-    '剑鱼文库会员'
+    '剑鱼文库会员',
+    '市场分析定制报告下载包',
+    '企业中标分析报告下载包',
+    '业主采购分析报告下载包'
   ],
   // 支持再次购买的产品集合
   canBuyAgainProductions: [
@@ -60,7 +66,10 @@ var assetsConf = {
     '附件下载包',
     '省份订阅包',
     '采购单位画像包',
-    '剑鱼文库会员'
+    '剑鱼文库会员',
+    '市场分析定制报告下载包',
+    '企业中标分析报告下载包',
+    '业主采购分析报告下载包'
   ],
   init: function () {
     // this.getPlatform()
@@ -493,7 +502,71 @@ var assetsConf = {
         app: '/common-module/order-list/image/docVip.png'
       }
     }
-  }
+  },
+    // 市场分析定制报告下载包
+    marketAnalysisLink: {
+      pay: {
+        wx: '/weixin/pay/checkout_marketAnalysis',
+        app: '/jyapp/pay/checkout_marketAnalysis'
+      },
+      buyAgain: {
+        wx: '/jy_mobile/order/create/marketanalysis',
+        app: '/jy_mobile/order/create/marketanalysis'
+      },
+      orderDetail: {
+        wx: '/weixin/common/marketAnalysis/orderDetail',
+        app: '/jyapp/common/marketAnalysis/orderDetail'
+      },
+      imgMap: {
+        headerImg: {
+          wx: '/common-module/order-list/image/marketAnalysis.png',
+          app: '/common-module/order-list/image/marketAnalysis.png'
+        }
+      }
+    },
+        // 企业中标分析报告下载包
+        enterpriseAnalysisLink: {
+          pay: {
+            wx: '/weixin/pay/checkout_enterpriseAnalysis',
+            app: '/jyapp/pay/checkout_enterpriseAnalysis'
+          },
+          buyAgain: {
+            wx: '/jy_mobile/order/create/enterpriseanalysis',
+            app: '/jy_mobile/order/create/enterpriseanalysis'
+          },
+          orderDetail: {
+            wx: '/weixin/common/enterpriseAnalysis/orderDetail',
+            app: '/jyapp/common/enterpriseAnalysis/orderDetail'
+          },
+          imgMap: {
+            headerImg: {
+              wx: '/common-module/order-list/image/enterpriseAnalysis.png',
+              app: '/common-module/order-list/image/enterpriseAnalysis.png'
+            }
+          }
+        },
+            // 业主采购分析报告下载包
+    ownerAnalysisLink: {
+      pay: {
+        wx: '/weixin/pay/checkout_ownerAnalysis',
+        app: '/jyapp/pay/checkout_ownerAnalysis'
+      },
+      buyAgain: {
+        wx: '/jy_mobile/order/create/owneranalysis',
+        app: '/jy_mobile/order/create/owneranalysis'
+      },
+      orderDetail: {
+        wx: '/weixin/common/ownerAnalysis/orderDetail',
+        app: '/jyapp/common/ownerAnalysis/orderDetail'
+      },
+      imgMap: {
+        headerImg: {
+          wx: '/common-module/order-list/image/ownerAnalysis.png',
+          app: '/common-module/order-list/image/ownerAnalysis.png'
+        }
+      }
+    }
 }
 
+
 assetsConf.init()

+ 98 - 0
src/web/staticres/common-module/order-list/js/order-list.js

@@ -800,6 +800,36 @@ var vm = new Vue({
           }
           break
         }
+        case '市场分析定制报告下载包': {
+          try {
+            info.contentImgUrl = assetsConf.marketAnalysisLink.imgMap.headerImg[platform]
+            info.contentList = this.getAnalysisInfo(order)
+          } catch (error) {
+            info.contentList = []
+            console.log(error)
+          }
+          break
+        }
+        case '企业中标分析报告下载包': {
+          try {
+            info.contentImgUrl = assetsConf.enterpriseAnalysisLink.imgMap.headerImg[platform]
+            info.contentList = this.getAnalysisInfo(order)
+          } catch (error) {
+            info.contentList = []
+            console.log(error)
+          }
+          break
+        }
+        case '业主采购分析报告下载包': {
+          try {
+            info.contentImgUrl = assetsConf.ownerAnalysisLink.imgMap.headerImg[platform]
+            info.contentList = this.getAnalysisInfo(order)
+          } catch (error) {
+            info.contentList = []
+            console.log(error)
+          }
+          break
+        }
         default: {
           console.log('没有找到商品类型: ' + productType)
           break
@@ -1283,6 +1313,27 @@ var vm = new Vue({
           }
           break
         }
+        case '市场分析定制报告下载包': {
+          var href = assetsConf.marketAnalysisLink.pay[platform]
+          if (href) {
+            this.goToLink(`${href}?orderCode=${orderCode}`)
+          }
+          break
+        }
+        case '企业中标分析报告下载包': {
+          var href = assetsConf.enterpriseAnalysisLink.pay[platform]
+          if (href) {
+            this.goToLink(`${href}?orderCode=${orderCode}`)
+          }
+          break
+        }
+        case '业主采购分析报告下载包': {
+          var href = assetsConf.ownerAnalysisLink.pay[platform]
+          if (href) {
+            this.goToLink(`${href}?orderCode=${orderCode}`)
+          }
+          break
+        }
         default: {
           break
         }
@@ -1585,6 +1636,27 @@ var vm = new Vue({
           }
           break
         }
+        case '市场分析定制报告下载包': {
+          var href = assetsConf.marketAnalysisLink.orderDetail[platform]
+          if (href) {
+            goToFn(`${href}?order_code=${orderCode}`)
+          }
+          break
+        }
+        case '企业中标分析报告下载包': {
+          var href = assetsConf.enterpriseAnalysisLink.orderDetail[platform]
+          if (href) {
+            goToFn(`${href}?order_code=${orderCode}`)
+          }
+          break
+        }
+        case '业主采购分析报告下载包': {
+          var href = assetsConf.ownerAnalysisLink.orderDetail[platform]
+          if (href) {
+            goToFn(`${href}?order_code=${orderCode}`)
+          }
+          break
+        }
         default: {
           break
         }
@@ -2785,6 +2857,32 @@ var vm = new Vue({
 
       return [numInfo, date]
     },
+    // 市场 企业 采购  分析下载包卡片信息整理
+    getAnalysisInfo: function(order){
+      var filterInfo = JSON.parse(order.filter)
+      var payNum = filterInfo.pNum + '份'
+      var numInfo = {
+        label: '报告下载份数',
+        split: ':',
+        text: payNum
+      }
+      var time = {
+        label: '使用有效期',
+        split: ':',
+        text: filterInfo.validYear? filterInfo.validYear + '年' : '3年'
+      }
+      var date = {
+        label: '有效期至',
+        split: ':',
+        text: filterInfo.endTime
+      }
+      let itemlist = [numInfo,time]
+      if(order.order_status === 1 && filterInfo.endTime){ // 已完成订单才展示有效期
+        itemlist.push(date)
+      }
+      return itemlist
+
+    },
     // 采购单位画像包订单列表内容
     getBuyerPortraitPackInfo: function (order) {
       var filterInfo = JSON.parse(order.filter)

BIN
src/web/staticres/common-module/pdf/【剑鱼标讯】业主采购分析报告样例.pdf


BIN
src/web/staticres/common-module/pdf/【剑鱼标讯】企业中标分析报告样例.pdf


BIN
src/web/staticres/common-module/pdf/【剑鱼标讯】市场分析定制报告样例.pdf


+ 1 - 0
src/web/staticres/common-module/perfect-info/index.css

@@ -13,6 +13,7 @@
 .tips_tel{
   color: #2ABED1;
   text-decoration: underline;
+  
 }
 .perfect-info-group .top-tip-group {
   font-family: PingFang SC;

+ 48 - 4
src/web/staticres/common-module/perfect-info/js/perfect-info.js

@@ -166,7 +166,16 @@ var titleMap = {
   // 文库
   h5_library_details_free: '申请免费下载文档',
   app_library_details_free: '申请免费下载文档',
-  wx_library_details_free: '申请免费下载文档'
+  wx_library_details_free: '申请免费下载文档',
+  // 市场分析定制报告
+  app_dzbg_fullreport:'体验市场分析定制报告',
+  h5_dzbg_fullreport:'体验市场分析定制报告',
+  wx_dzbg_fullreport:'体验市场分析定制报告',
+  // 报告下载下单页引流留资
+  app_dzbgxzb_customizedquantity:'市场分析定制报告下载',
+  h5_dzbgxzb_customizedquantity:'市场分析定制报告下载',
+  wx_dzbgxzb_customizedquantity:'市场分析定制报告下载'
+  
 }
 
 // tip
@@ -375,7 +384,15 @@ var tipMap = {
     // 文库
   h5_library_details_free: '此文档为剑鱼文库的付费下载内容,提交资料后可免费下载。',
   app_library_details_free: '此文档为剑鱼文库的付费下载内容,提交资料后可免费下载。',
-  wx_library_details_free: '此文档为剑鱼文库的付费下载内容,提交资料后可免费下载。'
+  wx_library_details_free: '此文档为剑鱼文库的付费下载内容,提交资料后可免费下载。',
+  // 市场分析定制报告
+  app_dzbg_fullreport:'请留下联系方式,我们会安排客户经理与您对接下载查看!',
+  h5_dzbg_fullreport:'请留下联系方式,我们会安排客户经理与您对接下载查看!',
+  wx_dzbg_fullreport:'请留下联系方式,我们会安排客户经理与您对接下载查看!',
+    // 报告下载下单页引流留资
+  app_dzbgxzb_customizedquantity:'请留下联系方式,我们会安排客户经理与您对接,下载更多市场分析定制报告!',
+  h5_dzbgxzb_customizedquantity:'请留下联系方式,我们会安排客户经理与您对接,下载更多市场分析定制报告!',
+  wx_dzbgxzb_customizedquantity:'请留下联系方式,我们会安排客户经理与您对接,下载更多市场分析定制报告!'
 }
 
 // 留资来源(数据库新增字段,记录留资对应的来源,之前未记录的不考虑,新增的source要记录)
@@ -489,7 +506,15 @@ var sourceDescMap = {
       // 文库
   h5_library_details_free: '剑鱼文库-免费下载文档',
   app_library_details_free: '剑鱼文库-免费下载文档',
-  wx_library_details_free: '剑鱼文库-免费下载文档'
+  wx_library_details_free: '剑鱼文库-免费下载文档',
+    // 市场分析定制报告
+  app_dzbg_fullreport:'申请免费体验-完整查看市场分析定制报告',
+  h5_dzbg_fullreport:'申请免费体验-完整查看市场分析定制报告',
+  wx_dzbg_fullreport:'申请免费体验-完整查看市场分析定制报告',
+    // 报告下载下单页引流留资
+    app_dzbgxzb_customizedquantity:'市场分析定制报告下载包-定制报告份数',
+    h5_dzbgxzb_customizedquantity:'市场分析定制报告下载包-定制报告份数',
+    wx_dzbgxzb_customizedquantity:'市场分析定制报告下载包-定制报告份数'
 }
 
 var vNode = {
@@ -1672,6 +1697,7 @@ var vNode = {
                  },'提交成功')
                   break
                 }
+                // 文库
                 case 'h5_library_details_free':
                 case 'app_library_details_free':
                 case 'wx_library_details_free':{
@@ -1679,7 +1705,25 @@ var vNode = {
                       history.back()
                     },'提交成功')
                     break
-              }    // 文库
+              }   
+              // 市场分析定制报告下载包
+              case 'app_dzbg_fullreport':
+              case 'h5_dzbg_fullreport':
+              case 'wx_dzbg_fullreport':{
+                _this.showMessage('已收到您提交的市场分析定制报告体验申请,我们会尽快联系您。', '我知道了', function () {
+                  history.back()
+                },'提交成功')
+                break
+              }
+              // 市场分析定制报告下载包 下单页
+              case 'app_dzbgxzb_customizedquantity':
+              case 'h5_dzbgxzb_customizedquantity':
+              case 'wx_dzbgxzb_customizedquantity':{
+                _this.showMessage('已收到您提交的市场分析定制报告下载申请,我们会尽快联系您。', '我知道了', function () {
+                  history.back()
+                },'提交成功')
+                break
+              }
               default: {
                 var biaoshu = source === 'bid_document_Introduction_page' || source.indexOf('article_BidPreparation') > -1
                 // 标书制作或者三方认证(case语句满足不了条件,放default中做更多判断)

+ 341 - 0
src/web/staticres/common-module/portrait/css/downloadpopup.css

@@ -0,0 +1,341 @@
+.download-popup.j-popup {
+  padding-bottom: 0.4rem;
+  min-height: 11.6rem;
+  box-sizing: border-box;
+}
+.j-popup .popup-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 1.28rem;
+  padding: 0 .32rem;
+}
+.down-email-input.van-cell{
+  padding: 0.24rem 0 0.24rem 0.24rem;
+  margin-top: 0.24rem;
+  background: linear-gradient(180deg, #F7F9FA 0%, rgba(247, 249, 250, 0) 100%);
+  border: 0.02rem solid #0000000D;
+  border-radius: 0.16rem;
+  
+}
+.down-email-input.van-cell--required::before{
+  top: 0.2rem;
+  left: 0.12rem;
+}
+.down-email-input .van-cell__title.van-field__label{
+  width: 1.3rem;
+  font-size: 0.24rem;
+  line-height: 0.36rem;
+  height: 0.36rem;
+  margin-right: 0;
+  color:#5F5E64;
+}
+.down-email-input .van-cell__value.van-field__value{
+  font-size: 0.26rem;
+  line-height: 0.36rem;
+  height: 0.36rem;
+}
+.emailText{
+  color: #FB483D;
+  font-size: 0.26rem;
+  line-height: 0.36rem;
+  padding-left: 1.54rem;
+  padding-top: 0.14rem;
+}
+.down-email-input .van-field__control{
+  color: #171826;
+}
+.download-popup.j-popup .van-popup__close-icon {
+  font-size: 0.4rem;
+  color: #C0C4CC;
+}
+
+.download-popup.j-popup .popup-header.header-title {
+  color: #171826;
+  font-size: 0.4rem;
+}
+
+.download-popup .download-content {
+  padding: 0 0.32rem 0.14rem 0.32rem;
+  max-height: 8.5rem;
+  overflow-y: scroll;
+}
+
+.download-popup .download-content .titleconent {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 0.24rem;
+}
+
+.download-popup .download-content .titleconent>div {
+  display: flex;
+  align-items: center;
+}
+
+.download-content .titlecon_left {
+  font-size: 0.32rem;
+  font-weight: 400;
+  line-height: 0.48rem;
+  color: #171826;
+}
+
+.download-content .titlecon_right {
+  font-size: 0.28rem;
+  font-weight: 400;
+  line-height: 0.4rem;
+  color: #2ABED1;
+  text-align: right;
+
+}
+
+.download-content .right_icon {
+  width: 0.24rem;
+  height: 0.24rem;
+  background-size: contain;
+  background-repeat: no-repeat;
+  background-image: url('../image/icon/icon-right.png');
+}
+
+.download-content .desccontent {
+  font-size: 0.24rem;
+  line-height: 0.36rem;
+  color: #5F5E64;
+  margin-top: 0.16rem;
+}
+
+.download-content .detailed_content {
+  height: 1.5rem;
+  border-radius: 0.16rem;
+  border: 0.02rem solid #0000000D;
+  background: linear-gradient(180deg, #F7F9FA 0%, rgba(247, 249, 250, 0) 100%);
+  border-radius: 0.16rem;
+  padding: 0.22rem;
+  margin-top: 0.24rem;
+
+}
+.download-content .detailed_content .detailed_row{
+  display: flex;
+  text-align: left;
+  align-items: center;
+  margin-top: 0.24rem;
+}
+.download-content .detailed_content .detailed_row:first-child{
+  margin-top: 0;
+}
+.download-content .detailed_content .detailed_row .detailed_row_item {
+display: flex;
+align-items: center;
+flex: 1;
+}
+.detailed_content .detailed_row .detailed_row_item .detailed_row_item_title {
+ font-size: 0.24rem;
+  font-weight: 400;
+  line-height: 0.36rem;
+  color: #5F5E64;
+}
+.detailed_content .detailed_row .detailed_row_item .detailed_row_item_value {
+  font-size: 0.26rem;
+  font-weight: 400;
+  line-height: 0.4rem;
+  color: #171826;
+}
+.download_instructions{
+  margin-top: 0.16rem;
+}
+.download_instructions .instructions_text{
+font-size: 0.24rem;
+font-weight: 400;
+line-height: 0.36rem;
+text-align: left;
+color: #5F5E64;
+
+}
+.hieightlight{
+  color: #2ABED1;
+}
+.download_instructions .under_line{
+  text-decoration: underline;
+}
+.download_footbox{
+  background: linear-gradient(360deg, #FFFFFF 0%, #F8FEFF 100%);
+  border-top: 0.02rem solid #0000000D;
+  box-shadow: 0px -0.04rem 0.16rem 0px #3693B30D;
+  height: 1.2rem;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0.16rem 0.32rem;
+  box-sizing: border-box;
+  /* margin-top: 0.14rem; */
+}
+.download_footbox .footbox_left{
+}
+.download_footbox .footbox_left .count_text{
+  font-size: 0.26rem;
+  color: #5F5E64;
+  line-height: 0.4rem;
+}
+.download_footbox .footbox_right{
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  min-width: 1.4rem;
+  height: 0.48rem;
+  color: #2ABED1;
+  font-size: 0.28rem;
+  border: 0.02rem solid #2ABED1;
+  border-radius: 0.4rem;
+}
+.download_footbox .footflex_box{
+  display: flex;
+  align-items: center;
+  margin-top: 0.06rem;
+}
+.download_footbox .footflex_box .balance_tag{
+  min-width: 2.66rem;
+  height: 0.4rem;
+  background-color: #FFECEC;
+  color: #FB483D;
+  border-radius: 0.4rem;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 0.26rem;
+  margin-left: 0.2rem;
+}
+.down-footbtnGroup {
+  margin: 0.16rem 0.32rem;
+  height: 0.92rem;
+  background-color: #2ABED1;
+  color: #F7F9FA;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 0.36rem;
+  border-radius:0.16rem;
+}
+.down-footbtnGroup .download-icon{
+  content: '';
+  display: inline-block;
+  width: 0.4rem;
+  height: 0.4rem;
+  background-image: url('../image/icon/download.png');
+  background-size: contain;
+  background-repeat: no-repeat;
+  margin-right: 0.04rem;
+}
+.rightArrow_icon{
+  width: 0.24rem;
+  height: 0.24rem;
+  background-size: contain;
+  background-repeat: no-repeat;
+  background-image: url('../image/icon/icon-right.png');
+}
+.font-b{
+  font-weight: bold;
+}
+.download_empty{
+  width: 100%;
+}
+.download_empty .download_empty_img{
+  width: 4rem;
+  height: 4rem;
+  background-image: url('../image/empty.png');
+  background-size: contain;
+  margin: auto;
+  background-repeat: no-repeat;
+}
+.download_empty .download_empty_text{
+  font-size: 0.24rem;
+  line-height: 0.36rem;
+  color: #999999;
+  max-width: 3.36rem;
+  margin: auto;
+  text-align: center;
+}
+.download_filtering_module{
+  background: linear-gradient(180deg, #F7F9FA 0%, rgba(247, 249, 250, 0) 100%);
+  border: 0.02rem solid  #0000000D;
+  padding: 0.24rem;
+  border-radius: 0.16rem;
+  margin-top: 0.24rem;
+
+}
+.download_filtering_module .filtering_module_con{
+  display: flex;
+  margin-bottom: 0.24rem;
+  /* align-items: center; */
+}
+.flex-a-c{
+  align-items: center;
+}
+.download_filtering_module .filtering_module_con:last-child{
+  margin-bottom: 0;
+}
+.download_filtering_module .filtering_module_label{
+  color: #5F5E64;
+  line-height: 0.4rem;
+  font-size: 0.24rem;
+  min-width: 1.3rem;
+
+}
+.download_filtering_module .filtering_module_value{
+  color: #171826;
+  line-height: 0.4rem;
+  font-size: 0.28rem;
+}
+.filtering_box{
+
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  margin-top: 0.24rem;
+}
+.filtering_box .titlecon_right {
+  font-size: 0.28rem;
+  font-weight: 400;
+  line-height: 0.4rem;
+  color: #2ABED1;
+  text-align: right;
+
+}
+
+.filtering_box .right_icon {
+  width: 0.24rem;
+  height: 0.24rem;
+  background-size: contain;
+  background-repeat: no-repeat;
+  background-image: url('../image/icon/icon-right.png');
+}
+.download-popup  .years-container{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  /* padding: .22rem .32rem; */
+  /* background: #fff; */
+}
+.download-popup  .year-input{
+  width: 2.4rem;
+  height: .52rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: 1px solid #eee;
+  border-radius: 4px;
+  padding: 0;
+}
+.download-popup  .year-input .van-field__control{
+  text-align: center;
+}
+.download-popup  .border-active{
+  border-color: #2abed1;
+}
+.van-picker-column__item--selected {
+  color: #2ABED1;
+   font-size: 18px;
+}
+.line_down{
+  color: #5F5E64;
+  margin: 0 0.02rem;
+}

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