Просмотр исходного кода

Merge branch 'feature/v4.7.23' of http://192.168.3.207:8080/qmx/jy into feature/v4.7.23

zhangxinlei1996 2 лет назад
Родитель
Сommit
4c5cdbea59
100 измененных файлов с 6169 добавлено и 2499 удалено
  1. 2 1
      src/active.json
  2. 3 1
      src/config.json
  3. 2 1
      src/jfw/front/big-member.go
  4. 602 12
      src/jfw/front/follow.go
  5. 26 21
      src/jfw/front/front.go
  6. 19 18
      src/jfw/front/frontRouter.go
  7. 45 42
      src/jfw/front/shorturl.go
  8. 57 18
      src/jfw/front/supsearch.go
  9. 8 15
      src/jfw/front/swordfish.go
  10. 81 0
      src/jfw/jyutil/jyutil.go
  11. 10 18
      src/jfw/modules/app/src/app/followent/followent.go
  12. 1 1
      src/jfw/modules/app/src/app/front/bigMember.go
  13. 850 760
      src/jfw/modules/app/src/app/front/follow.go
  14. 14 29
      src/jfw/modules/app/src/app/front/front.go
  15. 17 16
      src/jfw/modules/app/src/app/front/shorturl.go
  16. 25 29
      src/jfw/modules/app/src/app/front/swordfish.go
  17. 82 0
      src/jfw/modules/app/src/app/jyutil/util.go
  18. 2 1
      src/jfw/modules/app/src/config.json
  19. 10 2
      src/jfw/modules/app/src/db.json
  20. 1 0
      src/jfw/modules/app/src/main.go
  21. 2 2
      src/jfw/modules/app/src/seo.json
  22. 51 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/public.css
  23. 4 1
      src/jfw/modules/app/src/web/staticres/jyapp/css/dev2/superSearch.css
  24. 7 0
      src/jfw/modules/app/src/web/staticres/jyapp/invoice/css/invoicing.css
  25. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/js/common.js
  26. 15 14
      src/jfw/modules/app/src/web/staticres/jyapp/me/js/mine.js
  27. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_order_detail.css
  28. 36 14
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_order_detail.js
  29. 23 88
      src/jfw/modules/app/src/web/templates/big-member/page_client_follow_list.html
  30. 3 3
      src/jfw/modules/app/src/web/templates/big-member/page_pro_follow_detail.html
  31. 25 8
      src/jfw/modules/app/src/web/templates/big-member/page_pro_follow_list.html
  32. 1 0
      src/jfw/modules/app/src/web/templates/commonPay/myOrder.html
  33. 17 14
      src/jfw/modules/app/src/web/templates/followent/add.html
  34. 8 7
      src/jfw/modules/app/src/web/templates/followent/list.html
  35. 23 15
      src/jfw/modules/app/src/web/templates/followent/set.html
  36. 21 13
      src/jfw/modules/app/src/web/templates/invoice/invoicing.html
  37. 5 1
      src/jfw/modules/app/src/web/templates/vipsubscribe/vip_order_detail.html
  38. 1687 0
      src/jfw/modules/app/src/web/templates/weixin/follow/detail.html
  39. 76 146
      src/jfw/modules/app/src/web/templates/weixin/follow/list.html
  40. 1 1
      src/jfw/modules/app/src/web/templates/weixin/follow/set.html
  41. 72 51
      src/jfw/modules/app/src/web/templates/weixin/wxinfocontent.html
  42. 2 2
      src/jfw/modules/bigmember/src/config/config.go
  43. 9 1
      src/jfw/modules/bigmember/src/db.json
  44. 14 0
      src/jfw/modules/bigmember/src/db/db.go
  45. 245 257
      src/jfw/modules/bigmember/src/entity/followEnterprise.go
  46. 263 180
      src/jfw/modules/bigmember/src/entity/followProject.go
  47. 4 1
      src/jfw/modules/bigmember/src/service/follow/enterprise.go
  48. 44 9
      src/jfw/modules/bigmember/src/service/follow/project.go
  49. 19 17
      src/jfw/modules/bigmember/src/service/use/use.go
  50. 11 1
      src/jfw/modules/common/src/qfw/util/jy/bigVipPower.go
  51. 16 13
      src/jfw/modules/common/src/qfw/util/jy/subscribepush.go
  52. 30 4
      src/jfw/modules/followent/src/db.json
  53. 39 25
      src/jfw/modules/followent/src/followent/followent.go
  54. 15 20
      src/jfw/modules/followent/src/web/templates/weixin/add.html
  55. 44 33
      src/jfw/modules/followent/src/web/templates/weixin/list.html
  56. 41 34
      src/jfw/modules/followent/src/web/templates/weixin/set.html
  57. 1 0
      src/jfw/modules/publicapply/src/ad/entity/struct.go
  58. 6 3
      src/jfw/modules/publicapply/src/bidcollection/entity/entity.go
  59. 5 1
      src/jfw/modules/publicapply/src/config.json
  60. 4 0
      src/jfw/modules/publicapply/src/config/config.go
  61. 83 18
      src/jfw/modules/publicapply/src/customer/entity/entiy.go
  62. 13 11
      src/jfw/modules/publicapply/src/customer/service/service.go
  63. 4 1
      src/jfw/modules/publicapply/src/dataexport/service/action.go
  64. 1 1
      src/jfw/modules/publicapply/src/db.json
  65. 2 2
      src/jfw/modules/publicapply/src/db/db.go
  66. 15 1
      src/jfw/modules/publicapply/src/subscribePush/service/pushList.go
  67. 2 0
      src/jfw/modules/subscribepay/src/a/init.go
  68. 12 1
      src/jfw/modules/subscribepay/src/config.json
  69. 38 26
      src/jfw/modules/subscribepay/src/config/config.go
  70. 6 10
      src/jfw/modules/subscribepay/src/entity/aiForecastPack.go
  71. 11 10
      src/jfw/modules/subscribepay/src/entity/areaPack.go
  72. 6 10
      src/jfw/modules/subscribepay/src/entity/bidfile.go
  73. 9 9
      src/jfw/modules/subscribepay/src/entity/dataExportPackStruct.go
  74. 7 7
      src/jfw/modules/subscribepay/src/entity/dataReportStruct.go
  75. 11 15
      src/jfw/modules/subscribepay/src/entity/dataexport.go
  76. 5 5
      src/jfw/modules/subscribepay/src/entity/entniche.go
  77. 5 9
      src/jfw/modules/subscribepay/src/entity/integral.go
  78. 8 8
      src/jfw/modules/subscribepay/src/entity/jyCourseOnlineStruct.go
  79. 6 6
      src/jfw/modules/subscribepay/src/entity/jyCourseStruct.go
  80. 4 9
      src/jfw/modules/subscribepay/src/entity/member.go
  81. 141 128
      src/jfw/modules/subscribepay/src/entity/order.go
  82. 17 0
      src/jfw/modules/subscribepay/src/entity/payCalbackStrust.go
  83. 7 7
      src/jfw/modules/subscribepay/src/entity/resourcePackStruct.go
  84. 62 53
      src/jfw/modules/subscribepay/src/entity/subscribeVip.go
  85. 1 0
      src/jfw/modules/subscribepay/src/filter/sessionfilter.go
  86. 24 1
      src/jfw/modules/subscribepay/src/pay/util.go
  87. 1 1
      src/jfw/modules/subscribepay/src/service/areaPack.go
  88. 43 27
      src/jfw/modules/subscribepay/src/service/commonAction.go
  89. 2 0
      src/jfw/modules/subscribepay/src/service/dataexportPack.go
  90. 10 10
      src/jfw/modules/subscribepay/src/service/invoice.go
  91. 57 39
      src/jfw/modules/subscribepay/src/service/orderListDetails.go
  92. 2 2
      src/jfw/modules/subscribepay/src/service/payCallback.go
  93. 575 0
      src/jfw/modules/subscribepay/src/service/salesCreateOrder.go
  94. 8 7
      src/jfw/modules/subscribepay/src/service/userAccountInfo.go
  95. 2 0
      src/jfw/modules/subscribepay/src/service/vipSubscribeChange.go
  96. 74 66
      src/jfw/modules/subscribepay/src/service/vipSubscribePay.go
  97. 2 1
      src/jfw/modules/subscribepay/src/timetask.json
  98. 107 24
      src/jfw/modules/subscribepay/src/timetask/timetask.go
  99. 37 6
      src/jfw/modules/subscribepay/src/util/coupon.go
  100. 1 1
      src/jfw/modules/subscribepay/src/util/db.go

+ 2 - 1
src/active.json

@@ -18,7 +18,8 @@
 		"doubleEleven":"https://www.jianyu360.cn/swordfish/SingleLogin?toHref=https://www.jianyu360.cn/swordfish/SingleLogin?toHref=https://www.jianyu360.cn/weixin/leads/doubleEleven&title=%E7%95%99%E8%B5%84%E4%BA%92%E5%8A%A8%E6%8A%BD%E5%A5%96",
 		"mayActive":"https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/front/vipsubscribe/toSubVipSetPage?active=may&title=%E6%A0%87%E8%AE%AF%E8%AE%A2%E9%98%85&discored=81",
 		"introducePageB":"https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/big/wx/page/landingPage&title=%E5%A4%A7%E4%BC%9A%E5%91%98%E4%BB%8B%E7%BB%8D%E9%A1%B5",
-		"pageBBuy":"https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/jy_mobile/common/order/create/bigmember&title=%E5%A4%A7%E4%BC%9A%E5%91%98"
+		"pageBBuy":"https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/jy_mobile/common/order/create/bigmember&title=%E5%A4%A7%E4%BC%9A%E5%91%98",
+		"wxSubscrbePage":"https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/swordfish/SingleLogin?toHref=https://wx.jianyu360.cn/front/vipsubscribe/toSubVipSetPage"
 	},
 	"lottery":"https://host.huiju.cool/p/26256",
 	"mayActive":{

+ 3 - 1
src/config.json

@@ -56,7 +56,9 @@
 		"chanpartner":"/weixin/frontPage/partner/sess/partner?p=wxmeun",
 		"datareport":"/datareport/page/order/detail/%s?advertcode=%s",
 		"vipFree7":"/weixin/frontPage/share/sess/index?p=wxmeun",
-		"toSubVipSetPage":"/front/vipsubscribe/toSubVipSetPage?advertcode=%s"
+		"toSubVipSetPage":"/front/vipsubscribe/toSubVipSetPage?advertcode=%s",
+		"followProjectList":"/big/wx/page/pro_follow_list?advertcode=%s",
+		"followProjectSet": "/big/wx/page/pro_follow_detail?fid=%s&sid=%s&advertcode=%s"
     },
     "jy_activeset": {
         "activitystartcode": "3201000000",

+ 2 - 1
src/jfw/front/big-member.go

@@ -1,10 +1,11 @@
 package front
 
 import (
-	"github.com/go-xweb/xweb"
 	"jfw/config"
 	"jfw/public"
 	"qfw/util/jy"
+
+	"github.com/go-xweb/xweb"
 )
 
 type BigMemberAction struct {

+ 602 - 12
src/jfw/front/follow.go

@@ -16,8 +16,11 @@ import (
 	"qfw/util/redis"
 	"qfw/util/rpc"
 	"strings"
+	"sync"
 	"time"
 
+	"github.com/go-xweb/log"
+
 	"github.com/SKatiyar/qr"
 
 	"github.com/go-xweb/xweb"
@@ -28,10 +31,10 @@ import (
 type Follow struct {
 	*xweb.Action
 	ajaxReq        xweb.Mapper `xweb:"/follow/ajaxReq"` //关注项目ajax请求
-	list           xweb.Mapper `xweb:"/follow/list"`    //我关注的项目
-	add            xweb.Mapper `xweb:"/follow/add"`     //添加关注项目
+	newList        xweb.Mapper `xweb:"/follow/list"`    //我关注的项目
+	detaiToList    xweb.Mapper `xweb:"/follow/set/(\\w+)/([^.]*)"`
+	add            xweb.Mapper `xweb:"/follow/add"` //添加关注项目
 	addsave        xweb.Mapper `xweb:"/follow/addsave"`
-	set            xweb.Mapper `xweb:"/follow/set/(\\w+)/([^.]*)"`
 	notice         xweb.Mapper `xweb:"/follow/notice/([^.]+)/([^.]*)"` //项目公告
 	allNotice      xweb.Mapper `xweb:"/follow/allNotice"`              //项目公告/(.*)
 	visited        xweb.Mapper `xweb:"/follow/notice/visited"`
@@ -45,6 +48,8 @@ type Follow struct {
 	pcEntAllNotice xweb.Mapper `xweb:"/front/pcEntAllNotice"`
 	//分享拉新领取超级订阅
 	followGift xweb.Mapper `xweb:"/front/followGift/(.*)"`
+	//list           xweb.Mapper `xweb:"/follow/list"`    //我关注的项目
+	//set            xweb.Mapper `xweb:"/follow/set/(\\w+)/([^.]*)"`
 }
 
 var followLimit int
@@ -54,6 +59,16 @@ func init() {
 	followLimit = util.IntAllDef(config.Sysconfig["followProject"], 10)
 }
 
+//项目关注数据合并一张表 路由到大会员项目关注列表
+func (m *Follow) NewList() error {
+	return m.Redirect("/big/wx/page/pro_follow_list")
+}
+
+//非大会员用户访问关注项目-->访问大会员的项目管理路由
+func (m *Follow) DetaiToList() error {
+	return m.Redirect("/big/wx/page/pro_follow_list")
+}
+
 //
 func (m *Follow) CheckFPStatus() error {
 	defer util.Catch()
@@ -72,14 +87,15 @@ func (m *Follow) CheckFPStatus() error {
 //
 func (m *Follow) CheckCStatus() error {
 	defer util.Catch()
-	pname := m.GetString("pcname")
-	pcode := m.GetString("pccode")
+	//pname := m.GetString("pcname")
+	//pcode := m.GetString("pccode")
+	sid := util.DecodeArticleId2ByCheck(m.GetString("s_id"))[0]
 	userId, _ := m.GetSession("userId").(string)
-	openId, _ := m.GetSession("s_m_openid").(string)
+	//openId, _ := m.GetSession("s_m_openid").(string)
 	flag := false
 	followid := ""
 	if userId != "" {
-		flag, followid = MFollow(userId, pname, pcode, "", openId)
+		flag, followid = MFollow(userId, sid)
 	}
 	m.ServeJson(map[string]interface{}{
 		"flag":     flag,
@@ -94,8 +110,8 @@ func (m *Follow) Mylist() {
 	id := m.GetString("id")
 	id = util.DecodeArticleId2ByCheck(id)[0]
 	var flag = "F"
-	res, ok := mongodb.FindById("follow_project", id, `{"title":1}`)
-	if ok && res != nil && len(*res) > 0 {
+	res := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{"id": id}, "", "")
+	if res != nil && len(*res) > 0 {
 		flag = "T"
 	}
 	m.ServeJson(map[string]interface{}{
@@ -105,6 +121,70 @@ func (m *Follow) Mylist() {
 
 //关注列表关注
 func (m *Follow) Fwsave() {
+	defer util.Catch()
+	userId := m.GetSession("userId").(string)
+	var status = "n"
+	var followId string
+	s_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+	if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"s_userid": userId}) >= util.Int64All(followLimit) {
+		status = "m"
+	} else if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"s_userid": userId, "s_id": s_id}) > 0 {
+		status = "e"
+	} else {
+		data := make(map[string]interface{})
+		if remind, _ := m.GetInteger("remind"); remind == 1 {
+			data["i_remind"] = 1
+		} else {
+			data["i_remind"] = 0
+		}
+		if bidopentime, err := m.GetInt("bidopentime"); err == nil {
+			data["l_bidopentime"] = bidopentime
+		}
+		if remindtime, err := m.GetInt("remindtime"); err == nil {
+			data["l_remindtime"] = remindtime
+		}
+		projectname := m.GetString("projectname")
+		//data["s_projectname"] = projectname
+		data["s_userid"] = userId
+		data["l_createtime"] = time.Now().Unix()
+		data["s_title"] = projectname
+		data["s_id"] = s_id
+		//data["i_source"] = 3
+		//data["toptype"] = "招标"
+		fields := `"title","comeintime","bidopentime","projectcode","type","href","publishtime","area","subtype","toptype","industry","s_subscopeclass"`
+		res := elastic.GetByIdField("bidding", "bidding", s_id, fields)
+		if res != nil {
+			//	projectUserKey = []string{"s_id", "s_userid", "i_remind", "l_createtime", "l_lastpushtime", "a_visited", "info_source", "s_title", "i_apppushunread", "l_bidopentime", "l_remindtime", "old_id"}
+			data["s_title"] = (*res)["title"]
+			//data["l_publishtime"] = (*res)["publishtime"]
+			data["l_comeintime"] = (*res)["comeintime"]
+			if data["l_bidopentime"] == "" {
+				data["l_bidopentime"] = (*res)["bidopentime"]
+			}
+
+			projectcode, _ := (*res)["projectcode"].(string)
+			if id := public.BaseMysql.Insert("follow_project", data); id > 0 {
+				followId = util.InterfaceToStr(id)
+				status = "y"
+				go public.FollowPush(&rpc.FollowPush{
+					ProjectName: projectname,
+					ProjectCode: projectcode,
+					InfoId:      s_id,
+					FollowId:    followId,
+					UserId:      userId,
+				})
+			}
+		}
+	}
+	m.ServeJson(map[string]interface{}{
+		"status":   status,
+		"followId": util.EncodeArticleId2ByCheck(followId),
+		"infoId":   util.EncodeArticleId2ByCheck(s_id),
+	})
+}
+
+//关注列表关注
+func (m *Follow) FwsaveBk() {
 	defer util.Catch()
 	userId := m.GetSession("userId").(string)
 	openid := m.GetSession("s_m_openid").(string)
@@ -324,7 +404,7 @@ func (m *Follow) Photo(tp string) error {
 	userid, _ := m.GetSession("userId").(string)
 	openid := m.GetSession("s_m_openid").(string)
 	if userid != "" && openid != "" {
-		_, followid = MFollow(userid, projectname, projectcode, "", openid)
+		_, followid = MFollow(userid, openid)
 	}
 	//已关注
 	if followid != "" {
@@ -453,6 +533,122 @@ func (m *Follow) Photo(tp string) error {
 
 //关注项目相关的ajax请求
 func (m *Follow) AjaxReq() {
+	defer util.Catch()
+	userId := m.GetSession("userId").(string)
+	var status = "n"
+	reqType := m.GetString("reqType")
+	var followId string
+	if reqType == "follow" { //快照页面关注
+		s_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+		query := map[string]interface{}{
+			"s_userid": userId,
+		}
+		if public.BaseMysql.Count("follow_project_monitor", query) >= util.Int64All(followLimit) {
+			status = "m"
+		} else if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"s_userid": userId, "s_id": s_id}) > 0 {
+			status = "e"
+		} else {
+			//publishtime, _ := m.GetInt("publishtime")
+			projectname := m.GetString("projectname")
+			projectcode := m.GetString("projectcode")
+			//url := m.GetString("url")
+			title := m.GetString("title")
+			//area := m.GetString("area")
+			//subtype := m.GetString("subtype")
+			//toptype := m.GetString("toptype")
+			//s_type := m.GetString("type")
+			//s_industry := m.GetString("industry")
+			if projectname != "" || projectcode != "" {
+				data := map[string]interface{}{
+					"s_userid": userId,
+					"s_id":     s_id,
+					//"s_url":         url,
+					"s_title":      title,
+					"l_createtime": time.Now().Unix(),
+					"i_remind":     0,
+					//"l_publishtime": publishtime,
+					//"i_source":      1,
+					//"s_province":    area,
+					//"s_area":        area,
+					//"s_type":        s_type,
+					//"s_industry":    s_industry,
+					//"toptype":       "招标",
+				}
+				/*if comeintime, err := m.GetInt("comeintime"); err == nil {
+				  	data["l_comeintime"] = comeintime
+				  }
+				  if s_type := m.GetString("type"); s_type != "" {
+				  	data["s_type"] = s_type
+				  }
+				  if projectname != "" {
+				  	data["s_projectname"] = projectname
+				  } else {
+				  	data["s_projectname"] = title
+				  }
+				  if projectcode != "" {
+				  	data["s_projectcode"] = projectcode
+				  }*/
+				if bidopentime, err := m.GetInt("bidopentime"); err == nil && bidopentime > 0 {
+					data["l_bidopentime"] = bidopentime
+				}
+
+				if followId = util.InterfaceToStr(public.BaseMysql.Insert("follow_project_monitor", data)); len(followId) > 0 {
+					status = "y"
+					go public.FollowPush(&rpc.FollowPush{
+						ProjectName: projectname,
+						ProjectCode: projectcode,
+						InfoId:      s_id,
+						FollowId:    followId,
+						UserId:      userId,
+					})
+				}
+			}
+		}
+	} else if reqType == "cancel" { //取消关注
+		query := map[string]interface{}{
+			"s_userid": userId,
+			"id":       util.DecodeArticleId2ByCheck(m.GetString("_id"))[0],
+		}
+		if data := public.BaseMysql.FindOne("follow_project_monitor", query, "", ""); data != nil {
+			(*data)["s_followid"] = BsonIdToSId((*data)["id"])
+			delete(*data, "id")
+			(*data)["i_status"] = 1
+			mongodb.Save("follow_project_monitor_back", data)
+			if public.BaseMysql.Delete("follow_project_monitor", query) {
+				status = "y"
+				go delRelRedis((*data)["s_userid"], []interface{}{(*data)["s_id"]})
+			}
+		}
+	} else if reqType == "followset" {
+		id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+		if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"id": id, "s_userid": userId}) == 1 {
+
+			data := make(map[string]interface{})
+			data["l_updatetime"] = time.Now().Unix()
+			if remind, _ := m.GetInteger("remind"); remind == 1 {
+				data["i_remind"] = 1
+			} else {
+				data["i_remind"] = 0
+			}
+			if bidopentime, err := m.GetInt("bidopentime"); err == nil {
+				data["l_bidopentime"] = bidopentime
+			}
+			if remindtime, err := m.GetInt("remindtime"); err == nil {
+				data["l_remindtime"] = remindtime
+			}
+			if public.BaseMysql.Update("follow_project_monitor", map[string]interface{}{"id": id}, data) {
+				status = "y"
+			}
+		}
+	}
+	m.ServeJson(map[string]interface{}{
+		"status":   status,
+		"followId": util.EncodeArticleId2ByCheck(followId),
+	})
+}
+
+//关注项目相关的ajax请求
+func (m *Follow) AjaxReqBk() {
 	defer util.Catch()
 	userId := m.GetSession("userId").(string)
 	openid := m.GetSession("s_m_openid").(string)
@@ -577,8 +773,115 @@ func (m *Follow) AjaxReq() {
 	})
 }
 
-//我关注的项目
 func (m *Follow) List() error {
+	userId := util.ObjToString(m.Session().Get("userId"))
+	if userId == "" {
+		return errors.New("查询我关注的项目出错,userid为空")
+	}
+	datas := public.BaseMysql.SelectBySql(fmt.Sprintf(`SELECT * FROM follow_project_monitor WHERE s_userid ="%s" ORDER BY l_lastpushtime,l_createtime DESC LIMIT 0,%d`, userId, util.IntAll(config.Sysconfig["followProject"])))
+	//datas, ok := mongodb.Find("follow_project", `{"s_userid":"`+userId+`"}`, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"s_projectname":1,"s_projectcode":1,"i_remind":1,"l_lastpushtime":1,"l_createtime":1,"s_industry":1,"s_area":1,i_apppushunread":1}`, false, -1, -1)
+	m.T["flag"] = false
+	var followData []map[string]interface{}
+	if datas != nil && len(*datas) > 0 {
+		sidArr := []string{}
+		sidStr := ""
+		followSetting := map[string]map[string]interface{}{}
+		for _, followOne := range *datas {
+			sid := util.ObjToString(followOne["s_id"])
+			if followOne["l_lastpushtime"] != nil && followOne["l_lastpushtime"] != "" {
+				followOne["l_createtime"] = followOne["l_lastpushtime"]
+			} else if followOne["l_lastpushtime"] == nil {
+				followOne["l_lastpushtime"] = followOne["l_createtime"]
+			}
+			sidArr = append(sidArr, sid)
+			sidStr = sidStr + "," + sid
+
+			followSetting[sid] = followOne
+		}
+
+		projectInfos := []map[string]interface{}{}
+
+		pool := make(chan bool, 10)
+		wait := &sync.WaitGroup{}
+		var lock sync.Mutex
+		for _, v := range SplitArray(sidArr, 50) {
+			pool <- true
+			wait.Add(1)
+			go func(arr []string) error {
+				defer func() {
+					wait.Done()
+					<-pool
+				}()
+				//es查询
+				projectInfos_, err := getProjectsBySid(arr)
+				lock.Lock()
+				projectInfos = append(projectInfos, projectInfos_...)
+				lock.Unlock()
+				if err != nil {
+					err = errors.New("项目信息查询异常")
+					return err
+				}
+				return nil
+			}(v)
+		}
+		wait.Wait()
+
+		for _, projectinfo := range projectInfos { //补充设置信息
+			for _, k := range util.ObjArrToStringArr(projectinfo["ids"].([]interface{})) {
+				if info, ok := followSetting[k]; ok {
+					info["s_area"] = projectinfo["area"]
+					info["s_buyerclass"] = projectinfo["buyerclass"]
+					info["s_budget"] = util.Float64All(projectinfo["budget"])
+					info["s_title"] = projectinfo["projectname"]
+					info["s_projectname"] = projectinfo["projectname"]
+					info["toptype"] = projectinfo["bidstatus"]
+					info["s_projectcode"] = projectinfo["projectcode"]
+					if projectinfo["topscopeclass"] != nil && len(projectinfo["topscopeclass"].([]interface{})) > 0 {
+						topscopeclass, _ := projectinfo["topscopeclass"].([]interface{})
+						info["s_industry"] = topscopeclass[0]
+					}
+					break
+				}
+			}
+		}
+
+		for _, sid := range sidArr {
+			thisRow := followSetting[sid]
+			fid := util.InterfaceToStr(thisRow["id"])
+			thisRow["id"] = fid
+			if thisRow["s_title"] == nil {
+				log.Println("异常数据:", sid, fid)
+				continue
+			}
+			delete(thisRow, "s_id")
+			followData = append(followData, thisRow)
+		}
+
+		for _, v := range followData {
+			v["followid"] = BsonIdToSId(v["id"])
+			v["_id"] = util.EncodeArticleId2ByCheck(BsonIdToSId(v["id"]))
+			if v["l_lastpushtime"] == "" || v["l_lastpushtime"] == nil {
+				v["l_lastpushtime"] = v["l_createtime"]
+			}
+		}
+	}
+	m.T["datas"] = followData
+	if len(*datas) >= followLimit {
+		m.T["flag"] = true
+	}
+	myopenid, _ := m.Session().Get("s_m_openid").(string)
+	m.T["openid"] = se.EncodeString(myopenid)
+	mynickname, _ := m.Session().Get("s_nickname").(string)
+	myavatar, _ := m.Session().Get("s_avatar").(string)
+	m.T["nickname"] = mynickname
+	m.T["avatar"] = myavatar
+	m.T["signature"] = wx.SignJSSDK(m.Site() + m.Url())
+	m.T["followLimit"] = followLimit
+	return m.Render("/weixin/follow/list.html", &m.T)
+}
+
+//我关注的项目
+func (m *Follow) ListBk() error {
 	defer util.Catch()
 	myopenid, _ := m.Session().Get("s_m_openid").(string)
 	userId := util.ObjToString(m.Session().Get("userId"))
@@ -623,6 +926,66 @@ func (m *Follow) Add() error {
 
 //手动添加关注项目
 func (m *Follow) Addsave() error {
+	defer util.Catch()
+	var status = "n"
+	var id string
+	userId := m.GetSession("userId").(string)
+	query := map[string]interface{}{
+		"s_userid": userId,
+	}
+	if public.BaseMysql.Count("follow_project_monitor", query) >= util.Int64All(followLimit) {
+		status = "m"
+	} else {
+		//		"s_id":           sid,          //信息id
+		//		"s_userid":       this.UserId,  //用户id
+		//		"i_remind":       0,            //开标提醒
+		//		"l_createtime":   nowTimeStamp, //关注时间
+		//		"l_lastpushtime": nowTimeStamp, //关注时间
+		//		"a_visited":      "",           //浏览记录
+		if projectname := m.GetString("projectname"); projectname != "" {
+			data := map[string]interface{}{
+				"s_userid":     userId,
+				"l_createtime": time.Now().Unix(),
+				"i_remind":     0,
+				"s_title":      projectname,
+				"a_visited":    "",
+			}
+			//匹配
+			r := elastic.GetPage("bidding", "bidding", `{"TERM_projectname":"`+projectname+`"}`, `{"comeintime":-1}`, `"_id","title","comeintime","bidopentime","projectcode","type","href","publishtime","subtype","toptype","area","industry","s_subscopeclass"`, -1, -1)
+			var matchingFlag = r != nil && len(*r) != 0
+			var projectcode, sid string
+			if matchingFlag {
+				d := (*r)[0]
+				sid = d["_id"].(string) //(d["_id"].(bson.ObjectId)).Hex()
+				data["s_id"] = sid
+				publishtime := d["publishtime"]
+				data["l_lastpushtime"] = publishtime
+				data["s_title"] = d["title"]
+				if bidopentime := d["bidopentime"]; bidopentime != nil {
+					data["l_bidopentime"] = bidopentime
+				}
+			}
+			if public.BaseMysql.Insert("follow_project_monitor", data) > 0 {
+				status = "y"
+				go public.FollowPush(&rpc.FollowPush{
+					ProjectName: projectname,
+					ProjectCode: projectcode,
+					InfoId:      sid,
+					FollowId:    id,
+					UserId:      userId,
+				})
+			}
+		}
+	}
+	m.ServeJson(map[string]interface{}{
+		"status": status,
+		"id":     util.EncodeArticleId2ByCheck(id),
+	})
+	return nil
+}
+
+//手动添加关注项目
+func (m *Follow) AddsaveBk() error {
 	defer util.Catch()
 	var status = "n"
 	var id string
@@ -709,7 +1072,110 @@ func (m *Follow) Addsave() error {
 	})
 	return nil
 }
+
 func (m *Follow) Set(tp, id string) error {
+	defer util.Catch()
+	//isDel := false
+	var isDel bool
+	id = util.DecodeArticleId2ByCheck(id)[0]
+	//fields := `{"s_id":1,"i_source":1,"s_projectname":1,"s_projectcode":1,"s_url":1,"i_remind":1,"s_type":1,"l_bidopentime":1,"l_remindtime":1,"a_relationinfo":1,"a_visited":1,"l_lastpushtime":1,"a_lastpushids":1}`
+	//_id, _ := primitive.ObjectIDFromHex(id)
+	data := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{
+		"id":       id,
+		"s_userid": m.GetSession("userId").(string),
+	}, "", "")
+	if data == nil || len(*data) == 0 {
+		data, _ = mongodb.FindOneByField("follow_project_monitor_back", `{"s_followid":"`+id+`"}`, "")
+		isDel = true
+	}
+	if data == nil || len(*data) == 0 {
+		return m.Redirect("/jyapp/free/mob/err")
+	}
+	m.T["isDel"] = isDel
+	sid, _ := (*data)["s_id"].(string)
+
+	list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"match": {"list.infoid": "`+sid+`"}}]}},"_source":["list","projectcode","projectname","bidopentime","area","city","agency","buyer","buyerperson","buyertel","bidstatus"],"from": 0,"size": 1}`)
+	if len(*list) == 0 {
+		return m.Redirect("/jyapp/free/mob/err")
+	}
+	projectInfo := (*list)[0]
+	projectIds, _ := projectInfo["list"].([]interface{})
+	//if !ok {
+	//	return m.Redirect("/jyapp/free/mob/err")
+	//}
+	thisList := []map[string]interface{}{}
+	projectname, _ := projectInfo["projectname"].(string)
+	projectcode, _ := projectInfo["projectcode"].(string)
+
+	if sid != "" {
+		r := elastic.GetPage("bidding", "bidding", `{"TERM_projectname":"`+projectname+`"}`, `{"comeintime":-1}`, `"_id","title","comeintime","bidopentime","projectcode","type","href","publishtime","subtype","toptype","area","industry","s_subscopeclass"`, -1, -1)
+		if r != nil && len(*r) != 0 {
+			d := (*r)[0]
+			m.T["url"] = d["href"].(string)
+			if s_type := d["type"]; s_type != nil {
+				m.T["type"] = d["type"]
+				m.T["subtype"] = d["subtype"]
+				m.T["toptype"] = d["toptype"]
+			}
+		}
+	}
+
+	for _, d := range util.ObjArrToMapArr(projectIds) {
+		if len(thisList) >= 50 {
+			break
+		}
+		mySelf := make(map[string]interface{})
+		mySelf["s_type"] = util.ObjToString(d["type"])
+		mySelf["s_toptype"] = util.ObjToString(d["toptype"])
+		mySelf["s_subtype"] = util.ObjToString(d["subtype"])
+		mySelf["s_province"] = util.ObjToString(d["area"])
+		mySelf["s_projectname"] = projectname
+		mySelf["s_title"] = d["title"]
+		mySelf["s_projectcode"] = projectcode
+		mySelf["s_url"] = d["href"].(string)
+		mySelf["s_id"] = ""
+		mySelf["s_eid"] = util.EncodeArticleId2ByCheck(sid)
+		mySelf["l_publishtime"] = d["publishtime"]
+		if projectInfo["industry"] == nil && projectInfo["s_subscopeclass"] != nil {
+			ind := strings.Split(util.ObjToString(projectInfo["s_subscopeclass"]), ",")[0]
+			mySelf["s_industry"] = strings.Split(ind, "_")[0]
+		} else {
+			mySelf["s_industry"] = projectInfo["industry"]
+		}
+		thisList = append(thisList, mySelf)
+	}
+	jyutil.SortData(&thisList, "l_publishtime", true)
+	m.T["relationinfo"] = thisList
+
+	m.T["_id"] = util.EncodeArticleId2ByCheck(id)
+	m.T["sid"] = util.EncodeArticleId2ByCheck(sid)
+	//m.T["a_lastpushids"] = (*data)["ids"]
+	l_bidopentime := (*data)["l_bidopentime"]
+	if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
+		m.T["bidopentime"] = util.FormatDateWithObj(&l_bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_bidopentime), 0).Weekday().String())
+		m.T["l_bidopentime"] = l_bidopentime
+	}
+	if l_remindtime := (*data)["l_remindtime"]; l_remindtime != nil && l_remindtime != "" && util.Int64All(l_remindtime) != 0 {
+		m.T["remindtime"] = util.FormatDateWithObj(&l_remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_remindtime), 0).Weekday().String())
+		m.T["l_remindtime"] = l_remindtime
+	} else if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
+		date := time.Unix(util.Int64All(l_bidopentime), 0).AddDate(0, 0, -1)
+		m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
+		m.T["l_remindtime"] = date.Unix()
+	}
+	if !isDel {
+		public.BaseMysql.Update("follow_project_monitor", map[string]interface{}{"id": id}, map[string]interface{}{
+			"i_apppushunread": 0,
+		})
+	}
+	m.T["a_visited"] = (*data)["a_visited"]
+	m.T["remind"] = (*data)["i_remind"]
+	m.T["l_lastpushtime"] = (*data)["l_lastpushtime"]
+	m.T["projectname"] = projectname
+	m.T["projectcode"] = projectcode
+	return m.Render("/weixin/follow/set.html", &m.T)
+}
+func (m *Follow) SetBk(tp, id string) error {
 	defer util.Catch()
 	isDel := false
 	id = util.DecodeArticleId2ByCheck(id)[0]
@@ -841,7 +1307,70 @@ func (m *Follow) Set(tp, id string) error {
 	m.T["signature"] = wx.SignJSSDK(m.Site() + m.Url())
 	return m.Render("/weixin/follow/set.html", &m.T)
 }
+
 func (m *Follow) AllNotice() error {
+	defer util.Catch()
+	id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+	var relationinfo []interface{}
+	data := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{
+		"id":       id,
+		"s_userid": m.GetSession("userId").(string),
+	}, "", "")
+	if data == nil || len(*data) == 0 {
+		data, _ = mongodb.FindOneByField("follow_project_monitor_back", `{"s_followid":"`+id+`"}`, "")
+	}
+	sid, _ := (*data)["s_id"].(string)
+	if data != nil && len(*data) > 0 {
+		thisList := []map[string]interface{}{}
+		list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"match": {"list.infoid": "`+sid+`"}}]}},"_source":["list","projectcode","projectname","bidopentime","area","city","agency","buyer","buyerperson","buyertel","bidstatus"],"from": 0,"size": 1}`)
+		projectInfo := (*list)[0]
+		relationinfo, _ = projectInfo["list"].([]interface{})
+		if relationinfo != nil {
+
+			for _, d := range util.ObjArrToMapArr(relationinfo) {
+				mySelf := make(map[string]interface{})
+				mySelf["s_type"] = util.ObjToString(d["type"])
+				mySelf["s_toptype"] = util.ObjToString(d["toptype"])
+				mySelf["s_subtype"] = util.ObjToString(d["subtype"])
+				mySelf["s_province"] = util.ObjToString(d["area"])
+				mySelf["s_projectname"] = util.ObjToString(d["projectname"])
+				mySelf["s_title"] = d["title"]
+				mySelf["s_projectcode"] = util.ObjToString(d["projectcode"])
+				mySelf["s_url"] = d["href"].(string)
+				mySelf["s_id"] = ""
+				mySelf["s_eid"] = util.EncodeArticleId2ByCheck(sid)
+				mySelf["l_publishtime"] = d["publishtime"]
+				if projectInfo["industry"] == nil && projectInfo["s_subscopeclass"] != nil {
+					ind := strings.Split(util.ObjToString(projectInfo["s_subscopeclass"]), ",")[0]
+					mySelf["s_industry"] = strings.Split(ind, "_")[0]
+				} else {
+					mySelf["s_industry"] = projectInfo["industry"]
+				}
+				thisList = append(thisList, mySelf)
+			}
+			jyutil.SortData(&thisList, "l_publishtime", true)
+			//relationinfo = a_relationinfo.([]interface{})
+			//排序
+			//for x := range relationinfo {
+			//	for y := 0; y < len(relationinfo)-x-1; y++ {
+			//		dt1 := util.Int64All(relationinfo[y].(map[string]interface{})["l_publishtime"])
+			//		dt2 := util.Int64All(relationinfo[y+1].(map[string]interface{})["l_publishtime"])
+			//		if dt1 > 0 && dt2 > 0 && dt1 < dt2 {
+			//			temp := relationinfo[y]
+			//			relationinfo[y] = relationinfo[y+1]
+			//			relationinfo[y+1] = temp
+			//		}
+			//	}
+			//}
+		}
+		(*data)["a_relationinfo"] = thisList
+	}
+	m.ServeJson(map[string]interface{}{
+		"data": data,
+	})
+	return nil
+}
+func (m *Follow) AllNoticeBk() error {
 	defer util.Catch()
 	id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
 	var relationinfo []interface{}
@@ -873,6 +1402,26 @@ func (m *Follow) AllNotice() error {
 	})
 	return nil
 }
+
+func (m *Follow) Visited() error {
+	defer util.Catch()
+	d_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+	if d_id == "" {
+		return nil
+	}
+	reqType, _ := m.GetInteger("type")
+	sid := m.GetString("sid")
+	if reqType == 1 {
+		public.BaseMysql.Update("follow_project_monitor", map[string]interface{}{"s_id": sid}, map[string]interface{}{
+			"$addToSet": map[string]interface{}{"a_visited": sid},
+		})
+	} else if reqType == 2 {
+		mongodb.UpdateById("jy_pushproject", d_id, map[string]interface{}{
+			"$addToSet": map[string]interface{}{"a_visited": sid},
+		})
+	}
+	return nil
+}
 func (m *Follow) Notice(id, followId string) error {
 	defer util.Catch()
 	query := map[string]interface{}{
@@ -916,7 +1465,7 @@ func (m *Follow) Notice(id, followId string) error {
 	m.T["signature"] = wx.SignJSSDK(m.Site() + m.Url())
 	return m.Render("/weixin/follow/notice.html", &m.T)
 }
-func (m *Follow) Visited() error {
+func (m *Follow) VisitedBk() error {
 	defer util.Catch()
 	d_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
 	if d_id == "" {
@@ -1054,3 +1603,44 @@ func (this *Follow) FollowGift(shareid string) error {
 		return this.Render("/frontRouter/pc/share/sess/share-f.html", &this.T)
 	}
 }
+
+//根据多个信息id查询对应的项目信息
+func getProjectsBySid(sids []string) ([]map[string]interface{}, error) {
+	sidStr := strings.Join(sids, `","`)
+	list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"terms": {"list.infoid": ["`+sidStr+`"]}}]}},"_source":["projectname","topscopeclass","_id","area","buyerclass","budget","ids","bidstatus","projectcode"],"from": 0,"size": `+fmt.Sprint(len(sids))+`}`)
+	if len(*list) == 0 {
+		return nil, errors.New("获取项目信息查询出错")
+	}
+	return *list, nil
+}
+
+// SplitArray 分割数组
+func SplitArray(arr []string, num int64) [][]string {
+
+	max := int64(len(arr))
+	//判断数组大小是否小于等于指定分割大小的值,是则把原数组放入二维数组返回
+	if max <= num {
+		return [][]string{arr}
+	}
+	//获取应该数组分割为多少份
+	var quantity int64
+	if max%num == 0 {
+		quantity = max / num
+	} else {
+		quantity = (max / num) + 1
+	}
+	//声明分割好的二维数组
+	var segments = make([][]string, 0)
+	//声明分割数组的截止下标
+	var start, end, i int64
+	for i = 1; i <= quantity; i++ {
+		end = i * num
+		if i != quantity {
+			segments = append(segments, arr[start:end])
+		} else {
+			segments = append(segments, arr[start:])
+		}
+		start = i * num
+	}
+	return segments
+}

+ 26 - 21
src/jfw/front/front.go

@@ -844,26 +844,35 @@ func (m *Front) Sess(ostr string) error {
 			ok, _, _ = FindUserAndCreateSess(openid, m.Session(), "wx", false)
 		}
 		if ok {
-			actionurl := util.ObjToString(urlMap[str[3]])
-			if actionurl != "" {
+			actionurl := ""
+			if str[3] == "" {
 				if len(strs) > 1 {
-					if strings.Contains(actionurl, "followent/newInfo") {
-						actionurl = fmt.Sprintf(actionurl, (strs[1] + "___" + strs[2]))
-					} else {
-						//支持多个参数%s..
-						actionurl = fmt.Sprintf(actionurl, func(tmps []string) []interface{} {
-							res := make([]interface{}, strings.Count(actionurl, "%s"))
-							for k := range res {
-								if k < len(tmps) {
-									res[k] = tmps[k]
-								} else {
-									res[k] = ""
+					actionurl, _ = url.QueryUnescape(strs[1])
+				}
+			} else {
+				actionurl = util.ObjToString(urlMap[str[3]])
+				if actionurl != "" {
+					if len(strs) > 1 {
+						if strings.Contains(actionurl, "followent/newInfo") {
+							actionurl = fmt.Sprintf(actionurl, (strs[1] + "___" + strs[2]))
+						} else {
+							//支持多个参数%s..
+							actionurl = fmt.Sprintf(actionurl, func(tmps []string) []interface{} {
+								res := make([]interface{}, strings.Count(actionurl, "%s"))
+								for k := range res {
+									if k < len(tmps) {
+										res[k] = tmps[k]
+									} else {
+										res[k] = ""
+									}
 								}
-							}
-							return res
-						}(strs[1:])...)
+								return res
+							}(strs[1:])...)
+						}
 					}
 				}
+			}
+			if actionurl != "" {
 				//绑定手机号 跳转
 				if flag, _ := config.Sysconfig["phoneFilterFlag"].(bool); flag { //开关是否开启
 					//action走的nginx配置,需要单独在sess中判断
@@ -888,11 +897,7 @@ func (m *Front) Sess(ostr string) error {
 				}
 				m.Redirect(actionurl)
 			} else {
-				if !ok {
-					log.Println("数据库连接超时!", openid)
-				} else {
-					log.Println("解析结果:", str, ",actionurl为空")
-				}
+				log.Println("解析结果:", str, ",actionurl为空")
 				m.Render("_error.html")
 			}
 		} else {

+ 19 - 18
src/jfw/front/frontRouter.go

@@ -201,6 +201,7 @@ func (this *CommonRouter) BigpcPage(htmlPage string) error {
 
 var bigVipFreePageReg = regexp.MustCompile(`set_.*|free|unit_portrayal|analysis_(search|result)|pro_follow_detail|client_portrayal`)
 
+//工作桌面需求 不需要判断用户权限
 func (this *CommonRouter) doPcBigPage(pageSign, types string) error {
 	page := pageSign
 	userid, _ := this.GetSession("userId").(string)
@@ -208,25 +209,25 @@ func (this *CommonRouter) doPcBigPage(pageSign, types string) error {
 	if userid == "" {
 		return this.Redirect("/notin/page")
 	}
-	//没有购买大会员跳转大会员介绍页
-	if !strings.HasPrefix(pageSign, "svip/ent_ser_portrait") {
-		for _, v := range strings.Split(pageSign, "/") {
-			if v == "" || v == "desktop" {
-				continue
-			}
-			pageSign = v
-			break
-		}
+	//没有购买大会员跳转大会员介绍页(PC端订阅列表 所有用户都能进去)
+	if !strings.HasPrefix(pageSign, "svip/ent_ser_portrait") && pageSign != "big_subscribe" {
+		// for _, v := range strings.Split(pageSign, "/") {
+		// 	if v == "" || v == "desktop" {
+		// 		continue
+		// 	}
+		// 	pageSign = v
+		// 	break
+		// }
 		bigBaseMsg := jy.GetBigVipUserBaseMsg(userid, public.Mysql, public.MQFW)
-		if !bigVipFreePageReg.MatchString(pageSign) && pageSign != "index" {
-			if bigBaseMsg.Status <= 0 && bigBaseMsg.Vip_BuySet.Upgrade != 1 {
-				return this.Redirect("/big/page/index")
-			}
-			//大会员页面权限判断
-			if pageSign != "" && !bigBaseMsg.CheckBigVipFrontPower(pageSign) {
-				return this.Redirect("/big/page/index")
-			}
-		}
+		// if !bigVipFreePageReg.MatchString(pageSign) && pageSign != "index" {
+		// 	if bigBaseMsg.Status <= 0 && bigBaseMsg.Vip_BuySet.Upgrade != 1 {
+		// 		return this.Redirect("/big/page/index")
+		// 	}
+		// 	//大会员页面权限判断
+		// 	if pageSign != "" && !bigBaseMsg.CheckBigVipFrontPower(pageSign) {
+		// 		return this.Redirect("/big/page/index")
+		// 	}
+		// }
 		//限制超级订阅用户不能进入购买页
 		if page == "free/svip/buy" && bigBaseMsg.VipStatus > 0 && types != "upgrade" {
 			return this.Redirect("/front/subscribe.html")

+ 45 - 42
src/jfw/front/shorturl.go

@@ -163,10 +163,10 @@ func (s *Short) Article(stype, id string) error {
 				if ssOpenid != nil {
 					obj["ucbsId"] = util.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
 				}
-				if false && isbid(obj["subtype"]) {
-					//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
-					obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
-				}
+				//if false && isbid(obj["subtype"]) {
+				//	//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
+				//	obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
+				//}
 				//判断时间 //如果是seo页面超过时间访问的进入首页
 				comeinTime := time.Unix(util.Int64All(obj["comeintime"]), 0)
 				if stype == "indexcontent" {
@@ -333,8 +333,9 @@ func (s *Short) Article(stype, id string) error {
 				s.T["advertcode"] = s.GetString("advertcode")
 			} else {
 				obj = map[string]interface{}{
-					"title": obj["title"],
-					"_id":   obj["_id"],
+					"title":   obj["title"],
+					"_id":     obj["_id"],
+					"subtype": obj["subtype"],
 				}
 			}
 			//纠错随机回复
@@ -406,19 +407,19 @@ func (s *Short) Article(stype, id string) error {
 					if len(wo) > 0 {
 						s.T["winnerOther"] = wo
 					}
-					if false && isbid(obj["subtype"]) {
-						//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
-						obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
-					}
-
-					if !(isVip || isMember || isEntniche) { //非会员不展示电话字段
-						if obj["winnertel"] != nil {
-							obj["winnertel"] = "无权限"
-						}
-						if obj["winner_enttel"] != "" {
-							obj["winner_enttel"] = "无权限"
-						}
-					}
+					/*if false && isbid(obj["subtype"]) {
+					  	//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
+					  	obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
+					  }
+
+					  if !(isVip || isMember || isEntniche) { //非会员不展示电话字段
+					  	if obj["winnertel"] != nil {
+					  		obj["winnertel"] = "无权限"
+					  	}
+					  	if obj["winner_enttel"] != "" {
+					  		obj["winner_enttel"] = "无权限"
+					  	}
+					  }*/
 					//判断时间 //如果是seo页面超过时间访问的进入首页
 					comeinTime := time.Unix(util.Int64All(obj["comeintime"]), 0)
 					if stype == "indexcontent" {
@@ -427,7 +428,6 @@ func (s *Short) Article(stype, id string) error {
 						}
 					}
 					FieldProcessing(obj, ssOpenid, industry, id, from_userid, userId, stype, isVip || isMember || isEntniche, false)
-
 					//免费用户正文手机号替换
 					if obj["site"] == "剑鱼信息发布平台" && !isMember {
 						//采购电话中标单位电话置空
@@ -475,15 +475,18 @@ func (s *Short) Article(stype, id string) error {
 					}
 				} else {
 					obj = map[string]interface{}{
-						"title": obj["title"],
-						"_id":   obj["_id"],
+						"title":   obj["title"],
+						"_id":     obj["_id"],
+						"subtype": obj["subtype"],
 					}
 				}
+
 				obj["urlpath"] = s.Uri()
 				obj["industry"] = industry
 				if ssOpenid != nil {
 					obj["ucbsId"] = util.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
 				}
+
 				s.T["obj"] = obj
 				s.T["url"] = s.Uri()
 
@@ -548,7 +551,7 @@ func CNode(userId string) bool {
 	return false
 }
 
-//查看公告详情次数限制
+// 查看公告详情次数限制
 func SeeDetailLimit(obj map[string]interface{}, userId, sid string) bool {
 	watchKey := fmt.Sprintf("article_count_%d_%s_%d_%s", time.Now().Year(), time.Now().Month(), time.Now().Day(), userId)
 	subTypeStr, _ := obj["subtype"].(string)
@@ -598,7 +601,7 @@ func SwiDef(sid_openid []string) (string, string) {
 	return shareopenid, sid
 }
 
-//user 权限获取
+// user 权限获取
 func UserPermission(userId string, ssOpenid interface{}) (bool, bool, bool) {
 	var (
 		res                                      *map[string]interface{}
@@ -626,7 +629,7 @@ func UserPermission(userId string, ssOpenid interface{}) (bool, bool, bool) {
 	return isVip, isMember, isEntniche
 }
 
-//pc 移动共用字段处理
+// pc 移动共用字段处理
 func FieldProcessing(obj map[string]interface{}, ssOpenid interface{}, industry, id, from_userid, userId, stype string, isPayUser, b bool) {
 	obj["industry"] = industry
 	if ssOpenid != nil {
@@ -637,19 +640,19 @@ func FieldProcessing(obj map[string]interface{}, ssOpenid interface{}, industry,
 		obj["buyerperson"] = ""
 		obj["buyertel"] = ""
 	}
-	if false && isbid(obj["subtype"]) {
-		//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
-		obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
-	}
-
-	if !isPayUser { //非会员不展示电话字段
-		if obj["winnertel"] != nil {
-			obj["winnertel"] = "无权限"
-		}
-		if obj["winner_enttel"] != "" {
-			obj["winner_enttel"] = "无权限"
-		}
-	}
+	/*if false && isbid(obj["subtype"]) {
+	  	//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
+	  	obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
+	  }
+
+	  if !isPayUser { //非会员不展示电话字段
+	  	if obj["winnertel"] != nil {
+	  		obj["winnertel"] = "无权限"
+	  	}
+	  	if obj["winner_enttel"] != "" {
+	  		obj["winner_enttel"] = "无权限"
+	  	}
+	  }*/
 	if !b {
 		href, _ := obj["href"].(string)
 		href = strings.Replace(href, "\n", "", -1)
@@ -699,7 +702,7 @@ func FieldProcessing(obj map[string]interface{}, ssOpenid interface{}, industry,
 	}
 }
 
-//disWord 为空时处理
+// disWord 为空时处理
 func disWordNil(disWord, userId string) string {
 	var from_userid string
 	redisDis := redis.GetStr("other", "DIS_"+disWord[1:])
@@ -741,7 +744,7 @@ func disWordNil(disWord, userId string) string {
 	return from_userid
 }
 
-//检查用户是否关注
+// 检查用户是否关注
 func CheckUserIsSubscribe(openid string) bool {
 	user, ok := mongodb.FindOneByField("user", map[string]interface{}{
 		"i_appid":    2,
@@ -805,7 +808,7 @@ func isbid(typ interface{}) bool {
 	return false
 }
 
-//中标企业库
+// 中标企业库
 func getwinnertel(company interface{}) string {
 	if company != nil {
 		data, _ := public.Mgo_Ent.FindOne("winner_enterprise", map[string]interface{}{
@@ -837,7 +840,7 @@ func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
 	return
 }
 
-//该节点是否留资
+// 该节点是否留资
 func hasRetainedCapital(uid, source string) bool {
 	if count, err := mongodb.CountByErr("saleLeads", map[string]interface{}{"userid": uid, "source": source}); err != nil || count > 0 {
 		return true

+ 57 - 18
src/jfw/front/supsearch.go

@@ -23,8 +23,7 @@ import (
 
 type Pcsearch struct {
 	*xweb.Action
-
-	pcSearchIndex   xweb.Mapper `xweb:"/jylab/supsearch/index.html"`           //搜索首页
+	pcSearchIndex   xweb.Mapper `xweb:"/jylab/(supsearch|medical)/index.html"` //搜索首页
 	getNewBids      xweb.Mapper `xweb:"/jylab/supsearch/getNewBids"`           //最新招标信息
 	getstatus       xweb.Mapper `xweb:"/jylab/supsearch/getstatus"`            //实验室开启状态
 	proposedProject xweb.Mapper `xweb:"/jylab/supsearch/proposedProject.html"` //拟建项目
@@ -32,7 +31,6 @@ type Pcsearch struct {
 	changePro       xweb.Mapper `xweb:"/jylab/changePro"`                      //修改提示信息状态
 }
 
-//
 var industrylist map[string][]string
 var sortArray []string
 var PCS_index map[string]interface{}
@@ -53,6 +51,7 @@ var (
 )
 
 //
+
 func init() {
 	xweb.AddAction(&Pcsearch{})
 	industrylist, sortArray = jy.Getindustrys(util.ObjToString(config.Sysconfig["industry"]), mongodb)
@@ -72,7 +71,7 @@ func init() {
 	}
 }
 
-//定时清理搜索列表页 从redis获取存入内存中的数据
+// 定时清理搜索列表页 从redis获取存入内存中的数据
 func PCS_task() {
 	//根据配置延迟 PCS_time 小时执行
 	sub := time.Hour * time.Duration(PCS_time)
@@ -93,7 +92,7 @@ func PCS_task() {
 
 }
 
-//返回内存中列表也的数据,只获取首页,其他页面访问量暂时不多
+// 返回内存中列表也的数据,只获取首页,其他页面访问量暂时不多
 func PCS_list(page_type string) interface{} {
 	/*var _page_type = page_type
 	  //如果page_type为空,则是获取非拟建数据。
@@ -112,7 +111,6 @@ func PCS_list(page_type string) interface{} {
 	}
 }
 
-//
 func (p *Pcsearch) ChangePro() {
 	defer util.Catch()
 	userid := p.GetSession("userId")
@@ -121,7 +119,6 @@ func (p *Pcsearch) ChangePro() {
 	}
 }
 
-//
 func (p *Pcsearch) ProposedProject() error {
 	defer util.Catch()
 	var shareid = p.GetString("id")
@@ -205,7 +202,6 @@ func (p *Pcsearch) ProposedProject() error {
 	return p.Render("/pc/proproject.html", &p.T)
 }
 
-//
 func (p *Pcsearch) Getstatus() error {
 	defer util.Catch()
 	var supstatus, entstatus, tablepro, dataexportstatus, portraitpower, followent, smartstatus bool
@@ -228,7 +224,6 @@ func (p *Pcsearch) Getstatus() error {
 	return nil
 }
 
-//
 func (p *Pcsearch) GetNewBids() error {
 	pagenum, _ := p.GetInteger("pageNumber")
 	pageType := p.GetString("pageType")
@@ -274,11 +269,21 @@ func (p *Pcsearch) GetNewBids() error {
 	return nil
 }
 
-//
-func (p *Pcsearch) PcSearchIndex() error {
+func (p *Pcsearch) PcSearchIndex(module string) error {
 	defer util.Catch()
 	p.T["logid"] = config.Seoconfig["jysslby"].(string)
-	bidField := p.GetString("bid_field") // 领域类型  医疗-0101
+
+	// 领域化标识
+	bidField := p.GetString("bid_field")
+	switch module {
+	case "medical": // 领域类型  医疗-0101
+		if bidField == "" {
+			bidField = "0101"
+		}
+	default:
+		bidField = ""
+	}
+
 	keywords := p.GetString("keywords")
 	industry := strings.TrimSpace(p.GetString("industry")) //选中的行业
 	area := p.GetString("area")                            //地区
@@ -379,7 +384,6 @@ func (p *Pcsearch) PcSearchIndex() error {
 		p.T["toptype"] = toptype
 		p.T["subtype"] = subtype
 		p.T["searchvalue"] = s_word
-		p.T["selectType"] = selectType
 		p.T["minprice"] = minprice
 		p.T["maxprice"] = maxprice
 		p.T["buyerclass"] = buyerclass
@@ -411,6 +415,7 @@ func (p *Pcsearch) PcSearchIndex() error {
 			p.SetSession("paraminfotype", toptype)
 		}
 	}
+	p.T["selectType"] = selectType
 	p.T["login"] = p.Session().Get("user")
 	p.T["count"] = count
 	p.T["totalPage"] = totalPage
@@ -420,6 +425,7 @@ func (p *Pcsearch) PcSearchIndex() error {
 	p.T["sortArray"] = sortArray
 	p.T["showVipScreen"] = isPayedUser
 	p.T["bidField"] = bidField
+	p.T["module"] = module
 	//
 	if userId != "" {
 		//企业画像 权限
@@ -428,7 +434,6 @@ func (p *Pcsearch) PcSearchIndex() error {
 	return p.Render("/pc/supsearch.html", &p.T)
 }
 
-//
 func Newbids(p string) []interface{} {
 	pages, _ := redis.Get("newother", "index_list"+p).([]interface{})
 	if len(pages) == 0 {
@@ -529,7 +534,14 @@ func duplicateRemoval(ss []map[string]interface{}) []map[string]interface{} {
 	return data
 }
 
-func top500(industry string, bidField string) (list *[]map[string]interface{}) {
+var topType = map[string]string{
+	"招标预告":   "预告",
+	"招标公告":   "招标",
+	"招标结果":   "结果",
+	"招标信用信息": "其它",
+}
+
+func top500(subtype string, bidField string) (list *[]map[string]interface{}) {
 	qstr := ""
 	if bidField != "" {
 		// 如果是领域化数据
@@ -537,17 +549,44 @@ func top500(industry string, bidField string) (list *[]map[string]interface{}) {
         {"term": {"bid_field": "%s"}}]}}}`
 		qstr = fmt.Sprintf(q, bidField)
 	} else {
-		qstr = `{"query": {"bool": {"should": [{"term": {"dataweight": 1}}]}}}`
+		var query = ``
+		qstr = `{"query": {"bool": {"must": [%s]}}}`
+		if subtype != "" {
+			var topTypes []string
+			var subTypes []string
+
+			for _, v := range strings.Split(subtype, ",") {
+				if v1, ok := topType[v]; ok {
+					topTypes = append(topTypes, fmt.Sprintf(`"%s"`, v1))
+				} else {
+					subTypes = append(subTypes, fmt.Sprintf(`"%s"`, v))
+				}
+			}
+			log.Println("信息类型搜索:", topTypes, subTypes)
+			if len(subTypes) > 0 && len(topTypes) > 0 {
+				query = fmt.Sprintf(`{"bool": {"should": [{"terms": {"subtype": [%s]}},{"terms": {"toptype": [%s]}}]}}`, strings.Join(subTypes, ","), strings.Join(topTypes, ","))
+			} else if len(subTypes) > 0 {
+				query += fmt.Sprintf(`{"terms":{"subtype":[%s]}}`, strings.Join(subTypes, ","))
+			} else if len(topTypes) > 0 {
+				query += fmt.Sprintf(`{"terms":{"toptype":[%s]}}`, strings.Join(topTypes, ","))
+			}
+		}
+		if query != `` {
+			query = query + `,` + `{"term": {"dataweight": 1}}`
+		} else {
+			query = `{"term": {"dataweight": 1}}`
+		}
+		qstr = fmt.Sprintf(qstr, query)
 	}
 	repl := elastic.GetAllByNgram(INDEX, TYPE, qstr, `"title"`, `{"publishtime":-1}`, bidSearch_field, 0, 500, 115, false)
 	if repl != nil && *repl != nil && len(*repl) > 0 {
-		public.BidListConvert(industry, repl)
+		public.BidListConvert("", repl)
 		list = repl
 	}
 	return
 }
 
-//二维码图片
+// 二维码图片
 func (p *Pcsearch) Qr(t string) error {
 	openid := p.GetSession("openid")
 	if openid == nil {

+ 8 - 15
src/jfw/front/swordfish.go

@@ -512,10 +512,10 @@ func wxvisitD(sid, userId, openId string, isPayUser bool) (objdata map[string]in
 			obj["followFlag"] = false
 			obj["hasSession"] = false
 			if userId != "" {
-				pcode, _ := obj["projectcode"].(string)
-				pname, _ := obj["projectname"].(string)
+				//pcode, _ := obj["projectcode"].(string)
+				//pname, _ := obj["projectname"].(string)
 				titleTmp := util.ObjToString(obj["title"])
-				obj["followFlag"], obj["followId"] = MFollow(userId, pname, pcode, titleTmp, openId)
+				obj["followFlag"], obj["followId"] = MFollow(userId, sid)
 				if len([]rune(titleTmp)) > 100 {
 					titleTmp = string([]rune(titleTmp)[:100]) + "..."
 				}
@@ -699,21 +699,14 @@ func getWeightRandom(array []map[string]interface{}) int {
 	return 0
 }
 
-func MFollow(userId, pname, pcode, title, openid string) (bool, string) {
+func MFollow(userId, sid string) (bool, string) {
 	defer util.Catch()
 	var followId string
 	followFlag := false
-	follows, ok := mongodb.Find("follow_project", `{"s_userid":"`+userId+`"}`, `{"_id":1,"s_projectname":1,"s_projectcode":1}`, nil, false, -1, -1)
-	if ok && follows != nil && len(*follows) > 0 {
-		for _, v := range *follows {
-			pc, _ := v["s_projectcode"].(string)
-			pn, _ := v["s_projectname"].(string)
-			if (pc != "" && pc == pcode) || (pn != "" && pn == pname) {
-				followFlag = true
-				followId = util.EncodeArticleId2ByCheck(BsonIdToSId(v["_id"]))
-				break
-			}
-		}
+	follows := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{"s_userid": userId, "s_id": sid}, "id", "")
+	if follows != nil && len(*follows) > 0 {
+		followId = util.EncodeArticleId2ByCheck(util.InterfaceToStr((*follows)["id"]))
+		followFlag = true
 	}
 	return followFlag, followId
 }

+ 81 - 0
src/jfw/jyutil/jyutil.go

@@ -11,7 +11,9 @@ import (
 	"net/http"
 	"qfw/util"
 	"qfw/util/redis"
+	"reflect"
 	"regexp"
+	"sort"
 
 	"strings"
 	"time"
@@ -122,3 +124,82 @@ func GetSessionVal(q map[string]interface{}) (*map[string]interface{}, map[strin
 func LoginRedisKey(userid string) string {
 	return fmt.Sprintf("login_%s", userid)
 }
+
+// 排序 排序键必须为数字类型
+type SortBy struct {
+	Data    []map[string]interface{}
+	Sortkey string
+}
+
+func (a SortBy) Len() int { return len(a.Data) }
+
+func (a SortBy) Swap(i, j int) {
+	a.Data[i], a.Data[j] = a.Data[j], a.Data[i]
+}
+
+func (a SortBy) Less(i, j int) bool {
+	//return Float64(a.Data[i][a.Sortkey]) < Float64(a.Data[j][a.Sortkey])
+	m := a.Data[i][a.Sortkey]
+	n := a.Data[j][a.Sortkey]
+	w := reflect.ValueOf(m)
+	v := reflect.ValueOf(n)
+	switch v.Kind() {
+	case reflect.String:
+		return w.String() < v.String()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return w.Int() < v.Int()
+	case reflect.Float64, reflect.Float32:
+		return w.Float() < v.Float()
+	default:
+		return fmt.Sprintf("%v", w) < fmt.Sprintf("%v", v)
+	}
+}
+
+// ture  倒序3, 2, 1
+//fmt.Println(m)
+func SortData(data interface{}, sortkey string, reverse bool) {
+	//func SortData(data interface{}, sortkey string, reverse bool) {
+	var db []map[string]interface{}
+	err := Bind(data, &db)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	stb := SortBy{db, sortkey}
+	if !reverse {
+		sort.Sort(stb)
+	} else {
+		sort.Sort(sort.Reverse(stb))
+	}
+	err = Bind(stb.Data, data)
+	if err != nil {
+		fmt.Println(err)
+	}
+
+}
+
+// data 转换成ret
+func Bind(data interface{}, ret interface{}) error {
+	v := reflect.ValueOf(ret)
+	if v.Kind() != reflect.Ptr {
+		return fmt.Errorf("ptr input ret needed as type as input type %s", v.Kind())
+	}
+	havdata := false
+	var bk interface{}
+	if v.Elem().Kind() == reflect.Slice {
+		t := reflect.Zero(reflect.TypeOf(v.Elem().Interface()))
+		bk = v.Elem().Interface()
+		v.Elem().Set(t)
+		havdata = true
+	}
+	_data, _ := json.MarshalIndent(data, "", "    ")
+	err := json.Unmarshal(_data, ret)
+	if err != nil {
+		fmt.Println(err)
+		if havdata {
+			v.Elem().Set(reflect.ValueOf(bk))
+		}
+		return err
+	}
+	return nil
+}

+ 10 - 18
src/jfw/modules/app/src/app/followent/followent.go

@@ -10,10 +10,10 @@ import (
 	"strings"
 
 	"github.com/go-xweb/xweb"
-	"go.mongodb.org/mongo-driver/bson/primitive"
 )
 
 var mongodb = public.MQFW
+var base = public.BaseMysql
 
 type FollowEnt struct {
 	*xweb.Action
@@ -100,30 +100,22 @@ func (f *FollowEnt) Detail(followId string) error {
 	followId = util.DecodeArticleId2ByCheck(followId)[0]
 	winner := ""
 	var a_visited interface{}
-	_id, _ := primitive.ObjectIDFromHex(followId)
-	oneQy, ok := mongodb.FindOneByField("jylab_followent", map[string]interface{}{
-		"_id":      _id,
+	oneQy := base.FindOne("follow_ent_monitor", map[string]interface{}{
+		"id":       followId,
 		"s_userid": userId,
-	}, `{"s_entname":1,"s_id":1,"a_visited":1}`)
+	}, `s_entname,s_id`, "")
 	follow := "n"
-	if !ok || oneQy == nil || len(*oneQy) == 0 {
-		oneQy, ok = mongodb.FindOneByField("jylab_followent_back", map[string]interface{}{
+	if oneQy == nil || len(*oneQy) == 0 {
+		oneQy, _ = mongodb.FindOneByField("jylab_followent_back", map[string]interface{}{
 			"s_followid": followId,
 			"s_userid":   userId,
 		}, `{"s_entname":1,"s_id":1,"a_visited":1}`)
-		if !ok || oneQy == nil || len(*oneQy) == 0 {
+		if oneQy == nil || len(*oneQy) == 0 {
 			return f.Render("_error.html")
 		}
 	} else {
 		follow = "y"
-		mongodb.UpdateById("jylab_followent", followId, map[string]interface{}{
-			"$set": map[string]interface{}{
-				"i_apppushunread": 0,
-			},
-		})
-		if (*oneQy)["a_visited"] != nil {
-			a_visited = (*oneQy)["a_visited"]
-		}
+		base.Update("follow_ent_monitor", map[string]interface{}{"id": followId}, map[string]interface{}{"i_apppushunread": 0})
 	}
 	winner = util.ObjToString((*oneQy)["s_entname"])
 	f.T["data"] = public.GetWinnerNewestDatas(winner)
@@ -134,7 +126,7 @@ func (f *FollowEnt) Detail(followId string) error {
 	return f.Render("/followent/set.html", &f.T)
 }
 
-//企业最新信息
+// 企业最新信息
 func (f *FollowEnt) NewInfo(param string) error {
 	defer util.Catch()
 	userId := util.ObjToString(f.GetSession("userId"))
@@ -157,7 +149,7 @@ func (f *FollowEnt) NewInfo(param string) error {
 	return f.Render("/followent/set.html", &f.T)
 }
 
-//取消企业关注
+// 取消企业关注
 func (f *FollowEnt) QgFollow() error {
 	defer util.Catch()
 	status := "n"

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

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

+ 850 - 760
src/jfw/modules/app/src/app/front/follow.go

@@ -1,822 +1,912 @@
 package front
 
 import (
-	"jfw/config"
-	"jfw/public"
-	"log"
-	. "mongodb"
-	"qfw/util"
-	"qfw/util/elastic"
-	"qfw/util/redis"
-	"qfw/util/rpc"
-	"strings"
-	"time"
-
-	"github.com/go-xweb/xweb"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/bson/primitive"
+    "app/jyutil"
+    "fmt"
+    "jfw/config"
+    "jfw/public"
+    "log"
+    . "mongodb"
+    "qfw/util"
+    "qfw/util/elastic"
+    "qfw/util/redis"
+    "qfw/util/rpc"
+    "strings"
+    "sync"
+    "time"
+
+    "github.com/pkg/errors"
+
+    "github.com/go-xweb/xweb"
+    "go.mongodb.org/mongo-driver/bson"
+    "go.mongodb.org/mongo-driver/bson/primitive"
 )
 
 type Follow struct {
-	*xweb.Action
-	ajaxReq       xweb.Mapper `xweb:"/jyapp/follow/ajaxReq"` //关注项目ajax请求
-	list          xweb.Mapper `xweb:"/jyapp/follow/list"`    //我关注的项目
-	getList       xweb.Mapper `xweb:"/jyapp/follow/getList"` //我关注的项目
-	add           xweb.Mapper `xweb:"/jyapp/follow/add"`     //添加关注项目
-	addsave       xweb.Mapper `xweb:"/jyapp/follow/addsave"`
-	set           xweb.Mapper `xweb:"/jyapp/follow/set/(\\w+)/([^.]*)"`
-	notice        xweb.Mapper `xweb:"/jyapp/follow/notice/([^.]+)/([^.]*)"` //项目公告
-	allNotice     xweb.Mapper `xweb:"/jyapp/follow/allNotice"`              //项目公告/(.*)
-	visited       xweb.Mapper `xweb:"/jyapp/follow/notice/visited"`
-	photo         xweb.Mapper `xweb:"/jyapp/follow/photo/(.*)"`
-	fwsave        xweb.Mapper `xweb:"/jyapp/follow/fwsave"`
-	mylist        xweb.Mapper `xweb:"/jyapp/follow/mylist"`
-	checkFPStatus xweb.Mapper `xweb:"/jyapp/follow/checkFPStatus"`
-	checkCStatus  xweb.Mapper `xweb:"/jyapp/follow/checkCStatus"`
+    *xweb.Action
+    newList       xweb.Mapper `xweb:"/jyapp/follow/list"` //我关注的项目--项目关注表合并 临时调整
+    detail        xweb.Mapper `xweb:"/jyapp/follow/set/(\\w+)/([^.]*)"`
+    ajaxReq       xweb.Mapper `xweb:"/jyapp/follow/ajaxReq"` //关注项目ajax请求
+    getList       xweb.Mapper `xweb:"/jyapp/follow/getList"` //我关注的项目
+    add           xweb.Mapper `xweb:"/jyapp/follow/add"`     //添加关注项目
+    addsave       xweb.Mapper `xweb:"/jyapp/follow/addsave"`
+    notice        xweb.Mapper `xweb:"/jyapp/follow/notice/([^.]+)/([^.]*)"` //项目公告
+    allNotice     xweb.Mapper `xweb:"/jyapp/follow/allNotice"`              //项目公告/(.*)
+    visited       xweb.Mapper `xweb:"/jyapp/follow/notice/visited"`
+    photo         xweb.Mapper `xweb:"/jyapp/follow/photo/(.*)"`
+    fwsave        xweb.Mapper `xweb:"/jyapp/follow/fwsave"`
+    mylist        xweb.Mapper `xweb:"/jyapp/follow/mylist"`
+    checkFPStatus xweb.Mapper `xweb:"/jyapp/follow/checkFPStatus"`
+    checkCStatus  xweb.Mapper `xweb:"/jyapp/follow/checkCStatus"`
+    //list          xweb.Mapper `xweb:"/jyapp/follow/list"`    //我关注的项目
+    //set           xweb.Mapper `xweb:"/jyapp/follow/set/(\\w+)/([^.]*)"`
 }
 
 var followLimit int
 
 func init() {
-	xweb.AddAction(&Follow{})
-	followLimit = util.IntAllDef(config.Sysconfig["followProject"], 10)
+    xweb.AddAction(&Follow{})
+    followLimit = util.IntAllDef(config.Sysconfig["followProject"], 10)
+}
+
+//原关注项目详情页 到大会员项目关注列表页 此处涉及到项目推送
+func (m *Follow) Detail(tp, id string) error {
+    log.Println(tp, "--", id)
+    return m.Redirect("/jyapp/big/page/pro_follow_list")
 }
 
+//非大会员用户访问关注项目-->访问大会员的项目管理路由
+func (m *Follow) NewList() error {
+    return m.Redirect("/jyapp/big/page/pro_follow_list")
+}
+
+//
 func (m *Follow) CheckFPStatus() error {
-	defer util.Catch()
-	s_id := util.DecodeArticleId2ByCheck(m.GetString("s_id"))[0]
-	follows, _ := mongodb.FindById("follow_project", s_id, `{"_id":1}`)
-	flag := "f"
-	if follows != nil && *follows != nil && len(*follows) > 0 {
-		flag = "t"
-	}
-	m.ServeJson(map[string]interface{}{
-		"flag": flag,
-	})
-	return nil
+    defer util.Catch()
+    s_id := util.DecodeArticleId2ByCheck(m.GetString("s_id"))[0]
+    userId, _ := m.GetSession("userId").(string)
+    follows := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{"s_userid": userId, "s_id": s_id}, "_id", "")
+    flag := "f"
+    if follows != nil && *follows != nil && len(*follows) > 0 {
+        flag = "t"
+    }
+    m.ServeJson(map[string]interface{}{
+        "flag": flag,
+    })
+    return nil
 }
 
 func (m *Follow) CheckCStatus() error {
-	defer util.Catch()
-	pname := m.GetString("pcname")
-	pcode := m.GetString("pccode")
-	userId, _ := m.GetSession("userId").(string)
-	flag := false
-	followid := ""
-	if userId != "" {
-		flag, followid = MFollow(userId, pname, pcode, "")
-	}
-	m.ServeJson(map[string]interface{}{
-		"flag":     flag,
-		"followid": followid,
-	})
-	return nil
+    defer util.Catch()
+    flag := false
+    followid := ""
+    if m.GetString("s_id") != "" {
+        sid := util.DecodeArticleId2ByCheck(m.GetString("s_id"))[0]
+
+        userId, _ := m.GetSession("userId").(string)
+        if userId != "" {
+            flag, followid = MFollow(userId, sid)
+        }
+    }
+    m.ServeJson(map[string]interface{}{
+        "flag":     flag,
+        "followid": followid,
+    })
+    return nil
 }
 
 //
 func (m *Follow) Mylist() {
-	defer util.Catch()
-	id := m.GetString("id")
-	id = util.DecodeArticleId2ByCheck(id)[0]
-	var flag = "F"
-	res, ok := mongodb.FindById("follow_project", id, `{"title":1}`)
-	if ok && res != nil && len(*res) > 0 {
-		flag = "T"
-	}
-	m.ServeJson(map[string]interface{}{
-		"flag": flag,
-	})
+    defer util.Catch()
+    id := m.GetString("id")
+    id = util.DecodeArticleId2ByCheck(id)[0]
+    var flag = "F"
+    res := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{"id": id}, "", "")
+    if res != nil && len(*res) > 0 {
+        flag = "T"
+    }
+    m.ServeJson(map[string]interface{}{
+        "flag": flag,
+    })
 }
 
 //关注列表关注
 func (m *Follow) Fwsave() {
-	defer util.Catch()
-	userId := m.GetSession("userId").(string)
-	var status = "n"
-	var followId string
-	s_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
-	if mongodb.Count("follow_project", `{"s_userid":"`+userId+`"}`) >= followLimit {
-		status = "m"
-	} else if mongodb.Count("follow_project", `{"s_userid":"`+userId+`","s_id":"`+s_id+`"}`) > 0 {
-		status = "e"
-	} else {
-		data := make(map[string]interface{})
-		if remind, _ := m.GetInteger("remind"); remind == 1 {
-			data["i_remind"] = 1
-		} else {
-			data["i_remind"] = 0
-		}
-		if bidopentime, err := m.GetInt("bidopentime"); err == nil {
-			data["l_bidopentime"] = bidopentime
-		}
-		if remindtime, err := m.GetInt("remindtime"); err == nil {
-			data["l_remindtime"] = remindtime
-		}
-		projectname := m.GetString("projectname")
-		data["s_projectname"] = projectname
-		data["s_userid"] = userId
-		data["l_createtime"] = time.Now().Unix()
-		data["s_title"] = projectname
-		data["s_id"] = s_id
-		data["i_source"] = 3
-		data["toptype"] = "招标"
-		fields := `"title","comeintime","bidopentime","projectcode","type","href","publishtime","area","subtype","toptype","industry","s_subscopeclass"`
-		res := elastic.GetByIdField("bidding", "bidding", s_id, fields)
-		if res != nil {
-			projectcode, _ := (*res)["projectcode"].(string)
-			data["s_projectcode"] = projectcode
-			data["s_title"] = (*res)["title"]
-			data["s_type"] = (*res)["type"]
-			data["l_publishtime"] = (*res)["publishtime"]
-			data["s_area"] = (*res)["area"]
-			data["s_url"] = (*res)["href"]
-			data["s_province"] = (*res)["area"]
-			data["l_comeintime"] = (*res)["comeintime"]
-			if data["l_bidopentime"] == "" {
-				data["l_bidopentime"] = (*res)["bidopentime"]
-			}
-			mySelf := make(bson.M)
-			mySelf["s_projectname"] = projectname
-			mySelf["s_title"] = (*res)["title"]
-			mySelf["s_projectcode"] = projectcode
-			mySelf["s_url"] = (*res)["href"]
-			mySelf["s_type"] = (*res)["type"]
-			mySelf["s_subtype"] = (*res)["subtype"]
-			mySelf["s_toptype"] = (*res)["toptype"]
-			mySelf["s_province"] = (*res)["area"]
-			mySelf["s_id"] = s_id
-			mySelf["s_eid"] = util.EncodeArticleId2ByCheck(s_id)
-			mySelf["l_publishtime"] = (*res)["publishtime"]
-			if (*res)["industry"] == nil && (*res)["s_subscopeclass"] != nil {
-				ind := strings.Split(util.ObjToString((*res)["s_subscopeclass"]), ",")[0]
-				data["s_industry"] = strings.Split(ind, "_")[0]
-				mySelf["s_industry"] = strings.Split(ind, "_")[0]
-			} else {
-				data["s_industry"] = (*res)["industry"]
-				mySelf["s_industry"] = (*res)["industry"]
-			}
-			data["a_relationinfo"] = []map[string]interface{}{mySelf}
-			if followId = mongodb.Save("follow_project", data); len(followId) > 0 {
-				status = "y"
-				go public.FollowPush(&rpc.FollowPush{
-					ProjectName: projectname,
-					ProjectCode: projectcode,
-					InfoId:      s_id,
-					FollowId:    followId,
-					UserId:      userId,
-				})
-			}
-		}
-	}
-	m.ServeJson(map[string]interface{}{
-		"status":   status,
-		"followId": util.EncodeArticleId2ByCheck(followId),
-		"infoId":   util.EncodeArticleId2ByCheck(s_id),
-	})
+    defer util.Catch()
+    userId := m.GetSession("userId").(string)
+    var status = "n"
+    var followId string
+    s_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+    if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"s_userid": userId}) >= util.Int64All(followLimit) {
+        status = "m"
+    } else if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"s_userid": userId, "s_id": s_id}) > 0 {
+        status = "e"
+    } else {
+        data := make(map[string]interface{})
+        if remind, _ := m.GetInteger("remind"); remind == 1 {
+            data["i_remind"] = 1
+        } else {
+            data["i_remind"] = 0
+        }
+        if bidopentime, err := m.GetInt("bidopentime"); err == nil {
+            data["l_bidopentime"] = bidopentime
+        }
+        if remindtime, err := m.GetInt("remindtime"); err == nil {
+            data["l_remindtime"] = remindtime
+        }
+        projectname := m.GetString("projectname")
+        //data["s_projectname"] = projectname
+        data["s_userid"] = userId
+        data["l_createtime"] = time.Now().Unix()
+        data["s_title"] = projectname
+        data["s_id"] = s_id
+        //data["i_source"] = 3
+        //data["toptype"] = "招标"
+        fields := `"title","comeintime","bidopentime","projectcode","type","href","publishtime","area","subtype","toptype","industry","s_subscopeclass"`
+        res := elastic.GetByIdField("bidding", "bidding", s_id, fields)
+        if res != nil {
+            //	projectUserKey = []string{"s_id", "s_userid", "i_remind", "l_createtime", "l_lastpushtime", "a_visited", "info_source", "s_title", "i_apppushunread", "l_bidopentime", "l_remindtime", "old_id"}
+            data["s_title"] = (*res)["title"]
+            //data["l_publishtime"] = (*res)["publishtime"]
+            data["l_comeintime"] = (*res)["comeintime"]
+            if data["l_bidopentime"] == "" {
+                data["l_bidopentime"] = (*res)["bidopentime"]
+            }
+
+            projectcode, _ := (*res)["projectcode"].(string)
+            if id := public.BaseMysql.Insert("follow_project_monitor", data); id > 0 {
+                followId = util.InterfaceToStr(id)
+                status = "y"
+                go public.FollowPush(&rpc.FollowPush{
+                    ProjectName: projectname,
+                    ProjectCode: projectcode,
+                    InfoId:      s_id,
+                    FollowId:    followId,
+                    UserId:      userId,
+                })
+            }
+        }
+    }
+    m.ServeJson(map[string]interface{}{
+        "status":   status,
+        "followId": util.EncodeArticleId2ByCheck(followId),
+        "infoId":   util.EncodeArticleId2ByCheck(s_id),
+    })
 }
 
 //未关注项目
 func (m *Follow) Photo(tp string) error {
-	defer util.Catch()
-	followid := ""
-	tpm := strings.Split(tp, "__")
-	projectname := tpm[1]
-	projectcode := tpm[2]
-	userId, _ := m.GetSession("userId").(string)
-	if userId != "" {
-		_, followid = MFollow(userId, projectname, projectcode, "")
-	}
-	//已关注
-	if followid != "" {
-		id := util.DecodeArticleId2ByCheck(followid)[0]
-		fields := `{"s_id":1,"i_source":1,"s_projectname":1,"s_projectcode":1,"s_url":1,"i_remind":1,"s_type":1,"l_bidopentime":1,"l_remindtime":1,"a_relationinfo":1,"a_visited":1,"l_lastpushtime":1,"a_lastpushids":1}`
-		_id, _ := primitive.ObjectIDFromHex(id)
-		data, ok := mongodb.FindOneByField("follow_project", map[string]interface{}{
-			"_id":      _id,
-			"s_userid": m.GetSession("userId").(string),
-		}, fields)
-		m.T["isDel"] = false
-		if ok && (data == nil || len(*data) == 0) {
-			data, ok = mongodb.FindOneByField("follow_project_back", `{"s_followid":"`+id+`"}`, fields)
-			m.T["isDel"] = true
-		}
-		if !ok || data == nil || len(*data) == 0 {
-			return m.Redirect("/jyapp/free/mob/err")
-		}
-		sid, _ := (*data)["s_id"].(string)
-		m.T["_id"] = followid
-		m.T["sid"] = util.EncodeArticleId2ByCheck(sid)
-		m.T["source"] = (*data)["i_source"]
-		m.T["projectname"] = (*data)["s_projectname"]
-		m.T["projectcode"] = (*data)["s_projectcode"]
-		m.T["url"] = (*data)["s_url"]
-		m.T["remind"] = (*data)["i_remind"]
-		m.T["type"] = (*data)["s_type"]
-		if sid != "" {
-			info := elastic.GetByIdField("bidding", "bidding", sid, `"type","subtype","toptype"`)
-			info_ok := info != nil && len(*info) != 0
-			if info_ok {
-				m.T["subtype"] = (*info)["subtype"]
-				m.T["toptype"] = (*info)["toptype"]
-				m.T["type"] = (*data)["type"]
-			}
-		}
-		res := util.ObjArrToMapArr((*data)["a_relationinfo"].([]interface{}))
-		if len(res) > 0 {
-			for _, v := range res {
-				v["s_id"] = ""
-			}
-			m.T["relationinfo"] = res
-		}
-		m.T["a_visited"] = (*data)["a_visited"]
-		m.T["l_lastpushtime"] = (*data)["l_lastpushtime"]
-		m.T["a_lastpushids"] = (*data)["a_lastpushids"]
-		l_bidopentime := (*data)["l_bidopentime"]
-		if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
-			m.T["bidopentime"] = util.FormatDateWithObj(&l_bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_bidopentime), 0).Weekday().String())
-			m.T["l_bidopentime"] = l_bidopentime
-		}
-		if l_remindtime := (*data)["l_remindtime"]; l_remindtime != nil && l_remindtime != "" && util.Int64All(l_remindtime) != 0 {
-			m.T["remindtime"] = util.FormatDateWithObj(&l_remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_remindtime), 0).Weekday().String())
-			m.T["l_remindtime"] = l_remindtime
-		} else if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
-			date := time.Unix(util.Int64All(l_bidopentime), 0).AddDate(0, 0, -1)
-			m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
-			m.T["l_remindtime"] = date.Unix()
-		}
-	} else { //未关注
-		id := util.DecodeArticleId2ByCheck(tpm[0])[0]
-		m.T["projectname"] = projectname
-		m.T["projectcode"] = projectcode
-		fields := `"_id","title","comeintime","projectcode","projectname","bidopentime","projectcode","area","toptype","subtype","type","href","publishtime","area","industry","s_subscopeclass"`
-		data := elastic.GetByIdField("bidding", "bidding", id, fields)
-		mySelf := make(bson.M)
-		if data != nil && len(*data) > 0 {
-			mySelf["s_projectname"] = projectname
-			mySelf["s_title"] = (*data)["title"]
-			mySelf["type"] = (*data)["type"]
-			mySelf["subtype"] = (*data)["subtype"]
-			mySelf["toptype"] = (*data)["toptype"]
-			mySelf["area"] = (*data)["area"]
-			mySelf["s_projectcode"] = projectcode
-			mySelf["s_url"] = (*data)["href"]
-			mySelf["s_id"] = "" //id
-			mySelf["s_eid"] = util.EncodeArticleId2ByCheck(id)
-			mySelf["l_publishtime"] = (*data)["publishtime"]
-			if (*data)["industry"] == nil && (*data)["s_subscopeclass"] != nil {
-				ind := strings.Split(util.ObjToString((*data)["s_subscopeclass"]), ",")[0]
-				(*data)["industry"] = strings.Split(ind, "_")[0]
-				mySelf["s_industry"] = strings.Split(ind, "_")[0]
-			}
-			////////////////////////
-			bidopentime := (*data)["bidopentime"]
-			if bidopentime != nil && bidopentime != "" && util.Int64All(bidopentime) != 0 {
-				m.T["bidopentime"] = util.FormatDateWithObj(&bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(bidopentime), 0).Weekday().String())
-				m.T["l_bidopentime"] = bidopentime
-			}
-			if remindtime := (*data)["remindtime"]; remindtime != nil && remindtime != "" && util.Int64All(remindtime) != 0 {
-				m.T["remindtime"] = util.FormatDateWithObj(&remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(remindtime), 0).Weekday().String())
-				m.T["l_remindtime"] = remindtime
-			} else if bidopentime != nil && bidopentime != "" && util.Int64All(bidopentime) != 0 {
-				date := time.Unix(util.Int64All(bidopentime), 0).AddDate(0, 0, -1)
-				m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
-				m.T["l_remindtime"] = date.Unix()
-			}
-			m.T["type"] = (*data)["type"]
-			m.T["subtype"] = (*data)["subtype"]
-			m.T["toptype"] = (*data)["toptype"]
-			m.T["a_lastpushids"] = (*data)["a_lastpushids"]
-		}
-		if len(projectname) > 0 || len(projectcode) > 0 {
-			res, _ := public.FollowPush(&rpc.FollowPush{
-				ProjectName: projectname,
-				ProjectCode: projectcode,
-				InfoId:      id,
-				FollowId:    "",
-				UserId:      m.GetSession("userId").(string),
-				Flag:        1,
-			})
-			if len(res) > 0 {
-				for _, v := range res {
-					(*v)["s_eid"] = util.EncodeArticleId2ByCheck((*v)["s_id"].(string))
-					(*v)["s_id"] = ""
-				}
-				m.T["data"] = res
-			}
-		}
-		m.T["id"] = util.EncodeArticleId2ByCheck(id)
-		m.T["mySelf"] = mySelf
-		m.T["source"] = 1
-	}
-	return m.Render("/weixin/follow/set.html", &m.T)
+    defer util.Catch()
+    followid := ""
+    tpm := strings.Split(tp, "__")
+    projectname := tpm[1]
+    projectcode := tpm[2]
+    userId, _ := m.GetSession("userId").(string)
+    if userId != "" {
+        _, followid = MFollow(userId, tp)
+    }
+    //已关注
+    if followid != "" {
+        id := util.DecodeArticleId2ByCheck(followid)[0]
+        fields := `{"s_id":1,"i_source":1,"s_projectname":1,"s_projectcode":1,"s_url":1,"i_remind":1,"s_type":1,"l_bidopentime":1,"l_remindtime":1,"a_relationinfo":1,"a_visited":1,"l_lastpushtime":1,"a_lastpushids":1}`
+        _id, _ := primitive.ObjectIDFromHex(id)
+        data, ok := mongodb.FindOneByField("follow_project", map[string]interface{}{
+            "_id":      _id,
+            "s_userid": m.GetSession("userId").(string),
+        }, fields)
+        m.T["isDel"] = false
+        if ok && (data == nil || len(*data) == 0) {
+            data, ok = mongodb.FindOneByField("follow_project_back", `{"s_followid":"`+id+`"}`, fields)
+            m.T["isDel"] = true
+        }
+        if !ok || data == nil || len(*data) == 0 {
+            return m.Redirect("/jyapp/free/mob/err")
+        }
+        sid, _ := (*data)["s_id"].(string)
+        m.T["_id"] = followid
+        m.T["sid"] = util.EncodeArticleId2ByCheck(sid)
+        m.T["source"] = (*data)["i_source"]
+        m.T["projectname"] = (*data)["s_projectname"]
+        m.T["projectcode"] = (*data)["s_projectcode"]
+        m.T["url"] = (*data)["s_url"]
+        m.T["remind"] = (*data)["i_remind"]
+        m.T["type"] = (*data)["s_type"]
+        if sid != "" {
+            info := elastic.GetByIdField("bidding", "bidding", sid, `"type","subtype","toptype"`)
+            info_ok := info != nil && len(*info) != 0
+            if info_ok {
+                m.T["subtype"] = (*info)["subtype"]
+                m.T["toptype"] = (*info)["toptype"]
+                m.T["type"] = (*data)["type"]
+            }
+        }
+        res := util.ObjArrToMapArr((*data)["a_relationinfo"].([]interface{}))
+        if len(res) > 0 {
+            for _, v := range res {
+                v["s_id"] = ""
+            }
+            m.T["relationinfo"] = res
+        }
+        m.T["a_visited"] = (*data)["a_visited"]
+        m.T["l_lastpushtime"] = (*data)["l_lastpushtime"]
+        m.T["a_lastpushids"] = (*data)["a_lastpushids"]
+        l_bidopentime := (*data)["l_bidopentime"]
+        if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
+            m.T["bidopentime"] = util.FormatDateWithObj(&l_bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_bidopentime), 0).Weekday().String())
+            m.T["l_bidopentime"] = l_bidopentime
+        }
+        if l_remindtime := (*data)["l_remindtime"]; l_remindtime != nil && l_remindtime != "" && util.Int64All(l_remindtime) != 0 {
+            m.T["remindtime"] = util.FormatDateWithObj(&l_remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_remindtime), 0).Weekday().String())
+            m.T["l_remindtime"] = l_remindtime
+        } else if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
+            date := time.Unix(util.Int64All(l_bidopentime), 0).AddDate(0, 0, -1)
+            m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
+            m.T["l_remindtime"] = date.Unix()
+        }
+    } else { //未关注
+        id := util.DecodeArticleId2ByCheck(tpm[0])[0]
+        m.T["projectname"] = projectname
+        m.T["projectcode"] = projectcode
+        fields := `"_id","title","comeintime","projectcode","projectname","bidopentime","projectcode","area","toptype","subtype","type","href","publishtime","area","industry","s_subscopeclass"`
+        data := elastic.GetByIdField("bidding", "bidding", id, fields)
+        mySelf := make(bson.M)
+        if data != nil && len(*data) > 0 {
+            mySelf["s_projectname"] = projectname
+            mySelf["s_title"] = (*data)["title"]
+            mySelf["type"] = (*data)["type"]
+            mySelf["subtype"] = (*data)["subtype"]
+            mySelf["toptype"] = (*data)["toptype"]
+            mySelf["area"] = (*data)["area"]
+            mySelf["s_projectcode"] = projectcode
+            mySelf["s_url"] = (*data)["href"]
+            mySelf["s_id"] = "" //id
+            mySelf["s_eid"] = util.EncodeArticleId2ByCheck(id)
+            mySelf["l_publishtime"] = (*data)["publishtime"]
+            if (*data)["industry"] == nil && (*data)["s_subscopeclass"] != nil {
+                ind := strings.Split(util.ObjToString((*data)["s_subscopeclass"]), ",")[0]
+                (*data)["industry"] = strings.Split(ind, "_")[0]
+                mySelf["s_industry"] = strings.Split(ind, "_")[0]
+            }
+            ////////////////////////
+            bidopentime := (*data)["bidopentime"]
+            if bidopentime != nil && bidopentime != "" && util.Int64All(bidopentime) != 0 {
+                m.T["bidopentime"] = util.FormatDateWithObj(&bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(bidopentime), 0).Weekday().String())
+                m.T["l_bidopentime"] = bidopentime
+            }
+            if remindtime := (*data)["remindtime"]; remindtime != nil && remindtime != "" && util.Int64All(remindtime) != 0 {
+                m.T["remindtime"] = util.FormatDateWithObj(&remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(remindtime), 0).Weekday().String())
+                m.T["l_remindtime"] = remindtime
+            } else if bidopentime != nil && bidopentime != "" && util.Int64All(bidopentime) != 0 {
+                date := time.Unix(util.Int64All(bidopentime), 0).AddDate(0, 0, -1)
+                m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
+                m.T["l_remindtime"] = date.Unix()
+            }
+            m.T["type"] = (*data)["type"]
+            m.T["subtype"] = (*data)["subtype"]
+            m.T["toptype"] = (*data)["toptype"]
+            m.T["a_lastpushids"] = (*data)["a_lastpushids"]
+        }
+        if len(projectname) > 0 || len(projectcode) > 0 {
+            res, _ := public.FollowPush(&rpc.FollowPush{
+                ProjectName: projectname,
+                ProjectCode: projectcode,
+                InfoId:      id,
+                FollowId:    "",
+                UserId:      m.GetSession("userId").(string),
+                Flag:        1,
+            })
+            if len(res) > 0 {
+                for _, v := range res {
+                    (*v)["s_eid"] = util.EncodeArticleId2ByCheck((*v)["s_id"].(string))
+                    (*v)["s_id"] = ""
+                }
+                m.T["data"] = res
+            }
+        }
+        m.T["id"] = util.EncodeArticleId2ByCheck(id)
+        m.T["mySelf"] = mySelf
+        m.T["source"] = 1
+    }
+    return m.Render("/weixin/follow/set.html", &m.T)
 }
 
 //关注项目相关的ajax请求
 func (m *Follow) AjaxReq() {
-	defer util.Catch()
-	userId := m.GetSession("userId").(string)
-	var status = "n"
-	reqType := m.GetString("reqType")
-	var followId string
-	if reqType == "follow" { //快照页面关注
-		s_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
-		if mongodb.Count("follow_project", `{"s_userid":"`+userId+`"}`) >= followLimit {
-			status = "m"
-		} else if mongodb.Count("follow_project", `{"s_userid":"`+userId+`","s_id":"`+s_id+`"}`) > 0 {
-			status = "e"
-		} else {
-			publishtime, _ := m.GetInt("publishtime")
-			projectname := m.GetString("projectname")
-			projectcode := m.GetString("projectcode")
-			url := m.GetString("url")
-			title := m.GetString("title")
-			area := m.GetString("area")
-			subtype := m.GetString("subtype")
-			toptype := m.GetString("toptype")
-			s_type := m.GetString("type")
-			s_industry := m.GetString("industry")
-			if projectname != "" || projectcode != "" {
-				data := map[string]interface{}{
-					"s_userid":      userId,
-					"s_id":          s_id,
-					"s_url":         url,
-					"s_title":       title,
-					"l_createtime":  time.Now().Unix(),
-					"i_remind":      0,
-					"l_publishtime": publishtime,
-					"i_source":      1,
-					"s_province":    area,
-					"s_area":        area,
-					"s_type":        s_type,
-					"s_industry":    s_industry,
-					"toptype":       "招标",
-				}
-				if comeintime, err := m.GetInt("comeintime"); err == nil {
-					data["l_comeintime"] = comeintime
-				}
-				if s_type := m.GetString("type"); s_type != "" {
-					data["s_type"] = s_type
-				}
-				if projectname != "" {
-					data["s_projectname"] = projectname
-				} else {
-					data["s_projectname"] = title
-				}
-				if projectcode != "" {
-					data["s_projectcode"] = projectcode
-				}
-				if bidopentime, err := m.GetInt("bidopentime"); err == nil && bidopentime > 0 {
-					data["l_bidopentime"] = bidopentime
-				}
-				//
-				mySelf := make(bson.M)
-				mySelf["s_projectcode"] = projectcode
-				mySelf["s_projectname"] = projectname
-				mySelf["s_title"] = title
-				mySelf["s_url"] = url
-				mySelf["s_id"] = s_id
-				mySelf["s_eid"] = util.EncodeArticleId2ByCheck(s_id)
-				mySelf["l_publishtime"] = publishtime
-				mySelf["s_province"] = area
-				mySelf["s_subtype"] = subtype
-				mySelf["s_toptype"] = toptype
-				mySelf["s_type"] = s_type
-				mySelf["s_industry"] = s_industry
-				//
-				data["a_relationinfo"] = []map[string]interface{}{mySelf}
-				if followId = mongodb.Save("follow_project", data); len(followId) > 0 {
-					status = "y"
-					go public.FollowPush(&rpc.FollowPush{
-						ProjectName: projectname,
-						ProjectCode: projectcode,
-						InfoId:      s_id,
-						FollowId:    followId,
-						UserId:      userId,
-					})
-				}
-			}
-		}
-	} else if reqType == "cancel" { //取消关注
-		if data, ok := mongodb.FindOne("follow_project", `{"s_userid":"`+userId+`","_id":"`+util.DecodeArticleId2ByCheck(m.GetString("id"))[0]+`"}`); ok && data != nil {
-			(*data)["s_followid"] = BsonIdToSId((*data)["_id"])
-			delete(*data, "_id")
-			(*data)["i_status"] = 1
-			mongodb.Save("follow_project_back", data)
-			if mongodb.Del("follow_project", `{"s_userid":"`+(*data)["s_userid"].(string)+`","_id":"`+util.DecodeArticleId2ByCheck(m.GetString("id"))[0]+`"}`) {
-				status = "y"
-				go delRelRedis((*data)["s_userid"], (*data)["a_relationinfo"])
-			}
-		}
-	} else if reqType == "followset" {
-		id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
-		_id, _ := primitive.ObjectIDFromHex(id)
-		if mongodb.Count("follow_project", map[string]interface{}{"_id": _id, "s_userid": userId}) == 1 {
-			data := make(map[string]interface{})
-			data["l_updatetime"] = time.Now().Unix()
-			if remind, _ := m.GetInteger("remind"); remind == 1 {
-				data["i_remind"] = 1
-			} else {
-				data["i_remind"] = 0
-			}
-			if bidopentime, err := m.GetInt("bidopentime"); err == nil {
-				data["l_bidopentime"] = bidopentime
-			}
-			if remindtime, err := m.GetInt("remindtime"); err == nil {
-				data["l_remindtime"] = remindtime
-			}
-			if mongodb.Update("follow_project", `{"_id":"`+id+`"}`, map[string]interface{}{"$set": data}, false, false) {
-				status = "y"
-			}
-		}
-	}
-	m.ServeJson(map[string]interface{}{
-		"status":   status,
-		"followId": util.EncodeArticleId2ByCheck(followId),
-	})
+    defer util.Catch()
+    userId := m.GetSession("userId").(string)
+    var status = "n"
+    reqType := m.GetString("reqType")
+    var followId string
+    if reqType == "follow" { //快照页面关注
+        s_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+        query := map[string]interface{}{
+            "s_userid": userId,
+        }
+        if public.BaseMysql.Count("follow_project_monitor", query) >= util.Int64All(followLimit) {
+            status = "m"
+        } else if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"s_userid": userId, "s_id": s_id}) > 0 {
+            status = "e"
+        } else {
+            //publishtime, _ := m.GetInt("publishtime")
+            projectname := m.GetString("projectname")
+            projectcode := m.GetString("projectcode")
+            //url := m.GetString("url")
+            title := m.GetString("title")
+            //area := m.GetString("area")
+            //subtype := m.GetString("subtype")
+            //toptype := m.GetString("toptype")
+            //s_type := m.GetString("type")
+            //s_industry := m.GetString("industry")
+            if projectname != "" || projectcode != "" {
+                data := map[string]interface{}{
+                    "s_userid": userId,
+                    "s_id":     s_id,
+                    //"s_url":         url,
+                    "s_title":      title,
+                    "l_createtime": time.Now().Unix(),
+                    "i_remind":     0,
+                    //"l_publishtime": publishtime,
+                    //"i_source":      1,
+                    //"s_province":    area,
+                    //"s_area":        area,
+                    //"s_type":        s_type,
+                    //"s_industry":    s_industry,
+                    //"toptype":       "招标",
+                }
+                /*if comeintime, err := m.GetInt("comeintime"); err == nil {
+                  	data["l_comeintime"] = comeintime
+                  }
+                  if s_type := m.GetString("type"); s_type != "" {
+                  	data["s_type"] = s_type
+                  }
+                  if projectname != "" {
+                  	data["s_projectname"] = projectname
+                  } else {
+                  	data["s_projectname"] = title
+                  }
+                  if projectcode != "" {
+                  	data["s_projectcode"] = projectcode
+                  }*/
+                if bidopentime, err := m.GetInt("bidopentime"); err == nil && bidopentime > 0 {
+                    data["l_bidopentime"] = bidopentime
+                }
+
+                if followId = util.InterfaceToStr(public.BaseMysql.Insert("follow_project_monitor", data)); len(followId) > 0 {
+                    status = "y"
+                    go public.FollowPush(&rpc.FollowPush{
+                        ProjectName: projectname,
+                        ProjectCode: projectcode,
+                        InfoId:      s_id,
+                        FollowId:    followId,
+                        UserId:      userId,
+                    })
+                }
+            }
+        }
+    } else if reqType == "cancel" { //取消关注
+        query := map[string]interface{}{
+            "s_userid": userId,
+            "id":       util.DecodeArticleId2ByCheck(m.GetString("_id"))[0],
+        }
+        if data := public.BaseMysql.FindOne("follow_project_monitor", query, "", ""); data != nil {
+            (*data)["s_followid"] = util.InterfaceToStr((*data)["id"])
+            delete(*data, "id")
+            (*data)["i_status"] = 1
+            mongodb.Save("follow_project_monitor_back", data)
+            if public.BaseMysql.Delete("follow_project_monitor", query) {
+                status = "y"
+                go delRelRedis((*data)["s_userid"], []interface{}{(*data)["s_id"]})
+            }
+        }
+    } else if reqType == "followset" {
+        id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+        if public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{"id": id, "s_userid": userId}) == 1 {
+
+            data := make(map[string]interface{})
+            data["l_updatetime"] = time.Now().Unix()
+            if remind, _ := m.GetInteger("remind"); remind == 1 {
+                data["i_remind"] = 1
+            } else {
+                data["i_remind"] = 0
+            }
+            if bidopentime, err := m.GetInt("bidopentime"); err == nil {
+                data["l_bidopentime"] = bidopentime
+            }
+            if remindtime, err := m.GetInt("remindtime"); err == nil {
+                data["l_remindtime"] = remindtime
+            }
+            if public.BaseMysql.Update("follow_project_monitor", map[string]interface{}{"id": id}, data) {
+                status = "y"
+            }
+        }
+    }
+    m.ServeJson(map[string]interface{}{
+        "status":   status,
+        "followId": util.EncodeArticleId2ByCheck(followId),
+    })
 }
 
 //我关注的项目
 func (m *Follow) List() error {
-	m.T["followLimit"] = followLimit
-	return m.Render("/weixin/follow/list.html", &m.T)
+    m.T["followLimit"] = followLimit
+    return m.Render("/weixin/follow/list.html", &m.T)
 }
 func (m *Follow) GetList() {
-	userId := util.ObjToString(m.Session().Get("userId"))
-	if userId == "" {
-		log.Println("查询我关注的项目出错,userid为空")
-	}
-	datas, ok := mongodb.Find("follow_project", `{"s_userid":"`+userId+`"}`, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"s_projectname":1,"s_projectcode":1,"i_remind":1,"l_lastpushtime":1,"l_createtime":1,"s_industry":1,"s_area":1,i_apppushunread":1}`, false, -1, -1)
-	flag := false
-	if ok && datas != nil && len(*datas) > 0 {
-		for _, v := range *datas {
-			v["followid"] = BsonIdToSId(v["_id"])
-			v["_id"] = util.EncodeArticleId2ByCheck(BsonIdToSId(v["_id"]))
-			if v["l_lastpushtime"] == "" || v["l_lastpushtime"] == nil {
-				v["l_lastpushtime"] = v["l_createtime"]
-			}
-		}
-		m.T["datas"] = datas
-		if len(*datas) >= followLimit {
-			flag = true
-		}
-	}
-	m.ServeJson(map[string]interface{}{
-		"flag": flag,
-		"list": datas,
-	})
+    userId := util.ObjToString(m.Session().Get("userId"))
+    if userId == "" {
+        log.Println("查询我关注的项目出错,userid为空")
+    }
+    log.Println(userId, "---", util.IntAll(config.Sysconfig["followProject"]))
+    datas := public.BaseMysql.SelectBySql(`SELECT * FROM follow_project_monitor WHERE s_userid =? ORDER BY l_lastpushtime,l_createtime DESC LIMIT 0,?`, userId, util.IntAll(config.Sysconfig["followProject"]))
+    log.Println("datas:", datas)
+    //datas, ok := mongodb.Find("follow_project", `{"s_userid":"`+userId+`"}`, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"s_projectname":1,"s_projectcode":1,"i_remind":1,"l_lastpushtime":1,"l_createtime":1,"s_industry":1,"s_area":1,i_apppushunread":1}`, false, -1, -1)
+    flag := false
+    var followData []map[string]interface{}
+    if datas != nil && len(*datas) > 0 {
+        sidArr := []string{}
+        followSetting := map[string]map[string]interface{}{}
+        for _, followOne := range *datas {
+            sid := util.ObjToString(followOne["s_id"])
+            if followOne["l_lastpushtime"] != nil && util.ObjToString(followOne["l_lastpushtime"]) != "" {
+                followOne["l_createtime"] = followOne["l_lastpushtime"]
+            } else if followOne["l_lastpushtime"] == nil {
+                followOne["l_lastpushtime"] = followOne["l_createtime"]
+            }
+            sidArr = append(sidArr, sid)
+            followSetting[sid] = followOne
+        }
+
+        projectInfos := []map[string]interface{}{}
+        pool := make(chan bool, 10)
+        wait := &sync.WaitGroup{}
+        var lock sync.Mutex
+        for _, v := range SplitArray(sidArr, 50) {
+            pool <- true
+            wait.Add(1)
+            go func(arr []string) error {
+                defer func() {
+                    wait.Done()
+                    <-pool
+                }()
+                //es查询
+                projectInfos_, err := getProjectsBySid(arr)
+                lock.Lock()
+                projectInfos = append(projectInfos, projectInfos_...)
+                lock.Unlock()
+                if err != nil {
+                    err = errors.New("项目信息查询异常")
+                    return err
+                }
+                return nil
+            }(v)
+        }
+        wait.Wait()
+
+        for _, projectinfo := range projectInfos { //补充设置信息
+            for _, k := range util.ObjArrToStringArr(projectinfo["ids"].([]interface{})) {
+                if info, ok := followSetting[k]; ok {
+                    info["s_area"] = projectinfo["area"]
+                    info["s_buyerclass"] = projectinfo["buyerclass"]
+                    info["s_budget"] = util.Float64All(projectinfo["budget"])
+                    info["s_title"] = projectinfo["projectname"]
+                    info["s_projectname"] = projectinfo["projectname"]
+                    info["toptype"] = projectinfo["bidstatus"]
+                    info["s_projectcode"] = projectinfo["projectcode"]
+                    if projectinfo["topscopeclass"] != nil && len(projectinfo["topscopeclass"].([]interface{})) > 0 {
+                        topscopeclass, _ := projectinfo["topscopeclass"].([]interface{})
+                        info["s_industry"] = topscopeclass[0]
+                    }
+                    break
+                }
+            }
+        }
+
+        for _, sid := range sidArr {
+            thisRow := followSetting[sid]
+            fid := util.InterfaceToStr(thisRow["id"])
+            thisRow["id"] = fid
+            if thisRow["s_title"] == nil {
+                log.Println("异常数据:", sid, fid)
+                continue
+            }
+            delete(thisRow, "s_id")
+            followData = append(followData, thisRow)
+        }
+
+        for _, v := range followData {
+            v["followid"] = util.InterfaceToStr(v["id"])
+            v["_id"] = util.EncodeArticleId2ByCheck(util.InterfaceToStr(v["id"]))
+            if v["l_lastpushtime"] == "" || v["l_lastpushtime"] == nil {
+                v["l_lastpushtime"] = v["l_createtime"]
+            }
+        }
+    }
+    m.T["datas"] = followData
+    if len(*datas) >= followLimit {
+        flag = true
+    }
+    m.ServeJson(map[string]interface{}{
+        "flag": flag,
+        "list": followData,
+    })
 }
 
 //添加关注项目
 func (m *Follow) Add() error {
-	return m.Render("/weixin/follow/add.html")
+    return m.Render("/weixin/follow/add.html")
 }
 
 //手动添加关注项目
 func (m *Follow) Addsave() error {
-	defer util.Catch()
-	var status = "n"
-	var id string
-	userId := m.GetSession("userId").(string)
-	if mongodb.Count("follow_project", `{"s_userid":"`+userId+`"}`) >= followLimit {
-		status = "m"
-	} else {
-		if projectname := m.GetString("projectname"); projectname != "" {
-			data := map[string]interface{}{
-				"s_userid":      userId,
-				"s_projectname": projectname,
-				"l_createtime":  time.Now().Unix(),
-				"i_remind":      0,
-				"s_title":       projectname,
-				"i_source":      2,
-				"toptype":       "招标",
-			}
-			//匹配
-			r := elastic.GetPage("bidding", "bidding", `{"TERM_projectname":"`+projectname+`"}`, `{"comeintime":-1}`, `"_id","title","comeintime","bidopentime","projectcode","type","href","publishtime","subtype","toptype","area","industry","s_subscopeclass"`, -1, -1)
-			var matchingFlag = r != nil && len(*r) != 0
-			var projectcode, sid string
-			if matchingFlag {
-				d := (*r)[0]
-				sid = d["_id"].(string) //(d["_id"].(bson.ObjectId)).Hex()
-				data["s_id"] = sid
-				data["l_comeintime"] = d["comeintime"]
-				publishtime := d["publishtime"]
-				data["l_publishtime"] = publishtime
-				data["s_title"] = d["title"]
-				data["s_area"] = d["area"]
-				data["s_province"] = d["area"]
-				if bidopentime := d["bidopentime"]; bidopentime != nil {
-					data["l_bidopentime"] = bidopentime
-				}
-				if d["projectcode"] != nil {
-					projectcode = d["projectcode"].(string)
-					data["s_projectcode"] = projectcode
-				}
-				if s_type := d["type"]; s_type != nil {
-					data["s_type"] = s_type
-				}
-				url := d["href"].(string)
-				data["s_url"] = url
-				//
-				mySelf := make(bson.M)
-				mySelf["s_type"] = util.ObjToString(d["type"])
-				mySelf["s_toptype"] = util.ObjToString(d["toptype"])
-				mySelf["s_subtype"] = util.ObjToString(d["subtype"])
-				mySelf["s_province"] = util.ObjToString(d["area"])
-				mySelf["s_projectname"] = projectname
-				mySelf["s_title"] = d["title"]
-				mySelf["s_projectcode"] = projectcode
-				mySelf["s_url"] = url
-				mySelf["s_id"] = sid
-				mySelf["s_eid"] = util.EncodeArticleId2ByCheck(sid)
-				mySelf["l_publishtime"] = publishtime
-				if d["industry"] == nil && d["s_subscopeclass"] != nil {
-					ind := strings.Split(util.ObjToString(d["s_subscopeclass"]), ",")[0]
-					data["s_industry"] = strings.Split(ind, "_")[0]
-					mySelf["s_industry"] = strings.Split(ind, "_")[0]
-				} else {
-					data["s_industry"] = d["industry"]
-					mySelf["s_industry"] = d["industry"]
-				}
-				data["a_relationinfo"] = []map[string]interface{}{mySelf}
-			}
-			if id = mongodb.Save("follow_project", data); len(id) > 0 {
-				status = "y"
-				go public.FollowPush(&rpc.FollowPush{
-					ProjectName: projectname,
-					ProjectCode: projectcode,
-					InfoId:      sid,
-					FollowId:    id,
-					UserId:      userId,
-				})
-			}
-		}
-	}
-	m.ServeJson(map[string]interface{}{
-		"status": status,
-		"id":     util.EncodeArticleId2ByCheck(id),
-	})
-	return nil
+    defer util.Catch()
+    var status = "n"
+    var id string
+    userId := m.GetSession("userId").(string)
+    query := map[string]interface{}{
+        "s_userid": userId,
+    }
+    if public.BaseMysql.Count("follow_project_monitor", query) >= util.Int64All(followLimit) {
+        status = "m"
+    } else {
+        //		"s_id":           sid,          //信息id
+        //		"s_userid":       this.UserId,  //用户id
+        //		"i_remind":       0,            //开标提醒
+        //		"l_createtime":   nowTimeStamp, //关注时间
+        //		"l_lastpushtime": nowTimeStamp, //关注时间
+        //		"a_visited":      "",           //浏览记录
+        if projectname := m.GetString("projectname"); projectname != "" {
+            data := map[string]interface{}{
+                "s_userid":     userId,
+                "l_createtime": time.Now().Unix(),
+                "i_remind":     0,
+                "s_title":      projectname,
+                "a_visited":    "",
+            }
+            //匹配
+            r := elastic.GetPage("bidding", "bidding", `{"TERM_projectname":"`+projectname+`"}`, `{"comeintime":-1}`, `"_id","title","comeintime","bidopentime","projectcode","type","href","publishtime","subtype","toptype","area","industry","s_subscopeclass"`, -1, -1)
+            var matchingFlag = r != nil && len(*r) != 0
+            var projectcode, sid string
+            if matchingFlag {
+                d := (*r)[0]
+                sid = d["_id"].(string) //(d["_id"].(bson.ObjectId)).Hex()
+                data["s_id"] = sid
+                publishtime := d["publishtime"]
+                data["l_lastpushtime"] = publishtime
+                data["s_title"] = d["title"]
+                if bidopentime := d["bidopentime"]; bidopentime != nil {
+                    data["l_bidopentime"] = bidopentime
+                }
+            }
+            if public.BaseMysql.Insert("follow_project_monitor", data) > 0 {
+                status = "y"
+                go public.FollowPush(&rpc.FollowPush{
+                    ProjectName: projectname,
+                    ProjectCode: projectcode,
+                    InfoId:      sid,
+                    FollowId:    id,
+                    UserId:      userId,
+                })
+            }
+        }
+    }
+    m.ServeJson(map[string]interface{}{
+        "status": status,
+        "id":     util.EncodeArticleId2ByCheck(id),
+    })
+    return nil
 }
+
+//
+func (m *Front) NewFollowDetail() error {
+    return m.Render("/weixin/follow/detail.html")
+}
+
+//
 func (m *Follow) Set(tp, id string) error {
-	defer util.Catch()
-	isDel := false
-	id = util.DecodeArticleId2ByCheck(id)[0]
-	fields := `{"s_id":1,"i_source":1,"s_projectname":1,"s_projectcode":1,"s_url":1,"i_remind":1,"s_type":1,"l_bidopentime":1,"l_remindtime":1,"a_relationinfo":1,"a_visited":1,"l_lastpushtime":1,"a_lastpushids":1}`
-	_id, _ := primitive.ObjectIDFromHex(id)
-	data, ok := mongodb.FindOneByField("follow_project", map[string]interface{}{
-		"_id":      _id,
-		"s_userid": m.GetSession("userId").(string),
-	}, fields)
-	if ok && (data == nil || len(*data) == 0) {
-		data, ok = mongodb.FindOneByField("follow_project_back", `{"s_followid":"`+id+`"}`, fields)
-		isDel = true
-	}
-	if !ok || data == nil || len(*data) == 0 {
-		return m.Redirect("/jyapp/free/mob/err")
-	}
-	sid, _ := (*data)["s_id"].(string)
-	projectname, _ := (*data)["s_projectname"].(string)
-	projectcode, _ := (*data)["s_projectcode"].(string)
-	if isDel {
-		fields := `"_id","title","comeintime","projectcode","projectname","bidopentime","projectcode","area","toptype","subtype","type","href","publishtime","area"`
-		data := elastic.GetByIdField("bidding", "bidding", sid, fields)
-		mySelf := make(bson.M)
-		if data != nil && len(*data) > 0 {
-			mySelf["s_projectname"] = projectname
-			mySelf["s_title"] = (*data)["title"]
-			mySelf["type"] = (*data)["type"]
-			mySelf["subtype"] = (*data)["subtype"]
-			mySelf["toptype"] = (*data)["toptype"]
-			mySelf["area"] = (*data)["area"]
-			mySelf["s_projectcode"] = projectcode
-			mySelf["s_url"] = (*data)["href"]
-			mySelf["s_id"] = "" //sid
-			mySelf["s_eid"] = util.EncodeArticleId2ByCheck(sid)
-			mySelf["l_publishtime"] = (*data)["publishtime"]
-			////////////////////////
-			bidopentime := (*data)["bidopentime"]
-			if bidopentime != nil && bidopentime != "" && util.Int64All(bidopentime) != 0 {
-				m.T["bidopentime"] = util.FormatDateWithObj(&bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(bidopentime), 0).Weekday().String())
-				m.T["l_bidopentime"] = bidopentime
-			}
-			if remindtime := (*data)["remindtime"]; remindtime != nil && remindtime != "" && util.Int64All(remindtime) != 0 {
-				m.T["remindtime"] = util.FormatDateWithObj(&remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(remindtime), 0).Weekday().String())
-				m.T["l_remindtime"] = remindtime
-			} else if bidopentime != nil && bidopentime != "" && util.Int64All(bidopentime) != 0 {
-				date := time.Unix(util.Int64All(bidopentime), 0).AddDate(0, 0, -1)
-				m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
-				m.T["l_remindtime"] = date.Unix()
-			}
-			m.T["type"] = (*data)["type"]
-			m.T["subtype"] = (*data)["subtype"]
-			m.T["toptype"] = (*data)["toptype"]
-			m.T["a_lastpushids"] = (*data)["a_lastpushids"]
-		}
-		if len(projectname) > 0 || len(projectcode) > 0 {
-			res, _ := public.FollowPush(&rpc.FollowPush{
-				ProjectName: projectname,
-				ProjectCode: projectcode,
-				InfoId:      sid,
-				FollowId:    "",
-				UserId:      m.GetSession("userId").(string),
-				Flag:        1,
-			})
-			if len(res) > 0 || len(mySelf) > 0 {
-				for _, v := range res {
-					(*v)["s_eid"] = util.EncodeArticleId2ByCheck((*v)["s_id"].(string))
-					(*v)["s_id"] = ""
-				}
-				m.T["data"] = res
-			}
-		}
-		m.T["id"] = util.EncodeArticleId2ByCheck(sid)
-		m.T["mySelf"] = mySelf
-	} else {
-		m.T["_id"] = util.EncodeArticleId2ByCheck(id)
-		m.T["sid"] = util.EncodeArticleId2ByCheck(sid)
-		m.T["source"] = (*data)["i_source"]
-		m.T["url"] = (*data)["s_url"]
-		m.T["remind"] = (*data)["i_remind"]
-		m.T["type"] = (*data)["s_type"]
-		if sid != "" {
-			info := elastic.GetByIdField("bidding", "bidding", sid, `"type","subtype","toptype"`)
-			info_ok := info != nil && len(*info) != 0
-			if info_ok {
-				m.T["subtype"] = (*info)["subtype"]
-				m.T["toptype"] = (*info)["toptype"]
-				m.T["type"] = (*data)["type"]
-			}
-		}
-		rela := (*data)["a_relationinfo"]
-		var res []map[string]interface{}
-		if rela != nil {
-			res = util.ObjArrToMapArr((*data)["a_relationinfo"].([]interface{}))
-		}
-		if len(res) > 0 {
-			for _, v := range res {
-				v["s_id"] = ""
-			}
-			m.T["relationinfo"] = res
-		}
-		m.T["a_visited"] = (*data)["a_visited"]
-		m.T["l_lastpushtime"] = (*data)["l_lastpushtime"]
-		m.T["a_lastpushids"] = (*data)["a_lastpushids"]
-		l_bidopentime := (*data)["l_bidopentime"]
-		if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
-			m.T["bidopentime"] = util.FormatDateWithObj(&l_bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_bidopentime), 0).Weekday().String())
-			m.T["l_bidopentime"] = l_bidopentime
-		}
-		if l_remindtime := (*data)["l_remindtime"]; l_remindtime != nil && l_remindtime != "" && util.Int64All(l_remindtime) != 0 {
-			m.T["remindtime"] = util.FormatDateWithObj(&l_remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_remindtime), 0).Weekday().String())
-			m.T["l_remindtime"] = l_remindtime
-		} else if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
-			date := time.Unix(util.Int64All(l_bidopentime), 0).AddDate(0, 0, -1)
-			m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
-			m.T["l_remindtime"] = date.Unix()
-		}
-		//
-		mongodb.UpdateById("follow_project", id, map[string]interface{}{
-			"$set": map[string]interface{}{
-				"i_apppushunread": 0,
-			},
-		})
-	}
-	m.T["projectname"] = projectname
-	m.T["projectcode"] = projectcode
-	return m.Render("/weixin/follow/set.html", &m.T)
+    defer util.Catch()
+    //isDel := false
+    var isDel bool
+    id = util.DecodeArticleId2ByCheck(id)[0]
+    //fields := `{"s_id":1,"i_source":1,"s_projectname":1,"s_projectcode":1,"s_url":1,"i_remind":1,"s_type":1,"l_bidopentime":1,"l_remindtime":1,"a_relationinfo":1,"a_visited":1,"l_lastpushtime":1,"a_lastpushids":1}`
+    //_id, _ := primitive.ObjectIDFromHex(id)
+    data := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{
+        "id":       id,
+        "s_userid": m.GetSession("userId").(string),
+    }, "", "")
+    if data == nil || len(*data) == 0 {
+        data, _ = mongodb.FindOneByField("follow_project_monitor_back", `{"s_followid":"`+id+`"}`, "")
+        isDel = true
+    }
+    if data == nil || len(*data) == 0 {
+        return m.Redirect("/jyapp/free/mob/err")
+    }
+    m.T["isDel"] = isDel
+    sid, _ := (*data)["s_id"].(string)
+
+    list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"match": {"list.infoid": "`+sid+`"}}]}},"_source":["list","projectcode","projectname","bidopentime","area","city","agency","buyer","buyerperson","buyertel","bidstatus"],"from": 0,"size": 1}`)
+    if len(*list) == 0 {
+        return m.Redirect("/jyapp/free/mob/err")
+    }
+    projectInfo := (*list)[0]
+    projectIds, _ := projectInfo["list"].([]interface{})
+    //if !ok {
+    //	return m.Redirect("/jyapp/free/mob/err")
+    //}
+    thisList := []map[string]interface{}{}
+    projectname, _ := projectInfo["projectname"].(string)
+    projectcode, _ := projectInfo["projectcode"].(string)
+
+    if sid != "" {
+        r := elastic.GetPage("bidding", "bidding", `{"TERM_projectname":"`+projectname+`"}`, `{"comeintime":-1}`, `"_id","title","comeintime","bidopentime","projectcode","type","href","publishtime","subtype","toptype","area","industry","s_subscopeclass"`, -1, -1)
+        if r != nil && len(*r) != 0 {
+            d := (*r)[0]
+            m.T["url"] = d["href"].(string)
+            if s_type := d["type"]; s_type != nil {
+                m.T["type"] = d["type"]
+                m.T["subtype"] = d["subtype"]
+                m.T["toptype"] = d["toptype"]
+            }
+        }
+    }
+
+    for _, d := range util.ObjArrToMapArr(projectIds) {
+        if len(thisList) >= 50 {
+            break
+        }
+        mySelf := make(map[string]interface{})
+        mySelf["s_type"] = util.ObjToString(d["type"])
+        mySelf["s_toptype"] = util.ObjToString(d["toptype"])
+        mySelf["s_subtype"] = util.ObjToString(d["subtype"])
+        mySelf["s_province"] = util.ObjToString(d["area"])
+        mySelf["s_projectname"] = projectname
+        mySelf["s_title"] = d["title"]
+        mySelf["s_projectcode"] = projectcode
+        mySelf["s_url"] = d["href"].(string)
+        mySelf["s_id"] = ""
+        mySelf["s_eid"] = util.EncodeArticleId2ByCheck(sid)
+        mySelf["l_publishtime"] = d["publishtime"]
+        if projectInfo["industry"] == nil && projectInfo["s_subscopeclass"] != nil {
+            ind := strings.Split(util.ObjToString(projectInfo["s_subscopeclass"]), ",")[0]
+            mySelf["s_industry"] = strings.Split(ind, "_")[0]
+        } else {
+            mySelf["s_industry"] = projectInfo["industry"]
+        }
+        thisList = append(thisList, mySelf)
+    }
+    jyutil.SortData(&thisList, "l_publishtime", true)
+    m.T["relationinfo"] = thisList
+
+    m.T["_id"] = util.EncodeArticleId2ByCheck(id)
+    m.T["sid"] = util.EncodeArticleId2ByCheck(sid)
+    //m.T["a_lastpushids"] = (*data)["ids"]
+    l_bidopentime := (*data)["l_bidopentime"]
+    if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
+        m.T["bidopentime"] = util.FormatDateWithObj(&l_bidopentime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_bidopentime), 0).Weekday().String())
+        m.T["l_bidopentime"] = l_bidopentime
+    }
+    if l_remindtime := (*data)["l_remindtime"]; l_remindtime != nil && l_remindtime != "" && util.Int64All(l_remindtime) != 0 {
+        m.T["remindtime"] = util.FormatDateWithObj(&l_remindtime, "2006年01月02日 15时") + " " + convertWeekday(time.Unix(util.Int64All(l_remindtime), 0).Weekday().String())
+        m.T["l_remindtime"] = l_remindtime
+    } else if l_bidopentime != nil && l_bidopentime != "" && util.Int64All(l_bidopentime) != 0 {
+        date := time.Unix(util.Int64All(l_bidopentime), 0).AddDate(0, 0, -1)
+        m.T["remindtime"] = util.FormatDate(&date, "2006年01月02日 15时") + " " + convertWeekday(date.Weekday().String())
+        m.T["l_remindtime"] = date.Unix()
+    }
+    if !isDel {
+        public.BaseMysql.Update("follow_project_monitor", map[string]interface{}{"id": id}, map[string]interface{}{
+            "i_apppushunread": 0,
+        })
+    }
+    m.T["a_visited"] = (*data)["a_visited"]
+    m.T["remind"] = (*data)["i_remind"]
+    m.T["l_lastpushtime"] = (*data)["l_lastpushtime"]
+    m.T["projectname"] = projectname
+    m.T["projectcode"] = projectcode
+    return m.Render("/weixin/follow/set.html", &m.T)
 }
 func (m *Follow) AllNotice() error {
-	defer util.Catch()
-	id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
-	var relationinfo []interface{}
-	fields := `{"_id":-1,"s_title":1,"s_projectcode":1,"s_projectname":1,"s_url":1,"s_id":1,"l_publishtime":1,"a_relationinfo":1,"a_visited":1,"s_id":1}`
-	data, ok := mongodb.FindById("follow_project", id, fields)
-	if ok && (data == nil || len(*data) == 0) { //以取消关注
-		data, ok = mongodb.FindOneByField("follow_project_back", `{"s_followid":"`+id+`"}`, fields)
-	}
-	if ok && data != nil {
-		if a_relationinfo := (*data)["a_relationinfo"]; a_relationinfo != nil {
-			relationinfo = a_relationinfo.([]interface{})
-			//排序
-			for x := range relationinfo {
-				for y := 0; y < len(relationinfo)-x-1; y++ {
-					dt1 := util.Int64All(relationinfo[y].(map[string]interface{})["l_publishtime"])
-					dt2 := util.Int64All(relationinfo[y+1].(map[string]interface{})["l_publishtime"])
-					if dt1 > 0 && dt2 > 0 && dt1 < dt2 {
-						temp := relationinfo[y]
-						relationinfo[y] = relationinfo[y+1]
-						relationinfo[y+1] = temp
-					}
-				}
-			}
-		}
-		(*data)["a_relationinfo"] = relationinfo
-	}
-	m.ServeJson(map[string]interface{}{
-		"data": data,
-	})
-	return nil
+    defer util.Catch()
+    id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+    var relationinfo []interface{}
+    data := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{
+        "id":       id,
+        "s_userid": m.GetSession("userId").(string),
+    }, "", "")
+    if data == nil || len(*data) == 0 {
+        data, _ = mongodb.FindOneByField("follow_project_monitor_back", `{"s_followid":"`+id+`"}`, "")
+    }
+    sid, _ := (*data)["s_id"].(string)
+    if data != nil && len(*data) > 0 {
+        thisList := []map[string]interface{}{}
+        list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"match": {"list.infoid": "`+sid+`"}}]}},"_source":["list","projectcode","projectname","bidopentime","area","city","agency","buyer","buyerperson","buyertel","bidstatus"],"from": 0,"size": 1}`)
+        projectInfo := (*list)[0]
+        relationinfo, _ = projectInfo["list"].([]interface{})
+        if relationinfo != nil {
+
+            for _, d := range util.ObjArrToMapArr(relationinfo) {
+                mySelf := make(map[string]interface{})
+                mySelf["s_type"] = util.ObjToString(d["type"])
+                mySelf["s_toptype"] = util.ObjToString(d["toptype"])
+                mySelf["s_subtype"] = util.ObjToString(d["subtype"])
+                mySelf["s_province"] = util.ObjToString(d["area"])
+                mySelf["s_projectname"] = util.ObjToString(d["projectname"])
+                mySelf["s_title"] = d["title"]
+                mySelf["s_projectcode"] = util.ObjToString(d["projectcode"])
+                mySelf["s_url"] = d["href"].(string)
+                mySelf["s_id"] = ""
+                mySelf["s_eid"] = util.EncodeArticleId2ByCheck(sid)
+                mySelf["l_publishtime"] = d["publishtime"]
+                if projectInfo["industry"] == nil && projectInfo["s_subscopeclass"] != nil {
+                    ind := strings.Split(util.ObjToString(projectInfo["s_subscopeclass"]), ",")[0]
+                    mySelf["s_industry"] = strings.Split(ind, "_")[0]
+                } else {
+                    mySelf["s_industry"] = projectInfo["industry"]
+                }
+                thisList = append(thisList, mySelf)
+            }
+            jyutil.SortData(&thisList, "l_publishtime", true)
+            //relationinfo = a_relationinfo.([]interface{})
+            //排序
+            //for x := range relationinfo {
+            //	for y := 0; y < len(relationinfo)-x-1; y++ {
+            //		dt1 := util.Int64All(relationinfo[y].(map[string]interface{})["l_publishtime"])
+            //		dt2 := util.Int64All(relationinfo[y+1].(map[string]interface{})["l_publishtime"])
+            //		if dt1 > 0 && dt2 > 0 && dt1 < dt2 {
+            //			temp := relationinfo[y]
+            //			relationinfo[y] = relationinfo[y+1]
+            //			relationinfo[y+1] = temp
+            //		}
+            //	}
+            //}
+        }
+        (*data)["a_relationinfo"] = thisList
+    }
+    m.ServeJson(map[string]interface{}{
+        "data": data,
+    })
+    return nil
 }
 func (m *Follow) Notice(id, followId string) error {
-	defer util.Catch()
-	go mongodb.UpdateById("follow_project", followId, map[string]interface{}{
-		"$set": map[string]interface{}{
-			"i_apppushunread": 0,
-		},
-	})
-	userid, _ := m.GetSession("userId").(string)
-	var query map[string]interface{}
-	if len(id) == 19 {
-		query = map[string]interface{}{
-			"l_date":     util.Int64All(id) / 1000000000,
-			"s_userid":   userid,
-			"s_followid": followId,
-		}
-	} else {
-		query = map[string]interface{}{
-			"_id":      StringTOBsonId(id),
-			"s_userid": userid,
-		}
-	}
-	data, ok := public.MQFW.FindOneByField("jy_pushproject", query, `{"s_followid":-1,"s_title":1,"s_projectcode":1,"s_projectname":1,"a_relationinfo":1,"a_visited":1}`)
-	if ok && data != nil && len(*data) > 0 {
-		if a_relationinfo := (*data)["a_relationinfo"]; a_relationinfo != nil {
-			relationinfo := a_relationinfo.([]interface{})
-			for x := range relationinfo {
-				s_id, _ := relationinfo[x].(map[string]interface{})["s_id"].(string)
-				relationinfo[x].(map[string]interface{})["s_id"] = util.EncodeArticleId2ByCheck(s_id)
-				for y := 0; y < len(relationinfo)-x-1; y++ {
-					dt1 := util.Int64All(relationinfo[y].(map[string]interface{})["l_publishtime"])
-					dt2 := util.Int64All(relationinfo[y+1].(map[string]interface{})["l_publishtime"])
-					if dt1 > 0 && dt2 > 0 && dt1 < dt2 {
-						temp := relationinfo[y]
-						relationinfo[y] = relationinfo[y+1]
-						relationinfo[y+1] = temp
-					}
-				}
-			}
-			if len(relationinfo) == 1 {
-				firstMap, _ := relationinfo[0].(map[string]interface{})
-				go public.MQFW.UpdateById("jy_pushproject", id, map[string]interface{}{
-					"$addToSet": map[string]interface{}{"a_visited": firstMap["s_id"]},
-				})
-				return m.Redirect("/jyapp/article/content/" + util.ObjToString(firstMap["s_id"]) + ".html")
-			}
-			(*data)["a_relationinfo"] = relationinfo
-		}
-		m.T["data"] = data
-	}
-	m.T["id"] = util.EncodeArticleId2ByCheck(id)
-	return m.Render("/weixin/follow/notice.html", &m.T)
+    defer util.Catch()
+    go mongodb.UpdateById("follow_project", followId, map[string]interface{}{
+        "$set": map[string]interface{}{
+            "i_apppushunread": 0,
+        },
+    })
+    userid, _ := m.GetSession("userId").(string)
+    var query map[string]interface{}
+    if len(id) == 19 {
+        query = map[string]interface{}{
+            "l_date":     util.Int64All(id) / 1000000000,
+            "s_userid":   userid,
+            "s_followid": followId,
+        }
+    } else {
+        query = map[string]interface{}{
+            "_id":      StringTOBsonId(id),
+            "s_userid": userid,
+        }
+    }
+    data, ok := public.MQFW.FindOneByField("jy_pushproject", query, `{"s_followid":-1,"s_title":1,"s_projectcode":1,"s_projectname":1,"a_relationinfo":1,"a_visited":1}`)
+    if ok && data != nil && len(*data) > 0 {
+        if a_relationinfo := (*data)["a_relationinfo"]; a_relationinfo != nil {
+            relationinfo := a_relationinfo.([]interface{})
+            for x := range relationinfo {
+                s_id, _ := relationinfo[x].(map[string]interface{})["s_id"].(string)
+                relationinfo[x].(map[string]interface{})["s_id"] = util.EncodeArticleId2ByCheck(s_id)
+                for y := 0; y < len(relationinfo)-x-1; y++ {
+                    dt1 := util.Int64All(relationinfo[y].(map[string]interface{})["l_publishtime"])
+                    dt2 := util.Int64All(relationinfo[y+1].(map[string]interface{})["l_publishtime"])
+                    if dt1 > 0 && dt2 > 0 && dt1 < dt2 {
+                        temp := relationinfo[y]
+                        relationinfo[y] = relationinfo[y+1]
+                        relationinfo[y+1] = temp
+                    }
+                }
+            }
+            if len(relationinfo) == 1 {
+                firstMap, _ := relationinfo[0].(map[string]interface{})
+                go public.MQFW.UpdateById("jy_pushproject", id, map[string]interface{}{
+                    "$addToSet": map[string]interface{}{"a_visited": firstMap["s_id"]},
+                })
+                return m.Redirect("/jyapp/article/content/" + util.ObjToString(firstMap["s_id"]) + ".html")
+            }
+            (*data)["a_relationinfo"] = relationinfo
+        }
+        m.T["data"] = data
+    }
+    m.T["id"] = util.EncodeArticleId2ByCheck(id)
+    return m.Render("/weixin/follow/notice.html", &m.T)
 }
 func (m *Follow) Visited() error {
-	defer util.Catch()
-	d_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
-	if d_id == "" {
-		return nil
-	}
-	reqType, _ := m.GetInteger("type")
-	sid := m.GetString("sid")
-	if reqType == 1 {
-		mongodb.UpdateById("follow_project", d_id, map[string]interface{}{
-			"$addToSet": map[string]interface{}{"a_visited": sid},
-		})
-	} else if reqType == 2 {
-		mongodb.UpdateById("jy_pushproject", d_id, map[string]interface{}{
-			"$addToSet": map[string]interface{}{"a_visited": sid},
-		})
-	}
-	return nil
+    defer util.Catch()
+    d_id := util.DecodeArticleId2ByCheck(m.GetString("id"))[0]
+    if d_id == "" {
+        return nil
+    }
+    reqType, _ := m.GetInteger("type")
+    sid := m.GetString("sid")
+    if reqType == 1 {
+        public.BaseMysql.Update("follow_project_monitor", map[string]interface{}{"s_id": sid}, map[string]interface{}{
+            "$addToSet": map[string]interface{}{"a_visited": sid},
+        })
+    } else if reqType == 2 {
+        mongodb.UpdateById("jy_pushproject", d_id, map[string]interface{}{
+            "$addToSet": map[string]interface{}{"a_visited": sid},
+        })
+    }
+    return nil
 }
 func convertWeekday(weekday string) string {
-	if weekday == "Sunday" {
-		weekday = "日"
-	} else if weekday == "Monday" {
-		weekday = "一"
-	} else if weekday == "Tuesday" {
-		weekday = "二"
-	} else if weekday == "Wednesday" {
-		weekday = "三"
-	} else if weekday == "Thursday" {
-		weekday = "四"
-	} else if weekday == "Friday" {
-		weekday = "五"
-	} else if weekday == "Saturday" {
-		weekday = "六"
-	}
-	return "周" + weekday
+    if weekday == "Sunday" {
+        weekday = "日"
+    } else if weekday == "Monday" {
+        weekday = "一"
+    } else if weekday == "Tuesday" {
+        weekday = "二"
+    } else if weekday == "Wednesday" {
+        weekday = "三"
+    } else if weekday == "Thursday" {
+        weekday = "四"
+    } else if weekday == "Friday" {
+        weekday = "五"
+    } else if weekday == "Saturday" {
+        weekday = "六"
+    }
+    return "周" + weekday
 }
 
 //删除redis相关数据
 func delRelRedis(userid interface{}, relationinfo interface{}) {
-	defer util.Catch()
-	uid, _ := userid.(string)
-	if uid == "" || relationinfo == nil {
-		return
-	}
-	array, _ := relationinfo.([]interface{})
-	for _, v := range util.ObjArrToMapArr(array) {
-		sid, _ := v["s_id"].(string)
-		redis.Del("push", "push_"+uid+"_"+sid)
-	}
+    defer util.Catch()
+    uid, _ := userid.(string)
+    if uid == "" || relationinfo == nil {
+        return
+    }
+    array, _ := relationinfo.([]interface{})
+    for _, v := range util.ObjArrToMapArr(array) {
+        sid, _ := v["s_id"].(string)
+        redis.Del("push", "push_"+uid+"_"+sid)
+    }
+}
+
+// SplitArray 分割数组
+func SplitArray(arr []string, num int64) [][]string {
+
+    max := int64(len(arr))
+    //判断数组大小是否小于等于指定分割大小的值,是则把原数组放入二维数组返回
+    if max <= num {
+        return [][]string{arr}
+    }
+    //获取应该数组分割为多少份
+    var quantity int64
+    if max%num == 0 {
+        quantity = max / num
+    } else {
+        quantity = (max / num) + 1
+    }
+    //声明分割好的二维数组
+    var segments = make([][]string, 0)
+    //声明分割数组的截止下标
+    var start, end, i int64
+    for i = 1; i <= quantity; i++ {
+        end = i * num
+        if i != quantity {
+            segments = append(segments, arr[start:end])
+        } else {
+            segments = append(segments, arr[start:])
+        }
+        start = i * num
+    }
+    return segments
+}
+
+//根据多个信息id查询对应的项目信息
+func getProjectsBySid(sids []string) ([]map[string]interface{}, error) {
+    sidStr := strings.Join(sids, `","`)
+    list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"terms": {"list.infoid": ["`+sidStr+`"]}}]}},"_source":["projectname","topscopeclass","_id","area","buyerclass","budget","ids","bidstatus","projectcode"],"from": 0,"size": `+fmt.Sprint(len(sids))+`}`)
+    if len(*list) == 0 {
+        return nil, errors.New("获取项目信息查询出错")
+    }
+    return *list, nil
 }

+ 14 - 29
src/jfw/modules/app/src/app/front/front.go

@@ -121,7 +121,6 @@ func (f *Front) Policy() {
 	})
 }
 
-//
 func (m *Front) Receive() error {
 	defer util.Catch()
 	url_mid := m.GetString("url")
@@ -199,7 +198,6 @@ func (m *Front) Receive() error {
 	return nil
 }
 
-//
 func mesCaLog(mid, url, userId, recType string) {
 	defer util.Catch()
 	userData, ok1 := mongodb.FindById("user", userId, `{"s_province":1,"s_city":1,"s_nickname":1}`)
@@ -293,7 +291,7 @@ func (m *Front) Feedback() error {
 	return m.Render("/weixin/feedback.html", &m.T)
 }
 
-//招标订阅向导
+// 招标订阅向导
 func (f *Front) TSGuide() error {
 	defer util.Catch()
 	userid := util.ObjToString(f.GetSession("userId"))
@@ -367,7 +365,7 @@ func (f *Front) TSGuide() error {
 	return nil
 }
 
-//查看原文中转
+// 查看原文中转
 func (f *Front) Transfer() error {
 	return f.Redirect(f.GetString("url"))
 }
@@ -390,7 +388,6 @@ func (m *Front) WxpushListInfo(_id string) error {
 	return m.Redirect("/jyapp/swordfish/historypush")
 }
 
-//
 func (f *Front) LimitSearchText() {
 	userId, _ := f.GetSession("userId").(string)
 	if userId == "" || !public.Lst.IsCanLogin(userId) {
@@ -433,7 +430,6 @@ func (f *Front) LimitSearchText() {
 	f.Write("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">" + fmt.Sprintf(public.Lst.Msg, status, public.Lst.Count, public.Lst.TimeOut, public.Lst.TotalPage))
 }
 
-//
 func (f *Front) Index() error {
 	url := f.Url()
 	redirect := "/jyapp/jylab/mainSearch"
@@ -444,12 +440,11 @@ func (f *Front) Index() error {
 	return f.Redirect(redirect)
 }
 
-//
 func (f *Front) Kicked() error {
 	return f.Redirect("/jyapp/free/login?back=index")
 }
 
-//设置js css 版本号,修改以后记得同步更新seo.json中的值
+// 设置js css 版本号,修改以后记得同步更新seo.json中的值
 func (f *Front) SetSeoVersion() {
 	//!@111qqq@! md5=51a3b7b4ed3cf140
 	if f.GetString("p") != "51a3b7b4ed3cf140" {
@@ -479,7 +474,6 @@ func (f *Front) SetSeoVersion() {
 	f.Write("当前版本号:" + mod_version + "-固定版本号:" + version)
 }
 
-//
 func (f *Front) JylabShareTimeline() {
 	userId, _ := f.GetSession("userId").(string)
 	if userId == "" {
@@ -505,7 +499,8 @@ func (f *Front) JylabShareTimeline() {
 	}
 }
 
-/**
+/*
+*
 成功分享后 更改分享相关信息
 
 shareType - 分享类型 1-详情页 2-推送列表 3-实验室
@@ -582,26 +577,16 @@ func (s *Front) ShowRedSpotOnMenu() {
 			}
 			powerMap := jy.GetBigVipUserBaseMsg(userid, public.Mysql, public.MQFW).PowerMap
 			if memberStatus > 0 && (powerMap[13] || powerMap[16]) {
-				ent = mongodb.Count("follow_entinfo_bigvip", map[string]interface{}{
+				ent = util.IntAll(public.BaseMysql.Count("follow_ent_monitor", map[string]interface{}{
 					"i_apppushunread": 1,
 					"s_userid":        uid,
-				})
-			} else {
-				ent = mongodb.Count("jylab_followent", map[string]interface{}{
-					"i_apppushunread": 1,
-					"s_userid":        uid,
-				})
+				}))
 			}
 			if memberStatus > 0 && powerMap[14] {
-				project = mongodb.Count("follow_project_bigvip", map[string]interface{}{
-					"i_apppushunread": 1,
-					"s_userid":        uid,
-				})
-			} else {
-				project = mongodb.Count("follow_project", map[string]interface{}{
+				project = util.IntAll(public.BaseMysql.Count("follow_project_monitor", map[string]interface{}{
 					"i_apppushunread": 1,
 					"s_userid":        uid,
-				})
+				}))
 			}
 		}
 		notice = mongodb.Count("jyapp_notice", map[string]interface{}{
@@ -629,12 +614,12 @@ func (s *Front) GoToUpdate() {
 	s.Render("/app/update.html")
 }
 
-//静态页面
+// 静态页面
 func (s *Front) StaticPage(pagename string) error {
 	return s.Render("/staticpage/" + pagename)
 }
 
-//商机管理推送列表 --- 下个版本删除
+// 商机管理推送列表 --- 下个版本删除
 func (s *Front) EntnichePushList() error {
 	pi := s.GetString("pi")
 	pn := s.GetString("pn")
@@ -652,7 +637,7 @@ func (s *Front) EntnichePushList() error {
 	return s.Redirect("/page_entniche/home?f=push&selectTime=" + s.GetString("selectTime"))
 }
 
-//商机管理推送
+// 商机管理推送
 func (s *Front) EntnichePush() error {
 	pi := s.GetString("pi")
 	pn := s.GetString("pn")
@@ -677,7 +662,7 @@ func (s *Front) EntnichePush() error {
 	return nil
 }
 
-//删除模板缓存
+// 删除模板缓存
 func (f *Front) Delc(url string) {
 	f.App.TemplateMgr.CacheDelete(strings.Replace(url, "GG", "/", 1))
 	f.WriteBytes([]byte("清除路径:" + url))
@@ -727,7 +712,7 @@ func (s *Front) AppConfig() {
 	s.ServeJson(config.Sysconfig["appConfig"])
 }
 
-//app微信分享域名
+// app微信分享域名
 func (s *Front) ShareDomain() {
 	s.ServeJson(config.Seoconfig["wxDomain"].(string))
 }

+ 17 - 16
src/jfw/modules/app/src/app/front/shorturl.go

@@ -142,18 +142,18 @@ func (s *Short) Article(stype, id string) error {
 				obj["winnerMap"] = winnerMap
 			}
 			s.T["userId"] = se.Encode2Hex(userId) //加密用户userid
-			if false && obj["winnertel"] == nil && isbid(obj["subtype"]) {
-				//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
-				obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
-			}
-			if !(isVip || i_member_status > 0 || isEntniche) { //非会员不展示电话字段
-				if obj["winnertel"] != nil {
-					obj["winnertel"] = "无权限"
-				}
-				if obj["winner_enttel"] != "" {
-					obj["winner_enttel"] = "无权限"
-				}
-			}
+			//if false && obj["winnertel"] == nil && isbid(obj["subtype"]) {
+			//	//bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
+			//	obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
+			//}
+			//if !(isVip || i_member_status > 0 || isEntniche) { //非会员不展示电话字段
+			//	if obj["winnertel"] != nil {
+			//		obj["winnertel"] = "无权限"
+			//	}
+			//	if obj["winner_enttel"] != "" {
+			//		obj["winner_enttel"] = "无权限"
+			//	}
+			//}
 			//判断是否公开联系人信息
 			if util.Int64All(obj["buyerhint"]) == 2 {
 				obj["buyerperson"] = ""
@@ -190,8 +190,9 @@ func (s *Short) Article(stype, id string) error {
 			}
 		} else {
 			obj = map[string]interface{}{
-				"title": obj["title"],
-				"_id":   obj["_id"],
+				"title":   obj["title"],
+				"_id":     obj["_id"],
+				"subtype": obj["subtype"],
 			}
 		}
 		s.T["rewardText"], s.T["advertText"] = getRewardText()
@@ -304,7 +305,7 @@ func TimeProcessing(hour interface{}, duration int) time.Time {
 	return t
 }
 
-//三级页复制操作记录
+// 三级页复制操作记录
 func (s *Short) Replication() {
 	mongodb.Save("copyaction", map[string]interface{}{
 		"userid":     s.GetSession("userId").(string),
@@ -366,7 +367,7 @@ func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
 	return
 }
 
-//该节点是否留资
+// 该节点是否留资
 func hasRetainedCapital(uid, source string) bool {
 	if count, err := mongodb.CountByErr("saleLeads", map[string]interface{}{"userid": uid, "source": source}); err != nil || count > 0 {
 		return true

+ 25 - 29
src/jfw/modules/app/src/app/front/swordfish.go

@@ -3,6 +3,7 @@ package front
 import (
 	_ "app/filter"
 	. "app/jyutil"
+	"fmt"
 	"jfw/config"
 	"jfw/public"
 	"log"
@@ -462,21 +463,14 @@ func (f *Front) Historypush() error {
 	return f.Render("/weixin/historypush.html", &f.T)
 }
 
-func MFollow(userId, pname, pcode, title string) (bool, string) {
+func MFollow(userId, sid string) (bool, string) {
 	defer util.Catch()
 	var followId string
 	followFlag := false
-	follows, ok := mongodb.Find("follow_project", `{"s_userid":"`+userId+`"}`, `{"_id":1,"s_projectname":1,"s_projectcode":1}`, nil, false, -1, -1)
-	if ok && follows != nil && len(*follows) > 0 {
-		for _, v := range *follows {
-			pc, _ := v["s_projectcode"].(string)
-			pn, _ := v["s_projectname"].(string)
-			if (pc != "" && pc == pcode) || (pn != "" && pn == pname) {
-				followFlag = true
-				followId = util.EncodeArticleId2ByCheck(BsonIdToSId(v["_id"]))
-				break
-			}
-		}
+	follows := public.BaseMysql.FindOne("follow_project_monitor", map[string]interface{}{"s_userid": userId, "s_id": sid}, "id", "")
+	if follows != nil && len(*follows) > 0 {
+		followId = util.EncodeArticleId2ByCheck(util.InterfaceToStr((*follows)["id"]))
+		followFlag = true
 	}
 	return followFlag, followId
 }
@@ -513,10 +507,10 @@ func wxvisitD(sid, userId string, isPayUser bool) (objdata map[string]interface{
 				delete(obj, "href")
 			}
 			if userId != "" {
-				pcode, _ := obj["projectcode"].(string)
-				pname, _ := obj["projectname"].(string)
+				//pcode, _ := obj["projectcode"].(string)
+				//pname, _ := obj["projectname"].(string)
 				titleTmp := util.ObjToString(obj["title"])
-				obj["followFlag"], obj["followId"] = MFollow(userId, pname, pcode, titleTmp)
+				obj["followFlag"], obj["followId"] = MFollow(userId, sid)
 				if len([]rune(titleTmp)) > 100 {
 					titleTmp = string([]rune(titleTmp)[:100]) + "..."
 				}
@@ -616,12 +610,7 @@ func (m *Front) DelOL() error {
 	var flag = "F"
 	var arrid = strings.Split(m.GetString("arrid"), ",")
 	log.Println("---->", arrid)
-	if len(arrid) > 0 {
-		for _, chid := range arrid {
-			_id, _ := primitive.ObjectIDFromHex(util.DecodeArticleId2ByCheck(chid)[0])
-			ids = append(ids, _id)
-		}
-	}
+
 	userId, ok := m.GetSession("userId").(string)
 	log.Println("sss", ids)
 	if !ok || userId == "" || len(ids) < 1 {
@@ -630,18 +619,25 @@ func (m *Front) DelOL() error {
 		})
 		return nil
 	}
-	if datas, ok := mongodb.Find("follow_project", bson.M{"_id": bson.M{"$in": ids}, "s_userid": m.GetSession("userId").(string)}, nil, nil, false, -1, -1); ok && datas != nil {
+	arrStr := []string{}
+	for _, v := range arrid {
+		arrStr = append(arrStr, fmt.Sprintf(`"%s"`, v))
+	}
+	idStr := fmt.Sprintf(`SELECT * FROM follow_project_monitor WHERE s_userid ="%s" and id in (%s)`, userId, strings.Join(arrStr, ","))
+
+	if datas := public.BaseMysql.SelectBySql(idStr); datas != nil {
 		for _, v := range *datas {
-			go delRelRedis(v["s_userid"], v["a_relationinfo"])
-			v["s_followid"] = BsonIdToSId(v["_id"])
-			delete(v, "_id")
+			relation := []interface{}{v["s_id"]}
+			go delRelRedis(v["s_userid"], relation)
+			v["s_followid"] = BsonIdToSId(v["id"])
+			delete(v, "id")
 			v["i_status"] = 2
-			mongodb.Save("follow_project_back", v)
+			mongodb.Save("follow_project_monitor_back", v)
 		}
 	}
-	if mongodb.Del("follow_project", bson.M{"_id": bson.M{"$in": ids}, "s_userid": m.GetSession("userId").(string)}) {
-		flag = "T"
-	}
+	delIdStr := fmt.Sprintf(`delete FROM follow_project_monitor WHERE s_userid ="%s" and id in (%s)`, userId, strings.Join(arrStr, ","))
+	public.BaseMysql.SelectBySql(delIdStr)
+	flag = "T"
 	m.ServeJson(map[string]interface{}{
 		"flag": flag,
 	})

+ 82 - 0
src/jfw/modules/app/src/app/jyutil/util.go

@@ -1,10 +1,13 @@
 package jyutil
 
 import (
+	"encoding/json"
 	. "jfw/config"
 	"jfw/public"
 	"qfw/util"
+	"reflect"
 	"regexp"
+	"sort"
 
 	"github.com/go-xweb/xweb"
 
@@ -97,3 +100,82 @@ func IosExamInfo(a *xweb.Action, vip, ent bool) (bool, bool, bool, bool) {
 	}
 	return iosExam_flag, isExamPhone, isVip, isEnt
 }
+
+// 排序 排序键必须为数字类型
+type SortBy struct {
+	Data    []map[string]interface{}
+	Sortkey string
+}
+
+func (a SortBy) Len() int { return len(a.Data) }
+
+func (a SortBy) Swap(i, j int) {
+	a.Data[i], a.Data[j] = a.Data[j], a.Data[i]
+}
+
+func (a SortBy) Less(i, j int) bool {
+	//return Float64(a.Data[i][a.Sortkey]) < Float64(a.Data[j][a.Sortkey])
+	m := a.Data[i][a.Sortkey]
+	n := a.Data[j][a.Sortkey]
+	w := reflect.ValueOf(m)
+	v := reflect.ValueOf(n)
+	switch v.Kind() {
+	case reflect.String:
+		return w.String() < v.String()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return w.Int() < v.Int()
+	case reflect.Float64, reflect.Float32:
+		return w.Float() < v.Float()
+	default:
+		return fmt.Sprintf("%v", w) < fmt.Sprintf("%v", v)
+	}
+}
+
+// ture  倒序3, 2, 1
+//fmt.Println(m)
+func SortData(data interface{}, sortkey string, reverse bool) {
+	//func SortData(data interface{}, sortkey string, reverse bool) {
+	var db []map[string]interface{}
+	err := Bind(data, &db)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	stb := SortBy{db, sortkey}
+	if !reverse {
+		sort.Sort(stb)
+	} else {
+		sort.Sort(sort.Reverse(stb))
+	}
+	err = Bind(stb.Data, data)
+	if err != nil {
+		fmt.Println(err)
+	}
+
+}
+
+// data 转换成ret
+func Bind(data interface{}, ret interface{}) error {
+	v := reflect.ValueOf(ret)
+	if v.Kind() != reflect.Ptr {
+		return fmt.Errorf("ptr input ret needed as type as input type %s", v.Kind())
+	}
+	havdata := false
+	var bk interface{}
+	if v.Elem().Kind() == reflect.Slice {
+		t := reflect.Zero(reflect.TypeOf(v.Elem().Interface()))
+		bk = v.Elem().Interface()
+		v.Elem().Set(t)
+		havdata = true
+	}
+	_data, _ := json.MarshalIndent(data, "", "    ")
+	err := json.Unmarshal(_data, ret)
+	if err != nil {
+		fmt.Println(err)
+		if havdata {
+			v.Elem().Set(reflect.ValueOf(bk))
+		}
+		return err
+	}
+	return nil
+}

+ 2 - 1
src/jfw/modules/app/src/config.json

@@ -166,5 +166,6 @@
     "smsServiceRpc":"127.0.0.1:932",
     "searchTypeSwitch": true,
     "baseUserFilterFlag":true,
-    "userCenterApi":"https://web-zxl.jydev.jianyu360.com"
+    "userCenterApi":"https://web-zxl.jydev.jianyu360.com",
+    "freeProjectFocus": 10
 }

+ 10 - 2
src/jfw/modules/app/src/db.json

@@ -56,6 +56,14 @@
 	        "passWord": "Topnet123",
 			"maxOpenConns": 2,
 			"maxIdleConns": 2
-	    }
+	    },
+      "base": {
+        "dBName": "base_service",
+        "address": "192.168.3.217:4000",
+        "userName": "root",
+        "passWord": "=PDT49#80Z!RVv52_z",
+        "maxOpenConns": 5,
+        "maxIdleConns": 5
+      }
     }
-}
+}

+ 1 - 0
src/jfw/modules/app/src/main.go

@@ -12,6 +12,7 @@ import (
 	"jfw/public"
 	"net/http"
 	"qfw/util"
+
 	_ "qfw/util/jylog" //日志文件
 	"strings"
 	"time"

+ 2 - 2
src/jfw/modules/app/src/seo.json

@@ -1,4 +1,4 @@
-{	
+{
 	"cdn":"http://web-jydev-ws.jianyu360.cn",
 	"cdns":{
 	 	"web-jydev-ws.jianyu360.cn":""
@@ -15,7 +15,7 @@
             "title": "招标搜索结果_剑鱼标讯,全行业招标信息智能推送领导者!"
         }
     },
-	"version":"1439",
+	"version":"1444",
 	"mod_version":"5008",
 	"industry":{
 		"JZGC":{"NAME":"建筑工程_勘察设计,建筑工程_工程施工,建筑工程_监理咨询,建筑工程_材料设备,建筑工程_机电安装",

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

@@ -154,7 +154,7 @@ input::placeholder {
     background-color: #f2f3f5;
 }
 
-/* 
+/*
     border-line-t 0.5px上边框
     border-line-b 0.5px下边框
 */
@@ -577,3 +577,53 @@ button[disabled] {
 .visited .visited-ft.visited-tag {
     background-color: #F7F9F9;
 }
+
+/**/
+.j-container .freeShow {
+  display: flex;
+  align-items: center;
+  padding: 0 16px;
+  width: 100%;
+  height: 64px;
+  box-sizing: border-box;
+  background: #F5F6F7;
+}
+.j-container .freeShow .purchase_in {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 0 12px;
+  width: 100%;
+  height: 44px;
+  background: url('/jyapp/big-member/image/purchase_bg.jpg') no-repeat;
+  background-size: 100% 100%;
+  border-radius: 8px;
+  box-sizing: border-box;
+}
+.j-container .freeShow .purchase_in .pur_text {
+  font-size: 0.3rem;
+}
+.j-container .freeShow .purchase_in .pur_btn {
+  padding: 3px 12px;
+  line-height: 18px;
+  text-align: center;
+  background: linear-gradient(113.06deg, #3E3E52 0%, #2F2F3D 100%);
+  font-size: 12px;
+  color: #FAE7CA;
+  border-radius: 32px;
+}
+.j-main .tip {
+  font-size: 14px;
+  padding: 5px 20px;
+  margin-bottom: 20px;
+}
+.j-main .tip img {
+  margin-right: 10px;
+  height: 19.5px;
+  width: 19.5px;
+  vertical-align: sub;
+}
+.j-main .tip front {
+  margin-left: 10px;
+  color: #a0a0a0;
+}

+ 4 - 1
src/jfw/modules/app/src/web/staticres/jyapp/css/dev2/superSearch.css

@@ -10,6 +10,9 @@
     background-color: #fff;
 	padding: 2px 5px;
 }
+#searchInner #whole.active {
+  background-color: transparent;
+}
 #searchInner .active{
 	background-color: #2cb7ca;
 }
@@ -62,4 +65,4 @@
     text-align: center;
     padding-top: 30px;
     margin-bottom: 60px;
-}
+}

+ 7 - 0
src/jfw/modules/app/src/web/staticres/jyapp/invoice/css/invoicing.css

@@ -217,3 +217,10 @@ input:disabled{
 .jy-alert .weui-dialog__bd{
   text-align: justify;
 }
+
+.hide-icon .weui-icon_toast {
+  display: none;
+}
+.hide-icon .weui-toast__content {
+  margin: 0;
+}

+ 1 - 1
src/jfw/modules/app/src/web/staticres/jyapp/js/common.js

@@ -684,7 +684,7 @@ $(function () {
   } catch (e) {
   }
   //	}
-  setInterval(function () {
+  window.checkTabTimerId = setInterval(function () {
     if (localStorage.chooseTab != undefined) {
       try {
         JyObj.hiddenBottom("1");

+ 15 - 14
src/jfw/modules/app/src/web/staticres/jyapp/me/js/mine.js

@@ -124,12 +124,8 @@ var mine = {
         // 项目关注跳转
         $('.project-follow').on('click', function (e) {
             setLiActive(e.currentTarget)
-            if(entUserInfo.isNew) {
-              location.href = '/jyapp/big/page/client_follow_list'
-            } else {
-              var url = $(this).attr('data-href')
-              autoLogin(url) 
-            }
+            var url = $(this).attr('data-href')
+            autoLogin(url) 
         })
 
         // 我的企业跳转
@@ -343,7 +339,11 @@ var mine = {
     setBigVipState: function () {
         // 设置企业关注->企业情报
         var power = pageUserInfo.power || []
-
+        if(entUserInfo.isNew) {
+            $('.project-follow').attr('data-href', '/jyapp/big/page/client_follow_list')
+        } else {
+ 			$('.project-follow').attr('data-href', '/jyapp/big/page/pro_follow_list')
+		}
         if ($.isArray(power)) {
             // 企业情报-4,12,13
             var hasEntFollowVipPower = power.indexOf(4) != -1 || power.indexOf(12) != -1 || power.indexOf(13) != -1
@@ -353,16 +353,17 @@ var mine = {
                 $('.ent-follow').attr('data-href', '/jyapp/followent/entList').find('.label').text('企业关注')
             }
 
-            var hasProjectFollowVipPower = power.indexOf(14) != -1
-            if (hasProjectFollowVipPower) {
-                $('.project-follow').attr('data-href', '/jyapp/big/page/pro_follow_list')
-            } else {
-                $('.project-follow').attr('data-href', '/jyapp/follow/list')
-            }
+			//工作桌面需求 除商机管理 其他用户关注项目 都到 大会员项目关注页面
+            //var hasProjectFollowVipPower = power.indexOf(14) != -1
+            //if (hasProjectFollowVipPower) {
+            //    $('.project-follow').attr('data-href', '/jyapp/big/page/pro_follow_list')
+            //} else {
+            //    $('.project-follow').attr('data-href', '/jyapp/follow/list')
+            //}
         } else {
             // 普通用户的设置
             $('.ent-follow').attr('data-href', '/jyapp/followent/entList').find('.label').text('企业关注')
-            $('.project-follow').attr('data-href', '/jyapp/follow/list')
+            //$('.project-follow').attr('data-href', '/jyapp/follow/list')
         }
         // 设置大会员图标
         this.setBigVipPic()

+ 1 - 1
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_order_detail.css

@@ -375,7 +375,7 @@ margin-bottom:.38rem;
   flex-direction:column;
 }
 .nothing img{
-  width: 120px;
+  width: 180px;
 }
 .nothingDiv {
 	padding-top:0.42rem;

+ 36 - 14
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_order_detail.js

@@ -15,10 +15,15 @@ $(function () {
         $("body").css("visibility", "");
         var discount_price = 0;
         if (r.success) {
-            if (r.data.order.order_status == -1) {
+            // backend删除订单
+            if (r.data.order.del_status === 1 || r.data.order.order_status == -1) {
                 $(".nothing").show();
                 $('.j-header').addClass('bgc-f').find('.header-title').text('我的订单')
                 $(".j-body").remove();
+                $('.j-footer').remove()
+                if (r.data.order.del_status === 1) {
+                    $('.nothingDiv').text('该订单已删除,如有问题请联系您的客户经理。')
+                }
             }
             //下单时间
             if (r.data.order.create_time) {
@@ -57,21 +62,31 @@ $(function () {
                 }
                 var newbuyset = filterObj.newBuyset;
                 var give_type = filterObj.give_type;//时间类型:1/天、2/月
-                var marketing=false;
-                if (give_type!=undefined && give_type>0){
-                  marketing=true;
-                }
+                var seller_give_type = filterObj.seller_give_type;//时间类型:1/天、2/月
                 // 双11活动判断
                 var can1111 = filterObj && filterObj.original_price
-                if (can1111||marketing) {
+                if (can1111 || give_type > 0 || seller_give_type > 0) {
                     var giveTime = filterObj.give_cycle
-                    if(give_type==1){
-                       giveTime=giveTime+"天";
-                    }else{
-                       giveTime = giveTime < 12 ? (giveTime + '个月') : ('1年');
+                    var sellerGiveTime = filterObj.seller_give_cycle
+                    if (giveTime) {
+                      if(give_type==1){
+                        giveTime=giveTime+"天";
+                      }else{
+                        giveTime = giveTime < 12 ? (giveTime + '个月') : ('1年');
+                      }
+                      $(".discount-container .highlight-text").text('活动赠' + giveTime);
+                      $(".discount-container").removeClass("hide");
                     }
-                    $(".discount-container .highlight-text").text('赠送' + giveTime);
-                    $(".discount-container").removeClass("hide");
+                    if (sellerGiveTime) {
+                      if(seller_give_type==1){
+                        sellerGiveTime=sellerGiveTime+"天";
+                      }else{
+                        sellerGiveTime = sellerGiveTime < 12 ? (sellerGiveTime + '个月') : ('1年');
+                      }
+                      $(".discount-container-seller .highlight-text").text('销售赠' + sellerGiveTime);
+                      $(".discount-container-seller").removeClass("hide");
+                    }
+                    
                     if (filterObj.original_price!=undefined){
 	                    var originPrice = formatMoney(parseFloat(filterObj.original_price) / 100)
 	                    $(".price-num").text(originPrice);
@@ -319,10 +334,11 @@ $(function () {
                 var downtime = r.data.order.order_countdown.split("h")[0]
                 downtime = downtime * 60 * 60 * 1000
                 var create_unix = new Date(order_create_time).getTime()
+                var expiration_time = r.data.order.expiration_time // 优惠支付结束时间
                 var t = setInterval(() => {
                     var nowtime = new Date()  //获取当前时间
                     endtime = new Date(order_create_time);  //定义结束时间
-                    var lefttime = endtime.getTime() + downtime - nowtime.getTime() //距离结束时间的毫秒数
+                    var lefttime = expiration_time ? new Date(expiration_time.replace(/-/g, '/')).getTime() - nowtime.getTime() : endtime.getTime() + downtime - nowtime.getTime() //距离结束时间的毫秒数
                     if (Math.floor(lefttime % 1000) <= 0) {
                         clearInterval(t)
                         $.ajax({
@@ -340,6 +356,8 @@ $(function () {
                                 $(".remaining").text("")
                                 $(".nopay-bg").removeClass("nopay-bg").addClass("cancel-bg")
                                 $(".j-footer").hide()
+                                $(".discountPrice").parent().hide();
+                                $('.payPrice').parent().hide();
                             }
                         })
                     } else {
@@ -428,7 +446,9 @@ $(function () {
                     $(".line_transaction").css("display", "");
                     $(".transaction_id").text(r.data.transaction_id);
                 }
-                if (r.data.order.is_backstage_order!==1){
+
+                // 后台渠道为xdqd04(销售代下单)可以开发票,其他后台创建订单不可以开发票
+                if (r.data.order.is_backstage_order!==1 || r.data.order.order_channel === 'xdqd04'){
                     var pay_again = ""
                     //发票
                     if (r.data.order.applybill_status === 0) {
@@ -719,6 +739,8 @@ $(function () {
         return months;
     }
 
+    // 移除检查客户端检查tab的定时器
+    clearInterval(window.checkTabTimerId)
 })
 var orderCode_ = decodeURIComponent(getParam("orderCode"));
 

+ 23 - 88
src/jfw/modules/app/src/web/templates/big-member/page_client_follow_list.html

@@ -304,100 +304,35 @@
             filterList: function(val, client, area) {
               let _this = this
               let newlist = []
-              let obj = {
-                area: false,
-                client: false,
-                val: false
-              }
-              if(Object.keys(area).length != 0) {
-                obj.area = true
-              }
-              if(client !== 0) {
-                obj.client = true
-              }
-              if(val != '') {
-                obj.val = true
-              }
-              let objArr = []
-              Object.keys(obj).forEach(function(sum) {
-                if(obj[sum]) {
-                  objArr.push(sum)
-                }
-              })
-              let a = objArr.indexOf('area')
-              let b = objArr.indexOf('client')
-              let c = objArr.indexOf('val')
-              if(a>=0 && b>=0 && c>=0) {
-                this.list.filter(function(item) {
-                  // 地区
-                  area.forEach(function(res) {
-                    if(item.area == res && client == item.isClaim && item.title.indexOf(val) !== -1) {
-                      newlist.push(item)
-                    }
-                  })
-                  // 认领
-                  if(client == 0) {
-                    newlist = _this.newList
-                  } else {
-                    if(client == item.isClaim) {
-                      newlist.push(item)
-                    }
-                  }
-                  // 关键词
-                  if(val == '') {
-
-                  } else {
-                    if(item.title.indexOf(val) !== -1) {
-                      newlist.push(item)
-                    }
-                  }
-                })
-              } else if(a>=0 && b>= 0 && c< 0) {
-                this.list.filter(function(item) {
-                  // 地区
-                  area.forEach(function(res) {
-                    if(item.area == res && client == item.isClaim) {
-                      newlist.push(item)
-                    }
-                  })
-                })
-              } else if(a<0 &&b>= 0 && c< 0) {
-                this.list.filter(function(item) {
-                  if(client == item.isClaim && item.title.indexOf(val) !== -1) {
-                    newlist.push(item)
-                  }
-                })
-              } else if (a>=0 && b< 0 && c>= 0) {
-                this.list.filter(function(item) {
-                  area.forEach(function(res) {
-                    if(item.area == res && item.title.indexOf(val) !== -1) {
-                      newlist.push(item)
-                    }
-                  })
-                })
-              } else if (a>=0 && b< 0 && c< 0) {
-                this.list.filter(function(item) {
+              this.list.forEach(function(item){
+                let areaBool = area.length===0
+                let clintBool = client===0
+                let valBool = val===""
+                //地区选择
+                if (area.length>0){
                   area.forEach(function(res) {
                     if(item.area == res) {
-                      newlist.push(item)
+                      areaBool = true
+                      return true
                     }
                   })
-                })
-              } else if (a<0 && b< 0 && c>= 0) {
-                this.list.filter(function(item) {
-                  if(item.title.indexOf(val) !== -1) {
-                    newlist.push(item)
-                  }
-                })
-              } else if (a<0 && b>= 0 && c< 0) {
-                this.list.filter(function(item) {
+                }
+                //认领
+                if (client>0){
                   if(client == item.isClaim) {
-                    newlist.push(item)
+                    clintBool = true
                   }
-                })
-              } else {
-                newlist = this.newList
-              }
+                }
+                //关键词
+                if (val!=""){
+                  if(item.title.indexOf(val) !== -1) {
+                    valBool = true
+                  }
+                }
+                if (areaBool&&clintBool&&valBool){
+                   newlist.push(item)
+                }
+              })
               this.list = newlist
               console.log(this.list)
             },

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

@@ -10,8 +10,8 @@
     <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
     <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
     <link rel="preload" as="style" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
-    <link rel="preload" as="style"
-          href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/page_pro_follow_detail.css?v={{Msg "seo" "version"}}'/>
+<!--    <link rel="preload" as="style"
+          href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/page_pro_follow_detail.css?v={{Msg "seo" "version"}}'/> 重复请求-->
     <!--E-当前页必定需要预加载的资源-->
 
     <!--S-当前页面的css资源-->
@@ -761,4 +761,4 @@
 </script>
 
 </body>
-</html>
+</html>

+ 25 - 8
src/jfw/modules/app/src/web/templates/big-member/page_pro_follow_list.html

@@ -34,6 +34,12 @@
             </div>
         </div>
         <div class="j-container" v-if="!foShow">
+            <div class="freeShow" v-if="!isbigvip">
+              <div class="purchase_in">
+                <div class="pur_text">购买大会员,最多关注500个项目</div>
+                <div class="pur_btn" @click="toBuy()">立即购买</div>
+              </div>
+            </div>
             <div class="j-main havefomain" ref="jList">
                 <van-list
                     v-model="loading"
@@ -58,6 +64,9 @@
                         </div>
                     </div>
                 </van-list>
+                <div class="tip" v-if="!isbigvip">
+                  <img src="/jyapp/images/wx/jyprompt.png?v=2155">剑鱼标讯提示:<front>可关注10个项目</front>
+                </div>
             </div>
             <div class="j-footer">
                 <div class="j-button-group">
@@ -100,6 +109,7 @@
             fid:'',//关注后的加密id
             isbigvip:false, // 是否是大会员
             pageNum:0,
+            isFree:false
         },
         created () {
             var recover = this.recover()
@@ -136,15 +146,19 @@
             },
             // 判断是否开通大会员
             isOpening:function() {
+              var _this = this
                 $.ajax({
                     type:'POST',
-                    url:'/bigmember/use/isAdd',
+                    url:'/bigmember/use/isAdd?t='+Date.now(),
                     data:{},
                     success: function(res) {
-                        if(res.data.memberStatus<=0){
-                            this.isbigvip = true
+                        if(res.data.isFree){
+                          _this.isFree = true
+                        }
+                        if(res.data.memberStatus>0){
+                          _this.isbigvip = true
                         }else{
-                            this.isbigvip = false
+                          _this.isbigvip = false
                         }
                     }
                 })
@@ -166,10 +180,10 @@
                         url:'/bigmember/follow/project/remove30Day',
                         data:{},
                         success:function(res) {
-                            if(res.data.removeNum == 0) {
-                                this.vant.Toast('暂无30天无更新的数据可删除')
+                            if(res.data.removeNum === 0) {
+                                vant.Toast('暂无30天无更新的数据可删除')
                             }else{
-                                this.vant.Toast('删除成功')
+                                vant.Toast('删除成功')
                                 location.reload()
                             }
                         },
@@ -209,7 +223,7 @@
                                     try {
                                         res.data.List[i].visited = visitedPath.pathVisited(
                                             new VisitedPathItem(
-                                                '/jyapp/big/page/client_follow_detail',
+                                                '/jyapp/big/page/pro_follow_detail',
                                                 `sid=${res.data.List[i].sid}`
                                             )
                                         )
@@ -311,6 +325,9 @@
                     td = minutes + "分钟前";
                 }
                 return td;
+            },
+            toBuy:function () {
+              location.href = '/jyapp/big/page/landingPage'
             }
         }
     }

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

@@ -83,6 +83,7 @@
                                                 <div class="p-num">&yen; ${ item.payPrice }</div>
                                             </div>
                                         </div>
+                                        <div class="limited-countdown" v-if="item.countDown > serverInitTime && item.order_status == 0" v-text="'限时抢购支付倒计时 ' + diffCountdown(item)"> </div>
                                         <div class="o-i-f-button-group">
                                             <button
                                                     class="order-action-button click-active cancel-order"

+ 17 - 14
src/jfw/modules/app/src/web/templates/followent/add.html

@@ -69,7 +69,7 @@
                 $(".opation").addClass("disabled");
                 $("#recList").hide();
             }else{
-                $(".opation").removeClass("disabled");
+                // $(".opation").removeClass("disabled");
                 getRecList(this.value);
             }
         });
@@ -84,20 +84,23 @@
                 return;
             }
             $(this).addClass("disabled");
-            $.post("/jyapp/followent/addfwent",{winner:entName,id:winner_id},function(r){
-                if(r.status == "y" || r.status == "e"){
+            $.post("/bigmember/follow/ent/addFollow",{group:"A",entId:winner_id},function(r){
+                if(r.data == "success" && r.error_code == 0){
                     if(sessionStorage){
                         sessionStorage.version="1";
                     }
                     //window.location.href = "/followeEnt/set/add/"+r.id;
                     //window.location.href = "/jyapp/followent/entList";
-					window.history.back();
-                }else if(r.status == "m"){
-                    EasyAlert.show("最多可关注<br>10个企业!");
+					          window.history.back();
                 }else{
-                    EasyAlert.show("数据提交失败!");
-                    $(".opation").removeClass("disabled");
-                }
+                      EasyAlert.show(r.error_msg);
+                  }
+                // else if(r.status == "m"){
+                //     EasyAlert.show("最多可关注<br>10个企业!");
+                // }else{
+                //     EasyAlert.show("数据提交失败!");
+                //     $(".opation").removeClass("disabled");
+                // }
             });
         });
     });
@@ -105,13 +108,13 @@
 	function getRecList(entName_key) {
 		$("#recList").html("");
     if(getRecListXHR) getRecListXHR.abort();//取消请求响应
-		getRecListXHR=$.post("/jyapp/followent/recList",{entName:entName_key},function(r){
+		getRecListXHR=$.post("/bigmember/follow/ent/association",{entName:entName_key},function(r){
 			if(r){
-				if(typeof(r.recList)!="undefined" && r.recList != null && r.recList.length > 0){
-					var recList = r.recList;
+				if(typeof(r.data)!="undefined" && r.data != null && r.data.length > 0){
+					var recList = r.data;
 					for(var i=0;i<recList.length;i++){
-					    var entName = recList[i].name;
-					    var id = recList[i]._id;
+					    var entName = recList[i].entName;
+					    var id = recList[i].entId;
 						if(entName!="" && entName.length>20){
 							entName = entName.substr(0,20)+"...";
 						}

+ 8 - 7
src/jfw/modules/app/src/web/templates/followent/list.html

@@ -24,18 +24,19 @@
 	$(function () {
 		new FastClick(document.body);
         var followEntLimit = {{.T.followEntLimit}};
-		$.post("/jyapp/followent/getEntList?t="+new Date().getTime(),null,function(r){
+		$.post("/bigmember/follow/ent/list?t="+new Date().getTime(),null,function(r){
+      const res = r.data
 			$("#addDiv").click(function(){
-				if(r.flag){
+				if(res.list.length >=10){
 	                EasyAlert.show("最多可关注<br>"+followEntLimit+"个企业!");
 	                return;
 				}
 	            window.location.href = "/jyapp/followent/addEnt";
 	        });
-			if(!r.list){
+			if(!res.list){
 				return;
 			}
-			var data = r.list;
+			var data = res.list;
 			// $.ajax({
 			// 		type: 'POST',
 			// 		url: '/publicapply/bidcoll/power',
@@ -84,7 +85,7 @@
 			// 								console.log(res)
 			// 						}
 			// 				})
-			// 		}  
+			// 		}
 			// });
 			var allHtml = "";
 			var jyno = 0;
@@ -134,7 +135,7 @@
 				if(frontarr[f]["i_apppushunread"]==1){
 					redSpot = '<i class="redspot"></i>';
 				}
-				fronthtml +="<li data-id='"+frontarr[f]["_id"]+"' Sort='"+lastpushtime+"'>"
+				fronthtml +="<li data-id='"+frontarr[f]["fid"]+"' Sort='"+lastpushtime+"'>"
 	                +"<div class='jyfwlistno'>"+listno+".</div>"
 	                +"<div class='jyfwlisttitle'>"+entname+"</div>"
 	                +"<div style='clear:both;'></div>"+rem
@@ -167,7 +168,7 @@
 				if(lastarr[l]["i_apppushunread"]==1){
 					redSpot = '<i class="redspot"></i>';
 				}
-				lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["_id"]+"'>"
+				lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["fid"]+"'>"
 				+"<div class='jyfwlistno'>"+listno+".</div>"
 				+"<div class='jyfwlisttitle'>"+lastarr[l]["s_entname"]+"</div>"
 				+"<div style='clear:both;'></div>"+rem

+ 23 - 15
src/jfw/modules/app/src/web/templates/followent/set.html

@@ -45,18 +45,25 @@ if(sessionStorage){
 	    });
 		$(".qyxx").css("padding-top",$(".noticehead").outerHeight()).removeClass("hidden");
 		//解决样式回显问题
-		$.post(
-			"/jyapp/followent/ajaxSearch",
-			{"winner":winner},
-			function(r){
-				follow = r.follow;
-				if(follow == "n"){
-					$(".gz-followcancel").removeClass("hidden");
-				}else{
-					$(".qy-followcancel").removeClass("hidden");
-				}
-			}
-		)
+    follow = follow;
+    if(follow == "n"){
+      $(".gz-followcancel").removeClass("hidden");
+    }else{
+      $(".qy-followcancel").removeClass("hidden");
+    }
+    // const eid = window.location.href.split("/")[6]
+		// $.post(
+		// 	"/bigmember/follow/ent/followCheck",
+		// 	{"entId":eid},
+		// 	function(r){
+		// 		follow = r.follow;
+		// 		if(follow == "n"){
+		// 			$(".gz-followcancel").removeClass("hidden");
+		// 		}else{
+		// 			$(".qy-followcancel").removeClass("hidden");
+		// 		}
+		// 	}
+		// )
 
 
 		//alert(follow);
@@ -122,11 +129,12 @@ if(sessionStorage){
 		$("#sure").click(function(){
 			easyPopup.hide();
 			//发送Ajax请求,取消关注
+      const eid = window.location.href.split("/")[6]
 			$.post(
-				"/jyapp/followent/qgFollow",
-				{"winner":winner},
+				"/bigmember/follow/ent/delFollow",
+				{"fid":eid},
 				function(r){
-					if(r.status == "y"){
+					if(r.data == "success"){
 						if(sessionStorage){
 							sessionStorage.followSetReload = "1";
 						}

+ 21 - 13
src/jfw/modules/app/src/web/templates/invoice/invoicing.html

@@ -628,20 +628,28 @@
                                 url: post_url,
                                 type: "POST",
                                 data: param,
-                            })
-                            // ajax 提交成功后 展示toast 跳转到查看发票页面
-                            weui.toast('提交成功', {
-                                duration: 1500,
-                                className: 'j-toast-icon',
-                                callback: function () {
-                                    if ( c != "") {
-                                      window.location.href = '/jyapp/front/invoice/check_invoice.html?cc=replaceInv&order_code=' + order_code
-                                  }else{
-                                      window.location.href = '/jyapp/front/invoice/check_invoice.html?order_code=' + order_code
-
-                                  }
+                                success: function (r) {
+                                    if(r.invoice_status!=-1){
+                                        // ajax 提交成功后 展示toast 跳转到查看发票页面
+                                        weui.toast('提交成功', {
+                                            duration: 1500,
+                                            className: 'j-toast-icon',
+                                            callback: function () {
+                                                if ( c != "") {
+                                                    window.location.href = '/jyapp/front/invoice/check_invoice.html?cc=replaceInv&order_code=' + order_code
+                                                }else{
+                                                    window.location.href = '/jyapp/front/invoice/check_invoice.html?order_code=' + order_code
+                                                }
+                                            }
+                                        });
+                                    } else {
+                                        weui.toast('开发票失败', {
+                                            duration: 1500,
+                                            className: 'hide-icon'
+                                        });
+                                    }
                                 }
-                            });
+                            })
                         }
                     } else {
                         if (that.phoneStatus && that.emailStatus && that.cnameStatus && that.codeStatus){

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

@@ -44,7 +44,7 @@
     </div>
     <!-- 过期的订单 -->
     <div class="nothing" style="display:none">
-      <img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/vipsubscribe/image/nothing.png?v=51430"/>
+      <img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/image/jy-back.png"/>
       <div class="nothingDiv">该订单记录已删除</div>
     </div>
 		<div class="j-body">
@@ -89,6 +89,10 @@
 											    <span>&nbsp;+&nbsp;</span>
 											    <span class="highlight-text">赠送30天</span>
 											</span>
+                      <span class="discount-container-seller hide">
+                        <span>&nbsp;+&nbsp;</span>
+                        <span class="highlight-text"></span>
+                      </span>
 										</p>
 										<p class="l-item line_cycle" style="display:none">
 											<span>有效日期:</span>

+ 1687 - 0
src/jfw/modules/app/src/web/templates/weixin/follow/detail.html

@@ -0,0 +1,1687 @@
+<html>
+<head>
+<title>项目信息</title>
+{{include "/common/meta.html"}}
+<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/mobiscroll/mobiscroll.min.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+<link rel="stylesheet" type="text/css" href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/layout.css" />
+<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/font.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/common.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/follow.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.css" rel="stylesheet">
+<link href="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/css/p13.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+<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 />
+<script src="https://cdn-common.jianyu360.com/cdn/lib/jquery/3.6.0/jquery.min.js"></script>
+{{include "/common/js.html"}}
+<script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/fastclick.min.js"></script>
+<script src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/local/weui.min.js"></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/visited.js?v={{Msg "seo" "version"}}'></script>
+<style>
+.setpage .noticehead {
+	top: 21.333vw;
+}
+.bid-dec-in{
+  position: absolute;
+  right: -10px;
+  top: 15px;
+  display: flex;
+  align-items: center;
+  height: .56rem;
+  line-height: .56rem;
+  padding: 0 .16rem;
+  color: #fff;
+  font-size: .26rem;
+  border-radius: 14px 0px 0px 14px;
+  background-color: #2ABED1;
+}
+.bid-dec-in .dec-icon{
+  display: inline-block;
+  width: .32rem;
+  height: .32rem;
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIESURBVHgB5VfRccIwDFV6HYANmg3qEcIGbNBsUDYgTFA6Ad2g3SB0AmCCsAFsoEqNTFXXTmxDv3h3Ouew9SRZsmwAbh0FZAARJzSUJIbkJLIriuIE/wkyXJG0GAbP1XBtEGnpMbwlWZO8e+Y61oFrgIgMyVERzyUF7roJRy9rUHQMXALH+JvPcMCR1cVOCJGNpoFEKCe6GMd9BAtLAJlQtdFAKlT0VYKO0cWH/amxqYjfBaW4TdCx9XJ0fm+HArkL8NnFnxBpnIaWhKN8dab3DmeUA6WMO8fQM8uA8SV1w8bhshwP4ME9pKFhQ5xPMrSMMD6KMQfcwpmKwUaKqo4wnnUE51I4K8+cbk6jRwz7ds2YQ4ID5+MTmLdONBFcnXCldUR1fOI9/8tRZzczp4mUkAjsb1AbfQ05ULvQpTjhGF9DKiTH39euIuJxFqFbOTrszFN0DagCO8o3E2zxB63k1jgR1/j7YdLK70al0sQaR6U0k7lGRTaE8+lgXQ+fiTWu8SLR6Eg7Nc/f/DSzaZuITshB43Ngi8PosG8q5cAOcv4XGA7E4nzLFkqZWyZ7VpE8yui20QPJlNruIeCAvhs0+Lm+gf52Zd3N6BMeM1+66E/lR2j93QDXXn0fYCByDVrD1y9fWjrCHaQCVRvFvE6od6KCVGBfyS1e8AdDnGgx51V8M/gC6u7qiWrVshgAAAAASUVORK5CYII=) no-repeat center center;
+  background-size: contain;
+  margin-right: .04rem;
+}
+.prodetail .prodetailTop {
+	background: #fff;
+	box-shadow: inset 0px -0.5px 0px rgba(0, 0, 0, 0.05);
+}
+
+.prodetail .prodetailTop .prodetail_title {
+	padding: 0.32rem 0.32rem 0 0.32rem;
+	line-height: 0.6rem;
+	font-size: 0.4rem;
+	color: #171826;
+}
+
+.prodetail .prodetailTop .tocare {
+	position: relative;
+	margin: 0;
+	padding: 0.32rem;
+	box-sizing: border-box;
+	width: 100%;
+	max-height: 1rem;
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+}
+
+.prodetail .prodetailTop .tocare .nocare, .prodetail .prodetailTop .tocare .care {
+	display: flex;
+	align-items: center;
+	height: 100%;
+}
+
+.prodetail .prodetailTop .tocare .icon-favorite, .prodetail .prodetailTop .tocare .icon-no-favorite {
+	display: flex;
+	align-items: center;
+	width: 0.32rem;
+}
+
+.prodetail .prodetailTop .tocare .care_text {
+	margin-left: 0.08rem;
+	line-height: 0.4rem;
+	font-size: 0.26rem;
+	color: #9B9CA3;
+}
+
+.prodetail .prodetailTop .tocare .forecast {
+	position: absolute;
+	top: 0;
+	right: 0;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	width: 1.68rem;
+	height: 0.56rem;
+	background: #2ABED1;
+	border-radius: 14px 0px 0px 14px;
+}
+
+.prodetail .prodetailTop .tocare .icon-face {
+	display: flex;
+	width: .32rem;
+	height: .32rem;
+	margin-right: .08rem;
+}
+
+.prodetail .prodetailTop .tocare .for_text {
+	font-size: .26rem;
+	line-height: .4rem;
+	color: #fff;
+}
+.setpage .app-layout-content-b {
+	padding-top: 0;
+}
+
+/* 添加关注 - 被填满的心 */
+.icon-favorite {
+	background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAHlSURBVHgB7ZntTcJAHMafNg7gBjJC3QAmME6gJvoZRtAN4LMxsgEbaDewTiBs0AEE/D+1JoT2yr1RzuR+yYXQl7vn12u56wFEIpFIxIEEhmyfh0OkYLmQr+dSSmywkpInD3l+8PzX4Tm+keEMV/X5xnUYC1SNAmMpk7pBFUspcymz5C4vXeqQ85+gwUEBaTiTj4WUAfRZSrmWEIVjHSOpY9l1UKdA3fA7uq+YihLb6mqzlal1Hb8SheoApYCEH8jHh2XDPqHEpaon0o4Tba+8b5hhodrZKiBX/xZm9+uxybYvVaYGqh4YIzRS3LRtbjwD9b3/hRBZp4Pk/m21u6nZA2tkCJVkM9rf1BRIAhZo+VFJ8b/QEigRLo1sTYEUylHv5LRka+sBHhRqLxwWqGeROcJjvj/DJaqHeIbwaJ1etwqIaS4zyZAkZuaTuQSPQBAPdCHhJ6qdSoH6fuPId0qJos6gROeNjIMHp9Z9j9BV+LYHdxeTd+I+JbTCE+1ViR4ltMMTo2WVHiSMwhPzdaHjSRiHJ8YC5AgSVuGJlQDxKGEdnlgLEA8STuGJkwBxkHAOT5wFiIWEl/DEiwAxkPAWnngTIBoSXsMTrwKkQ8J7eOJd4I96eZJ/YjDwpwSfIhKJRCKh8QM2/7mt6fWCsAAAAABJRU5ErkJggg==) no-repeat center;
+	background-size: contain;
+}
+/* 添加关注 - 未被填充的心 */
+.icon-no-favorite {
+	background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAI3SURBVHgB7ZZPbptAFMbfAO4qC45Ab+AbNL5BsqzUKCA5a9IT2NwgXUVyLBHXqrJ0b2B6A47gI6CqC0sFT74XsDO2wAzgXfxJmDE83vdj/jyG6KyPLqETFIYLmyixPc9b6cYS2YnnXSd18eJYonTzz5dSuIKkozwS46GH4fDbTI2fTOc+rl+hefmeXKxwikzTDDzv60obYDqdX0kwoGnnV2QiyEikAsLJkXjAiYv4xX7sBs8K+x1Efh8Ob37XAqjJ8GAkpQzu7m6i3ZtOfrpk0Aj3nC3Eer2mXq83QuzMstIYQ5XksWFfCOseiW4Ls+tDiD2Ax8cXx+xly7culxsY346pRGEY2mlmLdHsqz1BFXp6mo/hNEIzscyLz+rcMNRA0/x/yeZIGleZs/gNLTMdoBnzsGRZtqQjQg+OcYpw2Gn69169twcgDOHzOSMZUI0UiAjHqi6eJAWFyRf1snUQ1uefT+ZFRBoqxnqgE8tzA8O289jKKE9cv36bajsxabeySgBkvm55kjl0Yk0mv7ZvHlcCYAL+4XOaGi6dWIYh/dxDVAOgC55zEsNXiDuLlzdWi8ttrLSgEoALDgrDDzRtEC/C8MWhE5hzbeE25z78npSWYhSOZ65eOkVGxzwvbDTDC7qHMZUfo64QOuZHAbpA6JrXArSBaGKuBdAEoqm5NoAORBvzRgDHINqaNwYog8BehNqatwJQIYq//JGx25i3BmBh6/aArdtbfW9r3lm8NeODzjqrg14BYv85br0avRMAAAAASUVORK5CYII=) no-repeat center;
+	background-size: contain;
+}
+.tocare .j-icon {
+	width: 0.32rem;
+	height: 0.32rem;
+}
+.tocare .report {
+	margin-left: 0.32rem;
+	display: flex;
+	flex-direction: row;
+}
+.report .down-report.active {
+	background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGHSURBVHgB7ZixTsMwEIbvmjwAj8DIkCELQp0IY8RQ3qjOE/AqVAhlDVOFunTIwAaPwAuEw05IaZ1EuchXioQ/qarr2smv2PfHdwAez2nBoT+ix01CQRUj4RkIQEgfFdLDazp/nzKvV2CUb5b6kgqOAqoyvczYo+2Oi3x9HkLwBkeluinTecEZGdodAeFdK5sItki0AgkQF/q6cXNdNN8FZ1pHYL3nsG3Tqry9UiBA9PRiRMa7ezCZwR/HC3Ql5A7kWQ/TQmZ4rfekMs0xf5zwBDm+yPbORItcmg/i7N7YWvMAwElgJjNmcK6K8nVi97KXuExru1EgQwGf9Fy3RvyRLVAULa711zF//G9RbDPtYNCHcBRLzDlEOIol5hxyqihm49/FrvgoBkd8FLvio9gVL9CVTpCYHAF3iTEu6vOaBDoP2W+3OUl9YN27N4wJRKTtzw990v0+TApjcpLE7jTJk93XWeKmZuLuX9OhrC+zGyy/mSKSqdNIld8GZZktpVeNW0zyeH6bLwWomqR68PBjAAAAAElFTkSuQmCC");
+}
+.report .down-report{
+	display: block;
+	background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAGBQTFRFAAAAn5+fl5eflZqfmpqfl5ufl5ujm5ufm5ujmZyjnJyjmpqimp2impyjmZuim5ukm5ujm52inJyjnJ2inJ2kmpyjnJyjm5yjmpuim5yknJyjmpyknJykm5yim5yjm5yjPsLlKAAAAB90Uk5TABAgMDBAQEBAUFBgYG9wcICPkJ+fr6+/wM/P39/v7wMdrEMAAACRSURBVDjLvZPdEkMwEEbRVoOlLVU/xff+b+kiDZGuZIbh3O6xOTETzzuJGy2JjPkLJo2vz0P8k+kCAcbKFoVdqLYIV9kfrApfGTf8BABdvBA+UihnAYNvaagpAxJ7pCFQoUh4QfuLF1Z4VoqS3+BscArpdMSbF3pXZDxd83FU5C5BYIW7+iDn5/m8UhCDOOvZjkPdJPU1xJWBAAAAAElFTkSuQmCC) no-repeat center center;
+	padding-left: 0.32rem;
+	background-position: left;
+	background-size: 0.32rem 0.32rem;
+	color: #9B9BA3;
+	font-size: 0.26rem;
+	line-height: 20px;
+}
+.report  .toVip{
+	border-radius: 0.16rem 0.16rem 0.16rem 0.16rem;
+	opacity: 1;
+	border: 1px solid #FA483C;
+	color: #FA483C;
+	height: 0.4rem;
+	line-height: 0.4rem;
+	padding: 0rem 0.1rem;
+	margin-left: 0.1rem;
+	font-size: 0.2rem;
+	font-weight: 500;
+}
+
+.van-dialog {
+	position: fixed;
+	top: 45%;
+	left: 50%;
+	width: 320px;
+	overflow: hidden;
+	font-size: 16px;
+	background-color: #fff;
+	border-radius: 16px;
+	-webkit-transform: translate3d(-50%,-50%,0);
+	transform: translate3d(-50%,-50%,0);
+	-webkit-backface-visibility: hidden;
+	backface-visibility: hidden;
+	-webkit-transition: .3s;
+	transition: .3s;
+	-webkit-transition-property: opacity,-webkit-transform;
+	transition-property: opacity,-webkit-transform;
+	transition-property: transform,opacity;
+	transition-property: transform,opacity,-webkit-transform
+}
+
+.van-dialog__header {
+	padding-top: 26px;
+	font-weight: 500;
+	line-height: 24px;
+	text-align: center
+}
+
+.van-dialog__header--isolated {
+	padding: 24px 0
+}
+
+.van-dialog__content--isolated {
+	display: -webkit-box;
+	display: -webkit-flex;
+	display: flex;
+	-webkit-box-align: center;
+	-webkit-align-items: center;
+	align-items: center;
+	min-height: 104px
+}
+
+.van-dialog__message {
+	-webkit-box-flex: 1;
+	-webkit-flex: 1;
+	flex: 1;
+	max-height: 60vh;
+	padding: 26px 24px;
+	overflow-y: auto;
+	font-size: 14px;
+	line-height: 20px;
+	white-space: pre-wrap;
+	text-align: center;
+	word-wrap: break-word;
+	-webkit-overflow-scrolling: touch
+}
+
+.van-dialog__message--has-title {
+	padding-top: 8px;
+	color: #646566
+}
+
+.van-dialog__message--left {
+	text-align: left
+}
+
+.van-dialog__message--right {
+	text-align: right
+}
+
+.van-dialog__footer {
+	display: -webkit-box;
+	display: -webkit-flex;
+	display: flex;
+	overflow: hidden;
+	-webkit-user-select: none;
+	user-select: none
+}
+
+.van-dialog__cancel,.van-dialog__confirm {
+	-webkit-box-flex: 1;
+	-webkit-flex: 1;
+	flex: 1;
+	height: 48px;
+	margin: 0;
+	border: 0
+}
+
+.van-dialog__confirm,.van-dialog__confirm:active {
+	color: #ee0a24
+}
+
+.van-dialog--round-button .van-dialog__footer {
+	position: relative;
+	height: auto;
+	padding: 8px 24px 16px
+}
+
+.van-dialog--round-button .van-dialog__message {
+	padding-bottom: 16px;
+	color: #323233
+}
+
+.van-dialog--round-button .van-dialog__cancel,.van-dialog--round-button .van-dialog__confirm {
+	height: 36px
+}
+
+.van-dialog--round-button .van-dialog__confirm {
+	color: #fff
+}
+
+.van-dialog-bounce-enter {
+	-webkit-transform: translate3d(-50%,-50%,0) scale(.7);
+	transform: translate3d(-50%,-50%,0) scale(.7);
+	opacity: 0
+}
+
+.van-dialog-bounce-leave-active {
+	-webkit-transform: translate3d(-50%,-50%,0) scale(.9);
+	transform: translate3d(-50%,-50%,0) scale(.9);
+	opacity: 0
+}
+
+.van-dialog .van-dialog__content .p1 {
+	color: #9b9ca3;
+	line-height: 18px;
+	font-size: .24rem;
+	text-align: center;
+	margin-top: .16rem;
+	padding: 0 .48rem;
+}
+
+.van-dialog .van-dialog__content .van-field {
+	border: 1px solid rgba(0,0,0,0.10);
+	border-radius: 4px;
+	padding: .26rem .32rem;
+}
+
+.van-dialog .van-dialog__content .v-inpt {
+	margin-top: .32rem;
+	padding: 0 .48rem;
+}
+
+.van-dialog .van-dialog__content .btns .van-button {
+	width: 50%;
+	height: .92rem;
+	border: none;
+	color: #171826;
+	line-height: 26px;
+	font-size: .36rem;
+	padding: 0;
+}
+.van-dialog .van-dialog__content .btns .c-btns {
+	color: #2ABED1;
+}
+.van-dialog .van-dialog__content .btns .s-line {
+	width: 1px;
+	height: .92rem;
+}
+.van-dialog .van-dialog__content .van-divider {
+	margin: 0;
+	border-color: #e6e6e6;
+}
+.van-dialog .van-dialog__content .isActive {
+	margin-bottom: .48rem;
+}
+.flex {
+	display: -webkit-box;
+	display: -webkit-flex;
+	display: flex;
+	-webkit-align-items: center;
+	align-items: center;
+}
+.van-button {
+	position: relative;
+	display: inline-block;
+	box-sizing: border-box;
+	height: 44px;
+	margin: 0;
+	padding: 0;
+	font-size: 16px;
+	line-height: 1.2;
+	text-align: center;
+	border-radius: 2px;
+	cursor: pointer;
+	-webkit-transition: opacity .2s;
+	transition: opacity .2s;
+	-webkit-appearance: none
+}
+
+.van-button::before {
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	width: 100%;
+	height: 100%;
+	background-color: #000;
+	border: inherit;
+	border-color: #000;
+	border-radius: inherit;
+	-webkit-transform: translate(-50%,-50%);
+	transform: translate(-50%,-50%);
+	opacity: 0;
+	content: ' '
+}
+
+.van-dialog .van-dialog__content .btns .s-line {
+	width: 1px;
+	height: .92rem;
+	background: #e6e6e6;
+}
+</style>
+<script>
+	var hasReload = false;
+	if(sessionStorage){
+		sessionStorage.followAddVersion="1";
+		if(!hasReload && sessionStorage.followSetReload == "1"){
+			hasReload = true;
+			sessionStorage.removeItem("followSetReload");
+			window.location.reload(true);
+		}
+	}
+</script>
+<script>
+	/***
+	 * weui datepicker for hour @zyh @date:2020/6/1
+	 * */
+	function weuiCron () {
+		var regex = /^(\d+)(?:-(\d+))?(?:\/(\d+))?$/g;
+		var constraints = [[1, 31], [1, 12], [0, 6]];
+		/**
+		 * Schedule
+		 */
+
+		var Schedule = /*#__PURE__*/function () {
+			"use strict";
+
+			function Schedule(fields, start, end) {
+				/**
+				 * dayOfMonth
+				 * @type {Array}
+				 */
+				this._dates = fields[0];
+				/**
+				 * month
+				 * @type {Array}
+				 */
+
+				this._months = fields[1];
+				/**
+				 * dayOfWeek
+				 * @type {Array}
+				 */
+
+				this._days = fields[2];
+				/**
+				 * start
+				 * @type {Date}
+				 */
+
+				this._start = start;
+				/**
+				 * end
+				 * @type {Date}
+				 */
+
+				this._end = end;
+				/**
+				 * cursor
+				 * @type {Date}
+				 * @private
+				 */
+
+				this._pointer = start;
+			}
+
+			var _proto = Schedule.prototype;
+
+			_proto._findNext = function _findNext() {
+				var next;
+
+				while (true) {
+					if (this._end.getTime() - this._pointer.getTime() < 0) {
+						throw new Error("out of range, end is " + this._end + ", current is " + this._pointer);
+					}
+
+					var month = this._pointer.getMonth();
+
+					var date = this._pointer.getDate();
+
+					var day = this._pointer.getDay();
+
+					if (this._months.indexOf(month + 1) === -1) {
+						this._pointer.setMonth(month + 1);
+
+						this._pointer.setDate(1);
+
+						continue;
+					}
+
+					if (this._dates.indexOf(date) === -1) {
+						this._pointer.setDate(date + 1);
+
+						continue;
+					}
+
+					if (this._days.indexOf(day) === -1) {
+						this._pointer.setDate(date + 1);
+
+						continue;
+					}
+
+					next = new Date(this._pointer);
+					break;
+				}
+
+				return next;
+			}
+			/**
+			 * fetch next data
+			 */
+			;
+
+			_proto.next = function next() {
+				var value = this._findNext(); // move next date
+
+
+				this._pointer.setDate(this._pointer.getDate() + 1);
+
+				return {
+					value: value,
+					done: !this.hasNext()
+				};
+			}
+			/**
+			 * has next
+			 * @returns {boolean}
+			 */
+			;
+
+			_proto.hasNext = function hasNext() {
+				try {
+					this._findNext();
+
+					return true;
+				} catch (e) {
+					return false;
+				}
+			};
+
+			return Schedule;
+		}();
+
+		function parseField(field, constraints) {
+			var low = constraints[0];
+			var high = constraints[1];
+			var result = [];
+			var pointer; // * 号等于最低到最高
+
+			field = field.replace(/\*/g, low + '-' + high); // 处理 1,2,5-9 这种情况
+
+			var fields = field.split(',');
+
+			for (var i = 0, len = fields.length; i < len; i++) {
+				var f = fields[i];
+
+				if (f.match(regex)) {
+					f.replace(regex, function ($0, lower, upper, step) {
+						// ref to `cron-parser`
+						step = parseInt(step) || 1; // Positive integer higher than constraints[0]
+
+						lower = Math.min(Math.max(low, ~~Math.abs(lower)), high); // Positive integer lower than constraints[1]
+
+						upper = upper ? Math.min(high, ~~Math.abs(upper)) : lower; // Count from the lower barrier to the upper
+
+						pointer = lower;
+
+						do {
+							result.push(pointer);
+							pointer += step;
+						} while (pointer <= upper);
+					});
+				}
+			}
+
+			return result;
+		}
+		/**
+		 *
+		 * @param expr
+		 * @param start
+		 * @param end
+		 * @returns {*}
+		 */
+
+
+		function parse(expr, start, end) {
+			var atoms = expr.replace(/^\s\s*|\s\s*$/g, '').split(/\s+/);
+			var fields = [];
+			atoms.forEach(function (atom, index) {
+				var constraint = constraints[index];
+				fields.push(parseField(atom, constraint));
+			});
+			return new Schedule(fields, start, end);
+		}
+		return { parse: parse }
+	}
+
+
+	// 扩展weui datepicker来支持选择小时
+	//自定义日期:月时分秒
+	function costomDatePicker(years, startTime, endTime, str) {
+		for (var j = startTime; j < endTime; j++) {
+			years.push({
+				label: ('' + j).length === 1 ? '0' + j + str : '' + j + str,
+				value: ('' + j).length === 1 ? '0' + j : '' + j
+			});
+		}
+
+		return years;
+	}
+
+	var Fixhours = costomDatePicker([], 0, 24, "时");
+
+	function datePickerForHour(options) {
+		var nowDate = new Date();
+		var defaults = options; // 兼容原来的 start、end 传 Number 的用法
+
+		if (typeof defaults.start === 'number') {
+			defaults.start = new Date(defaults.start + "/01/01");
+		} else if (typeof defaults.start === 'string') {
+			defaults.start = new Date(defaults.start.replace(/-/g, '/'));
+		}
+
+		if (typeof defaults.end === 'number') {
+			defaults.end = new Date(defaults.end + "/12/31");
+		} else if (typeof defaults.end === 'string') {
+			defaults.end = new Date(defaults.end.replace(/-/g, '/'));
+		}
+
+			var findBy = function findBy(array, key, value) {
+			for (var i = 0, len = array.length; i < len; i++) {
+				var _obj = array[i];
+
+				if (_obj[key] == value) {
+					return _obj;
+				}
+			}
+		};
+
+		var date = [];
+		var tempS = new Date(defaults.start.getTime())
+		var tempE = new Date(defaults.end.getTime())
+		var tempDefaultE = new Date(defaults.end.getTime())
+		// console.log('fix before', defaults.end.toLocaleString())
+		tempDefaultE.setHours(0)
+		tempDefaultE.setMinutes(0)
+		tempDefaultE.setSeconds(0)
+		defaults.end = new Date(tempDefaultE.getTime() + 60 * 60 * 24 * 1000)
+		// console.log('fix', defaults.end.toLocaleString(), tempDefaultE.toLocaleString())
+		// if (tempE.getFullYear() == tempS.getFullYear() && (tempE.getMonth() + 1) == (tempS.getMonth() + 1) && tempE.getDate() != tempS.getDate()) {
+		// 	defaults.end.setDate(defaults.end.getDate() + 1)
+		// }
+		var interval = weuiCron().parse(defaults.cron, defaults.start, defaults.end);
+		// console.log(tempS.toLocaleString(), tempE.toLocaleString())
+		var obj;
+
+		do {
+			obj = interval.next();
+			var year = obj.value.getFullYear();
+			var month = obj.value.getMonth() + 1;
+			var day = obj.value.getDate();
+			var Y = findBy(date, 'value', year);
+
+			if (!Y) {
+				Y = {
+					label: year + '年',
+					value: year,
+					children: []
+				};
+				date.push(Y);
+			}
+
+			var M = findBy(Y.children, 'value', month);
+
+			if (!M) {
+				M = {
+					label: month + '月',
+					value: month,
+					children: []
+				};
+				Y.children.push(M);
+			}
+			var cc = Fixhours
+			var isS = year == tempS.getFullYear() && month == (tempS.getMonth() + 1) && day == tempS.getDate()
+			var isE = year == tempE.getFullYear() && month == (tempE.getMonth() + 1) && day == tempE.getDate()
+			// console.log(isS, isE, obj.value.toLocaleString())
+			// console.log(tempS.getHours(), tempE.getHours())
+			if (isS) {
+				cc = costomDatePicker([], tempS.getHours(), 24, '时')
+			}
+			if (isE) {
+				var maxT = tempE.getHours() + 1
+				cc = costomDatePicker([], 0, maxT > 24 ? 24 : maxT, '时')
+			}
+			if (isS && isE) {
+				var maxT = tempE.getHours() + 1
+				cc = costomDatePicker([], tempS.getHours(), maxT > 24 ? 24 : maxT, '时')
+			}
+
+			M.children.push({
+				label: day + '日',
+				value: day,
+				children: cc
+			});
+		} while (!obj.done);
+
+		return weui.picker(date, defaults);
+	}
+</script>
+<script type="text/javascript">
+var _id = "";
+var source = {{.T.source}};
+var remind = {{.T.remind}};
+var bidopentime = {{.T.bidopentime}};
+var remindtime = {{.T.remindtime}};
+var l_bidopentime = {{.T.l_bidopentime}};
+var l_remindtime = {{.T.l_remindtime}};
+var lastpushtime = {{.T.l_lastpushtime}};
+var lastpushids = {{.T.a_lastpushids}};
+var relationinfo = {{.T.relationinfo}};
+if(l_bidopentime==null){
+        l_bidopentime = "";
+}
+if(l_remindtime==null){
+        l_remindtime = "";
+}
+var oldData = {bidopentime:bidopentime,remindtime:remindtime,remind:remind};
+if(sessionStorage&&sessionStorage.version=="0"){
+	sessionStorage.version="1";
+}
+var storage = window.localStorage;
+var hasNoFollowPopup = null;
+function isVisited(sid){
+	var a_visited = {{.T.a_visited}};
+	var visited = visitedPath.pathVisited(
+    new VisitedPathItem(
+      '/article/content/*.html',
+      'id=' + sid
+    )
+  )
+	return visited;
+}
+function beforeRedirect(obj,sid,link){
+	$(obj).addClass("visited");
+  try {
+    visitedPath.pathVisiting(
+      new VisitedPathItem(
+        '/article/content/*.html',
+        'id=' + sid
+      )
+    )
+  } catch (error) {}
+	newredirect("",link,sid);
+}
+
+function pageJump(){
+	setTimeout(function(){
+		if(sessionStorage){
+			if(sessionStorage.version=="1"){
+				history.go(-1);
+			}else if(sessionStorage.version=="3"){
+				window.location.href = "/jyapp/follow/list";
+			}else{
+				if(sessionStorage.cancelFollowVersion=="1"){
+					history.go(-1);
+				}else{
+					window.location.href = "/jyapp/follow/list";
+				}
+			}
+		}else{
+			window.location.href = "/jyapp/follow/list";
+		}
+	},1000);
+}
+function followSave(flag){
+	var projectname = {{.T.projectname}};
+	var nfid = {{.T.id}}
+	$.post("/jyapp/follow/fwsave",{projectname:projectname,id:nfid,remind:remind,bidopentime:l_bidopentime,remindtime:l_remindtime},function(r){
+		if(r.status == "y"){
+			if(flag == 1){
+				if(sessionStorage){
+					sessionStorage.followSetReload = "1";
+				}
+				_id = r.followId;
+				hasNoFollowPopup.hide();
+				EasyAlert.show("已关注!");
+				$("#bidtip>img").click();
+				$("#followsure").hide();
+				$("#followcancel").show();
+			}else if(flag == 2){
+				if(sessionStorage){
+					sessionStorage.followSetReload = "1";
+				}
+				EasyAlert.show('已关注"'+projectname+'"项目');
+				setTimeout(function(){
+					window.location.href = "/jyapp/follow/list";
+				},1000)
+			}
+		}else if(r.status == "m"){
+			$("#hasNoFollowPopup").css("display","none");
+			EasyAlert.show("最多可关注<br>10个项目!");
+		}else if(r.status == "e"){
+			EasyAlert.show("已关注此项目!");
+			isFollow()
+		}else{
+			EasyAlert.show("数据提交失败!");
+		}
+	});
+}
+//是否关注
+function isFollow(){
+	$.ajax({
+		type: "POST",
+		url: "/jyapp/follow/checkCStatus",
+		data: {s_id:""},
+		async: false,
+		cache: false,
+		dataType: "json",
+		success: function (r){
+			_id = r.followid;
+		}
+	});
+	if(_id == ""){
+		$(".tocare").attr('data-follow', 'false')
+		$(".tocare .care_text").text('关注')
+		$(".tocare .icon-favorite").removeClass('icon-favorite').addClass('icon-no-favorite')
+		return false;
+	}
+	$(".tocare").attr('data-follow', 'true')
+	$(".tocare .care_text").text('已关注')
+	$(".tocare .icon-no-favorite").removeClass('icon-no-favorite').addClass('icon-favorite')
+
+	return true;
+}
+
+$(function(){
+
+  $(".care").on('click', function () {
+	  var canFollow = $(".tocare").attr('data-follow')
+
+	  if (canFollow === 'true') {
+		  easyPopup.show();
+	  } else {
+		  followSave(2);
+	  }
+  })
+	var localEmail =  {{.T.email}} || sessionStorage.getItem('reportEmail') || ''
+	var vNode = {
+		delimiters: ['${', '}'],
+		el: '#v-pro',
+		data: {
+			isPayedUser: false,
+			sendReportMail: localEmail,
+			reportUrl: '',
+			sid: '',
+			isRequestIng:false,
+			isExportDialogShow: false
+		},
+		methods: {
+			//下载报告跳转开通会员
+			openVip: function () {
+				// location.href = "/jyapp/vipsubscribe/vipsubscribe_new"
+        location.href = '/jy_mobile/common/order/create/svip?type=buy'
+			},
+			//下载报告
+			downReport: function (type) {
+				if (!this.isPayedUser) {
+					return this.openVip()
+				}
+				if (this.isRequestIng) {
+					return
+				}
+				this.isRequestIng = true
+				this.$toast.loading({
+					duration: 0, // 持续展示 toast
+					forbidClick: true,
+					message: '请稍后~',
+				});
+				//获取下载链接
+				if (this.reportUrl === "") {
+					let _this = this
+					$.ajax({
+						type: 'POST',
+						url: '/bigmember/project/getPdfFile',
+						data: {sid: this.sid},
+						success: function (res) {
+							_this.isRequestIng = false
+							_this.$toast.clear()
+							if (res.error_code === 0) {
+								_this.reportUrl = res.data.path
+								//_this.$dialog.alert({title: '提示信息', message: '邮件已发送,请注意查收'})
+								_this.downReportNext(type)
+							} else {
+								_this.$dialog.alert({title: '提示信息', message: res.error_msg})
+							}
+						},
+						error: function (err) {
+							_this.isRequestIng = false
+							_this.$toast.clear()
+							console.log(err)
+						}
+					})
+				}else {
+					this.$toast.clear()
+					this.isRequestIng = false
+					this.downReportNext(type)
+				}
+			},
+			downReportNext:function (type){
+				if (type === 'app') {
+					var isIos = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
+					if (isIos) {
+						// ios
+						this.isExportDialogShow = true
+					} else {
+						// andorid/wx
+						const a1 = document.createElement('a')
+						a1.href = this.reportUrl
+						a1.click()
+					}
+				} else {
+					// 微信浏览器
+					location.href = this.reportUrl
+				}
+			},
+			sendMail: function () {
+				let _this = this
+				if (_this.isRequestIng){
+					return
+				}
+				if (_this.sendReportMail === "") {
+					_this.$dialog.alert({title: '提示信息', message: '请输入邮箱地址'})
+				}
+				if (_this.reportUrl === "") {
+					_this.$dialog.alert({title: '提示信息', message: '报告附件异常'})
+				}
+				_this.isRequestIng = true
+				sessionStorage.setItem('reportEmail', this.sendReportMail)
+				$.ajax({
+					type: 'POST',
+					url: '/jypay/sendMailNote/projectPdfFile',
+					data: {downurl: this.reportUrl, email: this.sendReportMail},
+					success: function (res) {
+						_this.sendMailCancel()
+						_this.isRequestIng = false
+						if (res.error_code === 0) {
+							_this.$dialog.alert({title: '提示信息', message: '邮件已发送,请注意查收'})
+						} else {
+							_this.$dialog.alert({title: '提示信息', message: res.error_msg})
+						}
+					},
+					error: function (err) {
+						_this.isRequestIng = false
+						console.log(err)
+					}
+				})
+			},
+			sendMailCancel: function () {
+				this.isExportDialogShow = false
+				// this.sendReportMail = ''
+			}
+		}
+	}
+	var vPage = new Vue(vNode)
+
+	$.ajax({
+		type: 'POST',
+		url: '/bigmember/use/isAdd',
+		data: {},
+		success: function (res) {
+			vPage.isPayedUser = res.data.memberStatus > 0 || res.data.vipStatus || res.data.entniche
+			if (vPage.isPayedUser) {
+				$(".report .toVip").remove()
+			}
+		},
+		error: function (err) {
+			console.log(err)
+		}
+	})
+	$(".report").on('click', function () {
+		vPage.downReport('app')
+	})
+
+	function checkStatusOfEId (eid) {
+		// 获取项目SID,展示下载项目报告
+		vPage.sid = eid
+		//查看信息是否关联项目,若无关联则展示
+		$.post("/bigmember/follow/project/check",{ sid: eid },function(res){
+			if(res.data.showFollow){
+				$('.report').show()
+			} else {
+				$('.report').hide()
+			}
+		})
+	}
+
+  //
+  localStorage.removeItem("redSpotLastAjaxTime");  
+
+	$(window).bind("pageshow", function(event){
+		if(event.originalEvent.persisted){
+			hasReload = true;
+			window.location.reload(true);
+		}
+	});
+	isFollow();
+	// $(".app-layout-content-b").css("padding-top",$(".noticehead").outerHeight()+10);
+	$(".app-layout-content-b>ul").removeClass("hide");
+	//$("#noticeCount").html("("+(relationinfo.length)+")");
+	new FastClick(document.body);
+	var easyPopup = new EasyPopup("easypopup");
+	hasNoFollowPopup = new EasyPopup("hasNoFollowPopup");
+	$("#bidtip>img").click(function(){
+		//if(source != 2){
+		//	var subtype = {{.T.subtype}};
+		//	var followType = {{.T.type}};
+		//	var toptype = {{.T.toptype}};
+		//	if(toptype != "" && toptype != null && typeof(toptype) != "undefined"){
+		//		if(toptype != "招标"){
+		//			return;
+		//		}
+		//	}else if(followType != "tender"){
+		//		return;
+		//	}
+		//}
+		if (_id != ""){
+			if($(this).parent().hasClass("turn-on")){
+				remind = 0;
+				$(".time").removeClass("tipon");
+				$(this).attr("src","{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/off.png?v={{Msg "seo" "version"}}");
+			}else{
+				remind = 1;
+				$(".time").addClass("tipon");
+				$(this).attr("src","{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/on.gif?v={{Msg "seo" "version"}}");
+			}
+			$(this).parent().toggleClass("turn-on");
+		}
+		opation();
+	});
+	var opation = function(){
+		if(_id == ""){
+			hasNoFollowPopup.show();
+			return;
+		}
+		$.post("/jyapp/follow/ajaxReq",{reqType:"followset",id:_id,remind:remind,bidopentime:l_bidopentime,remindtime:l_remindtime},function(r){
+			if(r.status != "y"){
+				EasyAlert.show("操作失败!");
+			}
+		});
+	};
+
+	$("#followcancel").click(function(){
+		easyPopup.show();
+	});
+	$("#cancel").click(function(){
+		easyPopup.hide();
+	});
+	$("#sure").click(function(){
+		easyPopup.hide();
+		$.post("/jyapp/follow/ajaxReq",{reqType:"cancel",id:_id},function(r){
+			if(r.status == "y"){
+				if(sessionStorage){
+					sessionStorage.followSetReload = "1";
+				}
+				EasyAlert.show("已取消关注");
+				pageJump();
+			}else{
+				EasyAlert.show("取消失败!");
+			}
+		});
+	});
+	/**$("#notice").click(function(){
+		if(relationinfo.length == 0){
+			return;
+		}
+		window.location.href = "/jyapp/follow/allNotice/"+_id;
+	});**/
+	var fg = {{.T.fg}}
+	if (_id == ""){
+		var relationinfo = {{.T.data}}
+		var projectname = {{.T.projectname}};
+		var projectcode = {{.T.projectcode}};
+		var mySelf = {{.T.mySelf}};
+		var listhtml = "";
+		if(mySelf){
+			/*var myarea = mySelf["area"]
+			if (myarea != ""&&myarea != null&&myarea != "A"){
+				mytmfdiv += '<span class="location">'+myarea+'</span>';
+			}*/
+      var mytype = mySelf.subtype;
+      // 判断最后一次标讯类型是否是中标、成交、合同,是则隐藏投标决策分析入口
+      if (mytype == '中标' || mytype == '成交' || mytype == '合同'){
+        $('#analysis-in').hide()
+      }
+			if(typeof(mytype) == "undefined" || mytype == "" || mytype == null){
+				mytype = mySelf.toptype;
+			}
+			if(typeof(mytype) == "undefined" || mytype == "" || mytype == null){
+				mytype = mySelf.type;
+				if(mytype == "tender"){
+					mytype = "招标";
+				}else if (mytype == "bid"){
+					mytype = "中标";
+				}
+			}
+			if(typeof(mytype) != "undefined" && mytype != "" && mytype != null){
+				mytype = '<span class="type">'+mytype+'</span>';
+			}else{
+				mytype = '';
+			}
+			var mynoticetime = '';
+			if(mySelf["l_publishtime"]){
+				mynoticetime = new Date(Number(mySelf["l_publishtime"]+"000")).Format("MM-dd");
+			}
+			var mytitle = mySelf["s_title"];
+			if(projectname && projectname != "" && mytitle != null && mytitle.toLowerCase().indexOf(projectname.toLowerCase()) > -1){
+				mytitle = keyWordHighlight(mytitle,projectname,"<span class='keyword'>$1</span>");
+			}else if(projectcode && projectcode != "" && mytitle != null && mytitle.toLowerCase().indexOf(projectcode.toLowerCase()) > -1){
+				mytitle = keyWordHighlight(mytitle,projectcode,"<span class='keyword'>$1</span>");
+			};
+			var myid = mySelf["s_eid"]
+
+			checkStatusOfEId(myid)
+			var myhtml = '';
+			if(mytitle!=undefined){
+				myhtml = '<div class="jynoticelist">'
+						+'<div>'
+						+'<span class="noticetime">'+mynoticetime+'</span>'
+						+mytype
+						+'</div>'
+						+'<div class="timeaxis"><span></span></div>'
+						+'<div>'
+						+'<a href="javascript:void(0)" class="title'+(isVisited(mySelf["s_id"])?' visited':'')+'" onclick="beforeRedirect(this,\''+myid+'\',\''+mySelf["s_url"]+'\')">'+mytitle+'</a>'
+						+'</div>'
+						+'</div>';
+
+			}
+			if(myhtml!=""){
+				$("#notice,.jynotice").removeClass("hidden");
+			}
+			$(".jynotice").append(myhtml);
+		}
+		if (relationinfo!= null&&relationinfo != ""){
+			for(var i =0;i<relationinfo.length;i++){
+        // 判断最后一次标讯类型是否是中标、成交、合同,是则隐藏投标决策分析入口
+        if (relationinfo[0].s_subtype == '中标' || relationinfo[0].s_subtype == '成交' || relationinfo[0].s_subtype == '合同') {
+          $('#analysis-in').hide()
+        }
+				var no = 1;
+				var title = "";
+				/*if (lastpushids != null&&lastpushids != ""){
+					for (var j=0;j<lastpushids.length;j++ ){
+						if(lastpushids[j]==relationinfo[i]["s_id"]){
+							j=lastpushids.length;
+							title = '<span class="noticenew">新</span>'+relationinfo[i]["s_title"];
+						}else{
+							title = relationinfo[i]["s_title"];
+						}
+					}
+				}else{
+					title = relationinfo[i]["s_title"];
+				}*/
+				title = relationinfo[i]["s_title"];
+				if(projectname && projectname != "" && title.toLowerCase().indexOf(projectname.toLowerCase()) > -1){
+					title = keyWordHighlight(title,projectname,"<span class='keyword'>$1</span>");
+				}else if(projectcode && projectcode != "" && title.toLowerCase().indexOf(projectcode.toLowerCase()) > -1){
+					title = keyWordHighlight(title,projectcode,"<span class='keyword'>$1</span>");
+				}
+				no = no + i + 1;
+				var relId = relationinfo[i]["s_eid"];
+				var type = relationinfo[i].s_subtype;
+				if(typeof(type) == "undefined" || type == "" || type == null){
+					type = relationinfo[i].s_toptype;
+				}
+				if(typeof(type) == "undefined" || type == "" || type == null){
+					type = relationinfo[i].s_type;
+					if(type=="tender"){
+						type = "招标";
+					}else if (type=="bid"){
+						type = "中标";
+					}
+				}
+				if(typeof(type) != "undefined" && type != "" && type != null){
+					type = '<span class="type">'+type+'</span>';
+				}else{
+					type = '';
+				}
+				var noticetime = '';
+				if(relationinfo[i]["l_publishtime"]){
+					noticetime = new Date(Number(relationinfo[i]["l_publishtime"]+"000")).Format("MM-dd");
+				}
+				listhtml +='<div class="jynoticelist">'
+						+'<div>'
+						+'<span class="noticetime">'+noticetime+'</span>'
+						+type
+						+'</div>'
+						+'<div class="timeaxis"><span></span></div>'
+						+'<div>'
+						+'<a href="javascript:void(0)" class="title'+(isVisited(relationinfo[i]["s_id"])?' visited':'')+'" onclick="beforeRedirect(this,\''+relId+'\',\''+relationinfo[i]["s_url"]+'\')">'+title+'</a>'
+						+'</div>'
+						+'</div>';
+				/*var province = relationinfo[i].s_province;
+				if (province == null||province.replace(/\s/g, "") == "A"){
+					province = ""
+				}else{
+					province = '<span class="location">'+province+'</span>';
+				}*/
+			}
+		}
+		if(listhtml!=""){
+			$("#notice,.jynotice").removeClass("hidden");
+		}
+		$(".jynotice").append(listhtml);
+		$("#followsure").click(function(){
+			followSave(2);
+		});
+	}else{
+		$.post("/jyapp/follow/allNotice/",{id:_id},function(D){
+			var relationinfo = D.data["a_relationinfo"];
+			var projectcode = D.data["s_projectcode"];
+			var projectname = D.data["s_projectname"];
+			var listhtml = "";
+			$('.report').hide()
+			if (relationinfo!=null&&relationinfo != ""){
+				for(var i =0;i<relationinfo.length;i++){
+					var infoid = relationinfo[i]["s_eid"]
+					if (i === 0) {
+						checkStatusOfEId(infoid)
+					}
+					var no = i+1;
+					var title = "";
+					/*if (lastpushids != null&&lastpushids != ""){
+						for (var j=0;j<lastpushids.length;j++ ){
+							if(relationinfo[i]["s_id"]==lastpushids[j]){
+								title = '<span class="noticenew">新</span>'+relationinfo[i]["s_title"];
+								j=lastpushids.length;
+							}else{
+								title = relationinfo[i]["s_title"];
+							}
+						}
+					}else{
+						title = relationinfo[i]["s_title"];
+					}*/
+					title = relationinfo[i]["s_title"];
+					if(projectname && projectname != "" && title.toLowerCase().indexOf(projectname.toLowerCase()) > -1){
+						title = keyWordHighlight(title,projectname,"<span class='keyword'>$1</span>");
+					}else if(projectcode && projectcode != "" && title.toLowerCase().indexOf(projectcode.toLowerCase()) > -1){
+						title = keyWordHighlight(title,projectcode,"<span class='keyword'>$1</span>");
+					}
+					var sttype = '';
+					var s_type = relationinfo[i].s_type;
+					var subtype = relationinfo[i].s_subtype;
+          var toptype  = relationinfo[i].s_toptype;
+          // 判断最后一次标讯类型是否是中标、成交、合同,是则隐藏投标决策分析入口
+          if (relationinfo[0].s_subtype == '中标' || relationinfo[0].s_subtype == '成交' || relationinfo[0].s_subtype == '合同') {
+            $('#analysis-in').hide()
+          }
+					if(typeof(subtype) != "undefined" && subtype != "" && subtype!=null){
+						sttype='<span class="type"'+(subtype.length>=4?' style="font-size:12px;padding: 1px 1px;"':'')+'>'+subtype+'</span>';
+					}else if(typeof(toptype) != "undefined" && toptype != "" && toptype!=null){
+						sttype='<span class="type"'+(toptype.length>=4?' style="font-size:12px;padding: 1px 1px;"':'')+'>'+toptype+'</span>';
+					}else if(typeof(s_type) != "undefined" && s_type != null&&s_type != ""){
+						if (s_type=="tender"){
+							sttype='<span class="type">招标</span>';
+						}else if (s_type=="bid"){
+							sttype='<span class="type">中标</span>';
+						}
+					}
+					var noticetime = '';
+					if(relationinfo[i]["l_publishtime"]){
+						noticetime = new Date(Number(relationinfo[i]["l_publishtime"]+"000")).Format("MM-dd");
+					}
+					listhtml += '<div class="jynoticelist">'
+							+'<div>'
+							+'<span class="noticetime">'+noticetime+'</span>'
+							+sttype
+							+'</div>'
+							+'<div class="timeaxis"><span></span></div>'
+							+'<div>'
+							+'<a href="javascript:void(0)" class="title'+(isVisited(infoid)?' visited':'')+'" onclick="beforeRedirect(this,\''+infoid+'\',\''+relationinfo[i]["s_url"]+'\')">'+title+'</a>'
+							+'</div>'
+							+'</div>';
+					/*var province = relationinfo[i].s_province;
+					if (province == null||province.replace(/\s/g, "") == "A"){
+						province = ""
+					}else{
+						province = '<span class="location">'+province+'</span>';
+					}*/
+				}
+			}
+			if(listhtml!=""){
+				$("#notice,.jynotice").removeClass("hidden");
+			}
+			$(".jynotice").append(listhtml);
+		});
+	}
+	var minDate = new Date();
+	minDate.setHours(minDate.getHours() + 1);
+	var setRemindTimeFlag = false;
+	var remindtimeMinDate = null;
+	if(l_remindtime == ""){
+		remindtimeMinDate = minDate;
+	}else{
+		var rtDate = new Date(Number(l_remindtime+"000"));
+		if(rtDate < minDate){
+			remindtimeMinDate = rtDate;
+		}else{
+			remindtimeMinDate = minDate;
+		}
+	}
+	var remindtimeMaxDate = null;
+	if(l_bidopentime != ""){
+		remindtimeMaxDate = new Date(Number(l_bidopentime+"000"));
+	}
+	//获取当前时间
+	var nowDate = (function () {
+		var date = new Date();
+		var year = date.getFullYear();
+		var month = date.getMonth() + 1;
+		var day = date.getDate();
+		month = month < 10 ? '0' + month : month;
+		day = day < 10 ? '0' + day : day;
+		return year + '/' + month + '/' + day;
+	})();
+	function nowDateForHour (msec) {
+		var date = new Date(msec);
+		var year = date.getFullYear();
+		var month = date.getMonth() + 1;
+		var day = date.getDate();
+		var hour = date.getHours();
+		month = month < 10 ? '0' + month : month;
+		day = day < 10 ? '0' + day : day;
+		hour = hour < 10 ? '0' + hour : hour;
+		return [year, month, day, hour]
+	}
+	var weekDay = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
+	// 显示记录值
+	var nowStartTime, nowEndTime;
+	var minSTime, minETime;
+	function getDefaultNowTime () {
+		// 获取默认值 开标
+		if (l_bidopentime != '') {
+			minSTime = new Date(Number(l_bidopentime + '000'))
+			// 默认值低,需使用最小值
+			if (minSTime.getTime() < minDate.getTime()) {
+				minSTime = new Date(minDate.getTime())
+			}
+		} else {
+			minSTime = new Date(minDate.getTime())
+		}
+		nowStartTime = nowDateForHour(minSTime.getTime())
+
+		// 获取默认值 提醒
+		minETime = new Date(minDate.getTime())
+		if (l_remindtime != '') {
+			var tempNowDate = new Date(Number(l_remindtime + '000'))
+			nowEndTime = nowDateForHour(tempNowDate.getTime())
+			// 默认值低
+			if (minETime.getTime() > tempNowDate.getTime()) {
+				nowEndTime = nowDateForHour(minETime.getTime())
+			}
+		} else {
+			nowEndTime = nowDateForHour(minETime.getTime())
+		}
+	}
+	getDefaultNowTime()
+	$("#bidopentime").click(function(){
+		if(!remind){
+			return false;
+		}
+		datePickerForHour({
+			id: 'start' + new Date().getTime(),
+			start: new Date(minSTime.getTime()),
+			title: '选择开标时间',
+			cron: '* * *',
+			end: new Date().getFullYear()+5,
+			defaultValue: nowStartTime ? nowStartTime : nowDate.split('/'),
+			className: 'jymobile-datePicker start',
+			onChange: function (result) {
+				var nowTArr = result.map(function (v) {
+					return v.label
+				})
+				$(".jymobile-datePicker.start .weui-picker__item").each(function(){
+					var nowT = $(this).text()
+					$(this).removeClass('is-now-select')
+					if (nowTArr.indexOf(nowT) !== -1) {
+						$(this).addClass('is-now-select')
+					}
+				})
+			},
+			onClose: function () {},
+			onConfirm: function (result) {
+				var year = result[0].value;
+				var month = result[1].value < 10 ? '0' + result[1].value : result[1].value;
+				var day = result[2].value < 10 ? '0' + result[2].value : result[2].value;
+				var hour = result[3].value;
+				var timeSec = year + '/' + month + '/' + day + ' ' + hour + ':00:00'
+				nowStartTime = [year, month, day, hour]
+
+				var date = new Date(timeSec);
+				var time_result = year + '年' + month + '月' + day + '日 ' + hour + '时 ' + weekDay[date.getDay()];
+				$("#bidopentime input").val(time_result).attr('value', time_result)
+				var now = new Date();
+				var defaultValue = null;
+				if(!(now.getFullYear() == date.getFullYear() && now.getMonth() == date.getMonth() && now.getDate() == date.getDate())){
+					defaultValue = new Date(date.getTime());
+					defaultValue.setDate(defaultValue.getDate() - 1);
+				}else{
+					defaultValue = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours());
+					defaultValue.setHours(defaultValue.getHours() + 1);
+				}
+
+				if(!setRemindTimeFlag){
+					l_remindtime = defaultValue.getTime()+"";
+					l_remindtime = l_remindtime.substring(0,l_remindtime.length - 3);
+					var tl_remindtime = Number(l_remindtime + '000')
+					nowEndTime = nowDateForHour(Number(tl_remindtime))
+					var time_result_end = nowEndTime[0] + '年' + nowEndTime[1] + '月' + nowEndTime[2] + '日 ' + nowEndTime[3] + '时 ' + weekDay[new Date(Number(tl_remindtime)).getDay()];
+					$("#remindtime input").val(time_result_end).attr('value', time_result_end)
+				}
+				l_bidopentime = date.getTime()+"";
+				l_bidopentime = l_bidopentime.substring(0,l_bidopentime.length - 3);
+				opation();
+			}
+		});
+		$(".jymobile-datePicker.start #weui-picker-confirm").text('确认')
+		return false;
+	});
+	$("#remindtime").click(function(){
+		if(!remind){
+			return false;
+		}
+		datePickerForHour({
+			id: 'end' + new Date().getTime(),
+			start: new Date(minETime.getTime()),
+			title: '选择提醒时间',
+			cron: '* * *',
+			end: new Date(nowStartTime[0] + '/' + nowStartTime[1] + '/' + nowStartTime[2] + ' ' + nowStartTime[3] + ':00:00'),
+			defaultValue: nowEndTime ? nowEndTime : nowDate.split('/'),
+			className: 'jymobile-datePicker end',
+			onChange: function (result) {
+				var nowTArr = result.map(function (v) {
+					return v.label
+				})
+				$(".jymobile-datePicker.end .weui-picker__item").each(function(){
+					var nowT = $(this).text()
+					$(this).removeClass('is-now-select')
+					if (nowTArr.indexOf(nowT) !== -1) {
+						$(this).addClass('is-now-select')
+					}
+				})
+			},
+			onClose: function () {},
+			onConfirm: function (result) {
+				var year = result[0].value;
+				var month = result[1].value < 10 ? '0' + result[1].value : result[1].value;
+				var day = result[2].value < 10 ? '0' + result[2].value : result[2].value;
+				var hour = result[3].value;
+				var timeSec = year + '/' + month + '/' + day + ' ' + hour + ':00:00'
+				nowEndTime = [year, month, day, hour]
+
+				var date = new Date(timeSec);
+				minSTime = new Date(timeSec)
+				var time_result = year + '年' + month + '月' + day + '日 ' + hour + '时 ' + weekDay[date.getDay()];
+				$("#remindtime input").val(time_result).attr('value', time_result)
+
+				setRemindTimeFlag = true;
+				l_remindtime = date.getTime()+"";
+				l_remindtime = l_remindtime.substring(0,l_remindtime.length - 3);
+				opation();
+			}
+		});
+		$(".jymobile-datePicker.end #weui-picker-confirm").text('确认')
+		return false;
+	});
+	$("#hasNoFollow-sure").click(function(){
+		followSave(1);
+	});
+	$("#hasNoFollow-cancel").click(function(){
+		hasNoFollowPopup.hide();
+  });
+
+  // 投标决策分析入口
+  $('#analysis-in').click(function() {
+    sessionStorage.removeItem('big-analysis_filter')
+    var datas = {{.T.relationinfo}} || [];
+    var obj = {{.T.mySelf}};
+    if (!datas || datas.length == 0) {
+      datas.push(obj)
+    }
+    console.log(_id,datas)
+    $.ajax({
+        type:'GET',
+        url:'/bigmember/use/isAdd',
+        success: function(res) {
+            if (res.data && res.data.power && res.data.power.indexOf(6) > -1) {
+              if (datas && datas.length > 0) {
+                location.href = '/jyapp/big/page/analysis_filter?sId=' + datas[0]['s_eid']
+              } else {
+                location.href = '/jyapp/big/page/analysis_filter?id=' + _id
+              }
+            } else {
+              if (datas && datas.length > 0) {
+                location.href = '/jyapp/big/page/analysis_filter?source=app_analysis_follow_project&sId=' + datas[0]['s_eid']
+              } else {
+                location.href = '/jyapp/big/page/analysis_filter?source=app_analysis_follow_project&id=' + _id
+              }
+
+            }
+        },
+        error:function(err) {
+            console.log(err)
+        }
+    })
+
+  })
+});
+function isVisited(sid){
+	var a_visited = {{.T.a_visited}};
+	var visited = visitedPath.pathVisited(
+    new VisitedPathItem(
+      '/article/content/*.html',
+      'id=' + sid
+    )
+  )
+	return visited;
+}
+function beforeRedirect(obj,sid,link){
+	$(obj).addClass("visited");
+  try {
+    visitedPath.pathVisiting(
+      new VisitedPathItem(
+        '/article/content/*.html',
+        'id=' + sid
+      )
+    )
+  } catch (error) {}
+	newredirect("",link,sid);
+}
+function afterRemindtimeSelect(date){
+	$("#bidopentime>.time").mobiscroll('getInst').option({minDate: date});
+	l_remindtime = date.getTime()+"";
+	l_remindtime = l_remindtime.substring(0,l_remindtime.length - 3);
+}
+function pageJump(){
+	setTimeout(function(){
+		if(sessionStorage){
+			if(sessionStorage.version=="1"){
+				history.go(-1);
+			}else if(sessionStorage.version=="3"){
+				window.location.href = "/jyapp/follow/list";
+			}else{
+				if(sessionStorage.cancelFollowVersion=="1"){
+					history.go(-1);
+				}else{
+					window.location.href = "/jyapp/follow/list";
+				}
+			}
+		}else{
+			window.location.href = "/jyapp/follow/list";
+		}
+	},1000);
+}
+function followSave(flag){
+	var projectname = {{.T.projectname}};
+	var nfid = {{.T.id}}
+	$.post("/jyapp/follow/fwsave",{projectname:projectname,id:nfid,remind:remind,bidopentime:l_bidopentime,remindtime:l_remindtime},function(r){
+		if(r.status == "y"){
+			if(flag == 1){
+				if(sessionStorage){
+					sessionStorage.followSetReload = "1";
+				}
+				_id = r.followId;
+				hasNoFollowPopup.hide();
+				EasyAlert.show("已关注!");
+				$("#bidtip>img").click();
+				$("#followsure").hide();
+				$("#followcancel").show();
+				isFollow()
+			}else if(flag == 2){
+				if(sessionStorage){
+					sessionStorage.followSetReload = "1";
+				}
+				EasyAlert.show('已关注"'+projectname+'"项目');
+				setTimeout(function(){
+					window.location.href = "/jyapp/follow/list";
+				},1000)
+			}
+		}else if(r.status == "m"){
+			$("#hasNoFollowPopup").css("display","none");
+			EasyAlert.show("最多可关注<br>10个项目!");
+		}else if(r.status == "e"){
+			EasyAlert.show("已关注此项目!");
+			isFollow()
+		}else{
+			EasyAlert.show("数据提交失败!");
+		}
+	});
+}
+</script>
+</head>
+<body class="setpage p13">
+	<div class="app-layout-header jy-app-header">
+		<span class="app-back jyapp-icon jyapp-icon-zuojiantou"></span>
+		项目信息
+		<span></span>
+		<div class="noticehead" style="display: none">
+    			{{if .T.projectname}}
+    				{{Html .T.projectname}}
+    			{{else}}
+    				{{.T.projectcode}}
+    			{{end}}
+    			<div class="followcancel">
+    				<div id="followsure" class="hidden">关注</div>
+    				<div id="followcancel" class="hidden">取消关注</div>
+    			</div>
+    		</div>
+	</div>
+	<div class="app-layout-content-b">
+		<div class="prodetail">
+			<div class="prodetailTop">
+				<div class="prodetail_title">
+					{{if .T.projectname}}
+					{{Html .T.projectname}}
+					{{else}}
+					{{.T.projectcode}}
+					{{end}}
+				</div>
+				<div class="tocare"><!---->
+					<div class="care"><span class="j-icon icon-favorite"></span> <span class="care_text">已关注</span></div>
+					<div class="report">
+						<span class="down-report active">下载项目报告</span>
+						<span class="toVip">开通</span>
+					</div>
+				</div>
+			</div>
+		</div>
+		<ul class="hide">
+			<!--<li>{{.T.projectname}}</li>-->
+			<li class="bidtip{{if .T.remind}} turn-on{{end}}" id="bidtip">
+				开标提醒
+				{{if .T.remind}}
+				<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/on.gif?v={{Msg "seo" "version"}}">
+				{{else}}
+				<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/off.png?v={{Msg "seo" "version"}}">
+				{{end}}
+			</li>
+			<li class="bidopentime" id="bidopentime">
+				<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/jyopentm.png?v={{Msg "seo" "version"}}" class="timeicon">
+				开标时间
+				<input type="text" readonly="readonly" class="time{{if .T.remind}} tipon{{end}}" value="{{.T.bidopentime}}" placeholder="请选择时间">
+				<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/d.png?v={{Msg "seo" "version"}}" class="arrow-right">
+			</li>
+			<li class="remindtime" id="remindtime">
+				<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/jyopenre.png?v={{Msg "seo" "version"}}" class="timeicon">
+				提醒时间
+				<input type="text" readonly="readonly" class="time{{if .T.remind}} tipon{{end}}" value="{{.T.remindtime}}" placeholder="请选择时间">
+				<img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/d.png?v={{Msg "seo" "version"}}" class="arrow-right">
+			</li>
+			<li id="notice" class="hidden">
+        项目公告
+        <!-- <span id="noticeCount">0</span><img src="/jyapp/images/wx/d.png?v=51430" class="arrow-right"> -->
+        <span id="analysis-in" class="bid-dec-in">
+          <em class="dec-icon"></em>
+          投标决策分析
+        </span>
+      </li>
+			<li class="jynotice hidden">
+			</li>
+		</ul>
+		<div class="easypopup" id="easypopup">
+			<div class="easypopup-main">
+				<div class="easypopup-header">提示信息</div>
+				<div class="easypopup-content">
+					取消对“{{.T.projectname}}”项目的关注?
+				</div>
+				<div class="easypopup-footer">
+					<span id="cancel">取消</span>
+					<span id="sure">确定</span>
+				</div>
+			</div>
+		</div>
+		<div class="easypopup" id="hasNoFollowPopup">
+			<div class="easypopup-main">
+				<div class="easypopup-header">提示信息</div>
+				<div class="easypopup-content">
+					关注项目即可使用开标提醒功能,是否关注?
+				</div>
+				<div class="easypopup-footer">
+					<span id="hasNoFollow-cancel">取消</span>
+					<span id="hasNoFollow-sure">确定</span>
+				</div>
+			</div>
+		</div>
+
+		<div id="v-pro" v-cloak>
+			<van-dialog v-model:show="isExportDialogShow" title="发送邮箱地址" :show-confirm-button="false">
+				<p class="p1">项目报告文件将以邮件的形式发送至您的邮箱</p>
+				<div class="v-inpt isActive">
+					<van-field placeholder="输入邮箱地址" v-model="sendReportMail"/>
+				</div>
+				<van-divider></van-divider>
+				<div class="btns flex">
+					<van-button class="x-btns" @click="sendMailCancel">取消</van-button>
+					<div class="s-line"></div>
+					<van-button class="c-btns" @click="sendMail">确认</van-button>
+				</div>
+			</van-dialog>
+		</div>
+	</div>
+{{include "/common/baiducc.html"}}
+</body>
+</html>

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

@@ -48,20 +48,9 @@
     }
 })(window);
 $(function(){
-	function getAjaxAdv () {
-			$.ajax({
-				type: 'POST',
-				url: '/publicapply/adLeague/exposure',
-				data: {
-						client: 'APP',
-						id: 'ad9',
-						position: '关注的项目列表页底部'
-				},
-				success: function(res) {
-						console.log(res)
-				}
-			})
-	}
+  //关注列表
+  getFollowList()
+  //
 	addEventListener('focus', function() {
 			if(document.activeElement = document.getElementById('iframeu6603899_0')) {
 					$.ajax({
@@ -81,80 +70,69 @@ $(function(){
 	var easyPopup = new EasyPopup("easypopup");
 	new FastClick(document.body);
 	var followLimit = {{.T.followLimit}};
-	$.post("/jyapp/follow/getList?t="+new Date().getTime(),null,function(r){
-		$(".divbtn").click(function(){
-			if(r.flag){
-				EasyAlert.show("最多可关注<br>"+followLimit+"个项目!");
-				return;
-			}
-			if(sessionStorage){
-				sessionStorage.followAddVersion="0";
-			}
-			window.location.href = "/jyapp/follow/add";
+
+	$(".jylistbottom").click(function(){
+		easyPopup.show("easypopup");
+	});
+
+	$("#cancel").click(function(){
+		easyPopup.hide("easypopup");
+	});
+	$("#sure").click(function(){
+		easyPopup.hide("easypopup");
+
+		var arrid = "";
+		$(".jyovertime").each(function(){
+			arrid +=","+$(this).attr("data-id");
 		});
-		if(!r.list){
-			return;
-		}
-		console.log(r)
-		var data = r.list;
-		$.ajax({
-			type: 'POST',
-			url: '/publicapply/bidcoll/power',
-			success: function(res) {
-					console.log(res)
-					// res.data.entniche = false
-					// res.data.member = false
-					// res.data.vip = 0
-					if(res.error_code == 0) {
-						if(!res.data.entniche && !res.data.member && res.data.vip <= 0){
-								if(data.length>0 ) {
-									$(".app-layout-footer").css("display","")
-									$('#entAdv').hide()
-									$(".app-layout-content-b").css("bottom",$(".app-layout-footer").height())
-									// ;(window.slotbydup = window.slotbydup || []).push({
-									// 		id: "u6603903",
-									// 		container: "_u2w0em6qe4",
-									// 		async: true
-									// });
-									// getAjaxAdv()
-								} else {
-									// ;(window.slotbydup = window.slotbydup || []).push({
-									// 	id: "u6603903",
-									// 	container: "_40lx7f736fw",
-									// 	async: true
-									// });
-									// getAjaxAdv()
-								}
-						} else {
-							if(data.length>0 ) {
-								$(".app-layout-footer").css("display","")
-								$('#entAdv').hide()
-								$(".app-layout-content-b").css("bottom",$(".app-layout-footer").height())
-							}
-						}
+		arrid = arrid.substring(1)
+		if (arrid.length>0){
+			$.ajax({
+				type:'post',
+				url:'/jyapp/swordfish/delovertimelist',
+				data:{arrid:arrid},
+				cache:false,
+				dataType:'json',
+				success:function(data){
+					if (data.flag == "T"){
+						EasyAlert.show("删除成功!");
+						window.location.reload();
+					}else{
+						EasyAlert.show("删除失败!");
 					}
-			},
-			error: function(err) {
-					console.log(err)
-			}
-	})
-		// addEventListener('blur', function() {
-		// 		if(document.activeElement = document.getElementById('iframeu6603903_0')) {
-		// 				$.ajax({
-		// 						type: 'POST',
-		// 						url: '/publicapply/adLeague/click',
-		// 						data: {
-		// 							client: 'APP',
-		// 							id: 'ad9',
-		// 							position: '关注的项目列表页底部'
-		// 						},
-		// 						success: function(res) {
-		// 								console.log(res)
-		// 						}
-		// 				})
-		// 		}  
-		// });
-		var html = "";
+				}
+			});
+		}else{
+			EasyAlert.show("暂无30天无更新的数据<br>可删除!");
+		}
+	});
+});
+
+//
+function receivePushMessageHandle(type,url){
+	if(type=="project"){
+		var array = url.split("__");
+		if(array.length > 2){
+			$("[data-followid='"+array[2]+"']").append('<i class="redspot"></i>');
+		}
+	}
+}
+
+// 大会员购买
+$(document).on('click','.pur_btn',function(){
+	location.href = '/jyapp/big/page/landingPage'
+})
+//
+function getFollowList(){
+  $.post("/bigmember/follow/project/list?t="+new Date().getTime(),null,function(r){
+    if (r.error_code==0&&r.data!=undefined){
+      formatInfo(r.data.List)
+    }
+  })
+}
+//
+function formatInfo(data){
+  	var html = "";
 		var fronthtml = "";
 		var lasthtml = "";
 		var frontarr = new Array();
@@ -174,7 +152,7 @@ $(function(){
 				frontarr.push(data[i]);
 			}
 		}
-		//30天内
+    //30天内
 		for(var f in frontarr){
 			var lastpushtime = frontarr[f]["l_lastpushtime"];
 			var rem = "";
@@ -201,11 +179,11 @@ $(function(){
 				indt ="<span class='indt'>"+frontarr[f]["s_industry"]+"</span>";
 			}
 			//地区
-			if (frontarr[f]["s_area"]!=""&&frontarr[f]["s_area"]!=undefined){
-				if(frontarr[f]["s_area"]=="A"){
+			if (frontarr[f]["area"]!=""&&frontarr[f]["area"]!=undefined){
+				if(frontarr[f]["area"]=="A"){
 					addr ="<span class='addr'>全国</span>";
 				}else{
-					addr ="<span class='addr'>"+frontarr[f]["s_area"]+"</span>";
+					addr ="<span class='addr'>"+frontarr[f]["area"]+"</span>";
 				}
 			}
 
@@ -214,9 +192,9 @@ $(function(){
 			if(frontarr[f]["i_apppushunread"]==1){
 				redSpot = '<i class="redspot"></i>';
 			}
-			fronthtml +="<li data-followid='"+frontarr[f]["followid"]+"' data-id='"+frontarr[f]["_id"]+"' Sort='"+lastpushtime+"'>"
+			fronthtml +="<li data-followid='"+frontarr[f]["fid"]+"' data-id='"+frontarr[f]["fid"]+"' Sort='"+lastpushtime+"'>"
 			+"<div class='jyfwlistno'>"+listno+".</div>"
-			+"<div class='jyfwlisttitle'>"+(frontarr[f]["s_projectname"]?frontarr[f]["s_projectname"]:frontarr[f]["s_projectcode"])+"</div>"
+			+"<div class='jyfwlisttitle'>"+(frontarr[f]["title"]?frontarr[f]["title"]:frontarr[f]["projectcode"])+"</div>"
 			+"<div style='clear:both;'></div>"+redSpot+"<img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/d.png?v={{Msg "seo" "version"}}' class='arrow-right'>"
 			+"<div class='jytimest'>"+rem
 			+addr+indt+tdf+"</li>";
@@ -249,11 +227,11 @@ $(function(){
 				indt ="<span class='indt'>"+lastarr[l]["s_industry"]+"</span>";
 			}
 			//地区
-			if (lastarr[l]["s_area"]!=""&&lastarr[l]["s_area"]!=undefined){
-				if(lastarr[l]["s_area"]=="A"){
+			if (lastarr[l]["area"]!=""&&lastarr[l]["area"]!=undefined){
+				if(lastarr[l]["area"]=="A"){
 					addr ="<span class='addr'>全国</span>";
 				}else{
-					addr ="<span class='addr'>"+lastarr[l]["s_area"]+"</span>";
+					addr ="<span class='addr'>"+lastarr[l]["area"]+"</span>";
 				}
 			}
 
@@ -263,9 +241,9 @@ $(function(){
 			if(lastarr[l]["i_apppushunread"]==1){
 				redSpot = '<i class="redspot"></i>';
 			}
-			lasthtml +="<li class='jyovertime' data-followid='"+lastarr[l]["followid"]+"' data-id='"+lastarr[l]["_id"]+"'>"
+			lasthtml +="<li class='jyovertime' data-followid='"+lastarr[l]["fid"]+"' data-id='"+lastarr[l]["fid"]+"'>"
 			+"<div class='jyfwlistno'>"+listno+".</div>"
-			+"<div class='jyfwlisttitle'>"+(lastarr[l]["s_projectname"]?lastarr[l]["s_projectname"]:lastarr[l]["s_projectcode"])+"</div>"
+			+"<div class='jyfwlisttitle'>"+(lastarr[l]["title"]?lastarr[l]["title"]:lastarr[l]["projectcode"])+"</div>"
 			+"<div style='clear:both;'></div>"+redSpot+"<img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/images/wx/d.png?v={{Msg "seo" "version"}}' class='arrow-right'>"
 			+"<div class='jytimest'>"+rem
 			+addr+indt+tdf+"</li>";
@@ -279,56 +257,8 @@ $(function(){
 			}
 			window.location.href = "/jyapp/follow/set/list/"+$(this).attr("data-id");
 		});
-	})
-
-	$(".jylistbottom").click(function(){
-		easyPopup.show("easypopup");
-	});
-
-	$("#cancel").click(function(){
-		easyPopup.hide("easypopup");
-	});
-	$("#sure").click(function(){
-		easyPopup.hide("easypopup");
-
-		var arrid = "";
-		$(".jyovertime").each(function(){
-			arrid +=","+$(this).attr("data-id");
-		});
-		arrid = arrid.substring(1)
-		if (arrid.length>0){
-			$.ajax({
-				type:'post',
-				url:'/jyapp/swordfish/delovertimelist',
-				data:{arrid:arrid},
-				cache:false,
-				dataType:'json',
-				success:function(data){
-					if (data.flag == "T"){
-						EasyAlert.show("删除成功!");
-						window.location.reload();
-					}else{
-						EasyAlert.show("删除失败!");
-					}
-				}
-			});
-		}else{
-			EasyAlert.show("暂无30天无更新的数据<br>可删除!");
-		}
-	});
-});
-function receivePushMessageHandle(type,url){
-	if(type=="project"){
-		var array = url.split("__");
-		if(array.length > 2){
-			$("[data-followid='"+array[2]+"']").append('<i class="redspot"></i>');
-		}
-	}
 }
-// 大会员购买
-$(document).on('click','.pur_btn',function(){
-	location.href = '/jyapp/big/page/landingPage'
-})
+
 </script>
 </head>
 <style>

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

@@ -786,7 +786,7 @@ function isFollow(){
 	$.ajax({
 		type: "POST",
 		url: "/jyapp/follow/checkCStatus",
-		data: {pcname: {{.T.projectname}},pccode: {{.T.projectcode}}},
+		data: {s_id:""},
 		async: false,
 		cache: false,
 		dataType: "json",

+ 72 - 51
src/jfw/modules/app/src/web/templates/weixin/wxinfocontent.html

@@ -1193,12 +1193,12 @@
                     }
                 }
                 var bigInfohtml =''
-
-                if({{.T.isVip}}||{{.T.member_status}}>0||{{.T.isEntniche}}){
-                    bigInfohtml +='<p style="width:4.2rem">'+bigWinnerTel+'</p><div class="border-tel"><div class="tel"></div></div><div class="tel-source">'+tel_source+'</div>'
-                }else if (checkFreeView({{.T.obj.winnertel}})||({{.T.obj.winner_enttel}}==="无权限")){
-                    bigInfohtml +='<div onclick="adv_statistics(this)" adv_name="app_article_getcontact" style="width:4.2rem"><a datalink="/jyapp/vipsubscribe/introducePage" style="color: rgb(44, 183, 202);">获取联系方式</a></div><div onclick="adv_statistics(this)" adv_name="app_article_getcontact" ><a class="border-tel" style="display:block;position: static;" datalink="/jyapp/vipsubscribe/introducePage"><div class="tel"></div></a></div>'
-                }
+              bigInfohtml +='<p style="width:4.2rem">'+bigWinnerTel+'</p><div class="border-tel"><div class="tel"></div></div><div class="tel-source">'+tel_source+'</div>'
+                // if({{.T.isVip}}||{{.T.member_status}}>0||{{.T.isEntniche}}){
+                //     bigInfohtml +='<p style="width:4.2rem">'+bigWinnerTel+'</p><div class="border-tel"><div class="tel"></div></div><div class="tel-source">'+tel_source+'</div>'
+                // }else if (checkFreeView({{.T.obj.winnertel}})||({{.T.obj.winner_enttel}}==="无权限")){
+                //     bigInfohtml +='<div onclick="adv_statistics(this)" adv_name="app_article_getcontact" style="width:4.2rem"><a datalink="/jyapp/vipsubscribe/introducePage" style="color: rgb(44, 183, 202);">获取联系方式</a></div><div onclick="adv_statistics(this)" adv_name="app_article_getcontact" ><a class="border-tel" style="display:block;position: static;" datalink="/jyapp/vipsubscribe/introducePage"><div class="tel"></div></a></div>'
+                // }
                 if(count>=5&&!isVip&&!isEntniche&&bigWinnerTel!=""&&isbid){
                     $(".bigwinnertel").append(bigInfohtml)
                 }
@@ -1890,51 +1890,72 @@
 
     function initToProjectPage(){
         $(".myfollow").on("tap", function(){
-            $.ajax({
-                type:"GET",
-                url:'/bigmember/use/isAdd',
-                success:function(res){
-                    // if (res.data.memberStatus <= 0 || res.data.power.indexOf(3) == -1) {
-                    //     window.isNoMember = true
-                    // }
-                    function goMemberFollowPage (url) {
-                        var objId = {
-                            fid:'',
-                            sid:''
-                        }
-                        if (followId != "" && jumpFlag){
-                            objId.fid = followId
-                            objId.sid = id
-                            sessionStorage.setItem('bigvip-fid',JSON.stringify(objId))
-                        }else{
-                            objId.fid = ''
-                            objId.sid = id
-                            sessionStorage.setItem('bigvip-fid',JSON.stringify(objId))
-                        }
-                        location.href = url
-                    }
-                    if(res.data.memberStatus <= 0 || hasServiceArr.indexOf(14) == -1){
-                        if (newEntNiche) {
-                            return goMemberFollowPage('/jyapp/big/page/client_follow_detail?from=client&industry=' + {{.T.obj.buyerclass}})
-                        }
-                        if (hsn){
-                            if (projectname != "" || projectcode != "" ){
-                                if(sessionStorage){
-                                    sessionStorage.version="3";
-                                }
-                                if (followId != "" && jumpFlag){
-                                    window.location.href="/jyapp/follow/set/list/"+followId;
-                                }else{
-                                    projectname = projectname.replace(/#/g,"%23").replace(/\?/g,"%3F")
-                                    window.location.href="/jyapp/follow/photo/"+id+"__"+projectname+"__"+projectcode;
-                                }
-                            }
-                        }
-                    }else{
-                        goMemberFollowPage('/jyapp/big/page/pro_follow_detail')
-                    }
-                }
-            })
+            function goMemberFollowPage (url) {
+              var objId = {
+                fid:'',
+                sid:''
+              }
+              if (followId != "" && jumpFlag){
+                objId.fid = followId
+                objId.sid = id
+                sessionStorage.setItem('bigvip-fid',JSON.stringify(objId))
+              }else{
+                objId.fid = ''
+                objId.sid = id
+                sessionStorage.setItem('bigvip-fid',JSON.stringify(objId))
+              }
+              location.href = url
+            }
+            if (newEntNiche) {
+              goMemberFollowPage('/jyapp/big/page/client_follow_detail?from=client&industry=' + {{.T.obj.buyerclass}})
+            }else{
+              goMemberFollowPage('/jyapp/big/page/pro_follow_detail')
+            }
+            // $.ajax({
+            //     type:"GET",
+            //     url:'/bigmember/use/isAdd',
+            //     success:function(res){
+            //         // if (res.data.memberStatus <= 0 || res.data.power.indexOf(3) == -1) {
+            //         //     window.isNoMember = true
+            //         // }
+            //         // function goMemberFollowPage (url) {
+            //         //     var objId = {
+            //         //         fid:'',
+            //         //         sid:''
+            //         //     }
+            //         //     if (followId != "" && jumpFlag){
+            //         //         objId.fid = followId
+            //         //         objId.sid = id
+            //         //         sessionStorage.setItem('bigvip-fid',JSON.stringify(objId))
+            //         //     }else{
+            //         //         objId.fid = ''
+            //         //         objId.sid = id
+            //         //         sessionStorage.setItem('bigvip-fid',JSON.stringify(objId))
+            //         //     }
+            //         //     location.href = url
+            //         // }
+            //         // if(res.data.memberStatus <= 0 || hasServiceArr.indexOf(14) == -1){
+            //         //     if (newEntNiche) {
+            //         //         return goMemberFollowPage('/jyapp/big/page/client_follow_detail?from=client&industry=' + {{.T.obj.buyerclass}})
+            //         //     }
+            //         //     if (hsn){
+            //         //         if (projectname != "" || projectcode != "" ){
+            //         //             if(sessionStorage){
+            //         //                 sessionStorage.version="3";
+            //         //             }
+            //         //             if (followId != "" && jumpFlag){
+            //         //                 window.location.href="/jyapp/follow/set/list/"+followId;
+            //         //             }else{
+            //         //                 projectname = projectname.replace(/#/g,"%23").replace(/\?/g,"%3F")
+            //         //                 window.location.href="/jyapp/follow/photo/"+id+"__"+projectname+"__"+projectcode;
+            //         //             }
+            //         //         }
+            //         //     }
+            //         // }else{
+            //         //     goMemberFollowPage('/jyapp/big/page/pro_follow_detail')
+            //         // }
+            //     }
+            // })
 
         });
     }

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

@@ -32,7 +32,7 @@ type config struct {
 	TimeSpan            int
 	RegWinner           string
 	OldSubscribeMoveTip int64
-	Customers           []customerInfo
+	Customers           []CustomerInfo
 	NewFreeUser         int64          //免费用户 -- 订阅升级新用户
 	FileUploadNum       map[string]int //每月附件下载次数
 	CreatePdfServer     string         //生成pdf文件服务地址
@@ -56,7 +56,7 @@ type config struct {
 	PotentialSwitch bool `json:"potentialSwitch"` //潜在客户 潜在竞争对手 新逻辑开关
 }
 
-type customerInfo struct {
+type CustomerInfo struct {
 	Name string `json:"name"`
 	Wxer string `json:"wxer"`
 }

+ 9 - 1
src/jfw/modules/bigmember/src/db.json

@@ -54,6 +54,14 @@
 			"maxOpenConns": 5,
 			"maxIdleConns": 5
 	    },
+      "base": {
+        "dBName": "base_service",
+        "address": "192.168.3.217:4000",
+        "userName": "root",
+        "passWord": "=PDT49#80Z!RVv52_z",
+        "maxOpenConns": 5,
+        "maxIdleConns": 5
+      },
 	    "push": {
 	        "dbName": "jianyu",
 	        "address": "192.168.3.11:3366",
@@ -65,4 +73,4 @@
     },
     "elascit_index":"projectset",
     "elascit_type":"projectset"
-}
+}

+ 14 - 0
src/jfw/modules/bigmember/src/db/db.go

@@ -28,6 +28,7 @@ type dbConf struct {
 	Mysql struct {
 		Main *mysqlConf
 		Push *mysqlConf
+		Base *mysqlConf
 	}
 	Elascit_index string
 	Elascit_type  string
@@ -66,6 +67,7 @@ var (
 	Mgo_Log     m.MongodbSim
 	Mgo_Bidding m.MongodbSim
 	Mysql       *mysql.Mysql
+	Base        *mysql.Mysql
 	Mysql_Push  *mysql.Mysql
 )
 
@@ -128,6 +130,18 @@ func init() {
 			}
 			Mysql.Init()
 		}
+		if DbConf.Mysql.Base != nil {
+			log.Println("初始化 mysql")
+			Base = &mysql.Mysql{
+				Address:      DbConf.Mysql.Base.Address,
+				UserName:     DbConf.Mysql.Base.UserName,
+				PassWord:     DbConf.Mysql.Base.PassWord,
+				DBName:       DbConf.Mysql.Base.DbName,
+				MaxOpenConns: DbConf.Mysql.Base.MaxOpenConns,
+				MaxIdleConns: DbConf.Mysql.Base.MaxIdleConns,
+			}
+			Base.Init()
+		}
 		if DbConf.Mongodb.Bidding != nil {
 			log.Println("初始化 mongodb bidding")
 			Mgo_Bidding = m.MongodbSim{

+ 245 - 257
src/jfw/modules/bigmember/src/entity/followEnterprise.go

@@ -36,9 +36,9 @@ func CreateEntFollowManager(userid string, pageFlag ...string) (*EntFollow, erro
 	}
 	if isBuy := bigMsg.CheckBigVipBackPower(defaultPageFlag); isBuy {
 		uid := qutil.If(bigMsg.Pid == "", userid, bigMsg.Pid).(string) //若为子账号则存储为主账号userid
-		return &EntFollow{true, uid, bigMsg.EntNum, "follow_entinfo_bigvip"}, nil
+		return &EntFollow{true, uid, bigMsg.EntNum, "follow_ent_monitor"}, nil
 	}
-	return &EntFollow{false, userid, config.Config.FollowProject.Normal, "jylab_followent"}, nil
+	return &EntFollow{false, userid, config.Config.FollowProject.Normal, "follow_ent_monitor"}, nil
 }
 
 // GetAssociationEnt 关注企业联想
@@ -58,7 +58,7 @@ func (this *EntFollow) GetAssociationEnt(entName string) ([]map[string]interface
 		})
 	}
 	//查询是否关注
-	followed, _ := db.Mgo.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, nil, `{"s_entname":1,"s_entId":1}`, false, -1, -1)
+	followed := db.Base.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, "s_entname,s_entId", "", -1, -1)
 	if followed != nil && len(*followed) > 0 { //有关注的项目
 		for _, follow := range *followed {
 			s_entId := qutil.ObjToString(follow["s_entId"])
@@ -79,179 +79,206 @@ func (this *EntFollow) GetAssociationEnt(entName string) ([]map[string]interface
 	return accMap, nil
 }
 
-//EntFollowedShow 详情页查询是否关注企业
-//followed 是否已关注
-//showFollow 是否展示关注(检索库存在相关企业信息时展示)
+// EntFollowedShow 详情页查询是否关注企业
+// followed 是否已关注
+// showFollow 是否展示关注(检索库存在相关企业信息时展示)
 func (this *EntFollow) EntFollowedShow(entId string) (followed, showFollow bool, err error) {
 	if entId == "" {
 		err = errors.New("未查询到企业")
 		return
 	}
-	if this.HasPower { //大会员付费用户
-		query := map[string]interface{}{"s_entId": entId, "s_userid": this.UserId}
-		fRes, _ := db.Mgo.FindOneByField(this.SaveTable, query, `{"i_apppushunread":1}`)
-		followed = false
-		if fRes != nil && len(*fRes) > 0 {
-			followed = true
-			//已关注,并且有未读标示
-			if qutil.IntAll((*fRes)["i_apppushunread"]) > 0 {
-				go db.Mgo.Update(this.SaveTable, query, map[string]interface{}{
-					"$set": map[string]interface{}{
-						"i_apppushunread": 0,
-					},
-				}, false, false)
-			}
-		}
-		if followed {
-			//查询是否可以关注
-			showFollow = true
-			return
-		}
-		//展示是否关注(部分企业不在企业库中 不展示关注按钮)
-		r := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query": {"term": {"_id": "%s"}},"_source": ["name"],"size": %d}`, entId, 1))
-		if r != nil && len(*r) > 0 {
-			showFollow = true
-		}
-	} else { //免费用户
-		//获取关注企业名字
-		entName := getEntNameById(entId)
-		if entName == "" {
-			return
+	query := map[string]interface{}{"s_entId": entId, "s_userid": this.UserId}
+	fRes := db.Base.FindOne(this.SaveTable, query, "i_apppushunread", "")
+	followed = false
+	if fRes != nil {
+		followed = true
+		//已关注,并且有未读标示
+		if qutil.IntAll((*fRes)["i_apppushunread"]) > 0 {
+			go db.Base.Update(this.SaveTable, query, map[string]interface{}{
+				"i_apppushunread": 0,
+			})
 		}
-
+	}
+	if followed {
+		//查询是否可以关注
+		showFollow = true
+		return
+	}
+	//展示是否关注(部分企业不在企业库中 不展示关注按钮)
+	r := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query": {"term": {"_id": "%s"}},"_source": ["name"],"size": %d}`, entId, 1))
+	if r != nil && len(*r) > 0 {
 		showFollow = true
-		query := map[string]interface{}{"s_entname": entName, "s_userid": this.UserId}
-		fRes, _ := db.Mgo.FindOneByField(this.SaveTable, query, `{"i_apppushunread":1}`)
-		if fRes != nil && len(*fRes) > 0 {
-			followed = true
-			//已关注,并且有未读标示
-			if qutil.IntAll((*fRes)["i_apppushunread"]) > 0 {
-				go db.Mgo.Update(this.SaveTable, query, map[string]interface{}{
-					"$set": map[string]interface{}{
-						"i_apppushunread": 0,
-					},
-				}, false, false)
-			}
-		}
 	}
 	return
 }
 
-//GetEntFollowList 我关注的企业列表
+// GetEntFollowList 我关注的企业列表
 // param A默认分组 B竞争对手 C合作伙伴 逗号分隔
 // db  0||nil 默认分组、1 竞争对手、2 合作伙伴、3 竞争对手和合作伙伴
 func (this *EntFollow) GetEntFollowList(pNum, pSize int, match, group string) (followData []map[string]interface{}, hasNext bool, count, total int, err error) {
-	var groupSearchArr []map[string]interface{}
-	if group != "" {
-		groupSearchArr = func() (searchArr []map[string]interface{}) {
-			if strings.Index(group, "A") > -1 {
-				searchArr = append(searchArr, []map[string]interface{}{{"i_group": map[string]interface{}{"$exists": 0}}, {"i_group": 0}}...)
-			}
-			if strings.Index(group, "B") > -1 && strings.Index(group, "C") > -1 {
-				searchArr = append(searchArr, []map[string]interface{}{{"i_group": 1},
-					{"i_group": 2}, {"i_group": 3}}...)
-			} else {
-				if strings.Index(group, "B") > -1 {
-					searchArr = append(searchArr, []map[string]interface{}{{"i_group": 1}, {"i_group": 3}}...)
-				} else if strings.Index(group, "C") > -1 {
-					searchArr = append(searchArr, []map[string]interface{}{{"i_group": 2}, {"i_group": 3}}...)
-				}
-			}
-			return
-		}()
-	}
-	query := map[string]interface{}{"s_userid": this.UserId}
-	//已关注数量查询
-	count = db.Mgo.Count(this.SaveTable, query)
-	if count == 0 {
+	flistSql := fmt.Sprintf(`SELECT id,f_capital,i_apppushunread,l_establishdate,l_lastpushtime,s_area,s_city,s_employeeno,s_entId,s_entname,i_group,s_phone FROM follow_ent_monitor WHERE  s_userid="%s" ORDER BY l_createtime DESC LIMIT %d,%d`, this.UserId, 0, this.MaxNum)
+	res := db.Base.SelectBySql(flistSql)
+	if res == nil || len(*res) == 0 {
+		//err = errors.New("查询异常")
 		return
 	}
-	if match = strings.TrimSpace(match); match != "" {
-		query["s_entname"] = map[string]interface{}{"$regex": match}
-	}
-	//当前筛选条件数量
-	if len(groupSearchArr) > 0 {
-		query["$or"] = groupSearchArr
-		total = db.Mgo.Count(this.SaveTable, query)
-		if total == 0 {
-			return
-		}
-	} else {
-		total = count
-	}
-
-	hasNext = (pNum+1)*pSize < total
-
-	if this.HasPower { //购买企业情报的用户直接查询
-		res, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1}`, `{"_id":1,"s_entname":1,"s_area":1,"s_city":1,"s_phone":1,"f_capital":1,"s_employeeno":1,"l_establishdate":1,"i_apppushunread":1,"s_entId":1,"l_lastpushtime":1,"i_group":1}`, false, pNum*pSize, pSize)
-		if res == nil || len(*res) == 0 {
-			err = errors.New("查询异常")
-			return
-		}
-		//followData = *res
-		//加密entId
-		for _, item := range *res {
-			entId := qutil.ObjToString(item["s_entId"])
-			if entId == "" { //dev3.6.2 前关注企业未存入企业id
-				//查询企业entid
-				entId = this.updateFollowed(item)
+	count = len(*res)
+	//var names []string
+	//for _, data := range *res {
+	//	if data["s_area"] == nil || data["s_city"] == nil || data["s_phone"] == nil || data["s_employeeno"] == nil || data["f_capital"] == nil {
+	//		//根据企业名字查询企业信息
+	//		names = append(names, qutil.ObjToString(data["s_entname"]))
+	//	}
+	//}
+	//
+	//fullData := getEntMsgByNames(names)
+	//if group != "" {
+	//		var igroup string
+	//		if strings.Index(group, "A") > -1 {
+	//			igroup = `i_group = 0 AND`
+	//		}
+	//		if strings.Index(group, "B") > -1 && strings.Index(group, "C") > -1 {
+	//			igroup = `(i_group = 1 OR i_group = 2 OR i_group = 3 ) AND`
+	//		} else {
+	//			if strings.Index(group, "B") > -1 {
+	//				igroup = `(i_group = 1 OR i_group = 3 ) AND`
+	//			} else if strings.Index(group, "C") > -1 {
+	//				igroup = `(i_group = 2 OR i_group = 3 ) AND`
+	//			}
+	//		}
+	//		flistSql = fmt.Sprintf(flistSql, igroup)
+	//		countSql = fmt.Sprintf(countSql, igroup)
+	//	} else {
+	//		flistSql = fmt.Sprintf(flistSql, ``)
+	//		countSql = fmt.Sprintf(countSql, ``)
+	//	}
+	// if match = strings.TrimSpace(match); match != "" {
+	//        flistSql = flistSql + `AND s_entname LIKE "%` + match + `%"`
+	//        countSql = countSql + `AND s_entname LIKE "%` + match + `%"`
+	//    }
+	var followDataAll []map[string]interface{}
+	for _, item := range *res {
+		//兼容从大会员变成免费用户时筛选条件数据错乱问题 取数据全部取出后在进行筛选过滤
+		if match != "" {
+			if !strings.Contains(qutil.InterfaceToStr(item["s_entname"]), match) {
+				continue
 			}
-			followData = append(followData, map[string]interface{}{
-				"fid":             util.EncodeId(mongodb.BsonIdToSId(item["_id"])),
-				"s_entId":         util.EncodeId(entId),
-				"f_capital":       item["f_capital"],
-				"l_establishdate": item["l_establishdate"],
-				"s_area":          item["s_area"],
-				"s_city":          item["s_city"],
-				"s_employeeno":    item["s_employeeno"],
-				"s_entname":       item["s_entname"],
-				"s_phone":         item["s_phone"],
-				"i_apppushunread": item["i_apppushunread"],
-				"l_lastpushtime":  item["l_lastpushtime"],
-				"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
-			})
 		}
-	} else { //免费用户根据企业名称 二次查询企业id、成立时间等数据
-		res, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1}`, `{"_id":1,"s_entname":1,"i_apppushunread":1,"l_lastpushtime":1,"i_group":1}`, false, pNum*pSize, pSize)
-		if res == nil || len(*res) == 0 {
-			err = errors.New("查询异常")
-			return
-		}
-		//根据企业名字查询企业信息
-		var names []string
-		for _, data := range *res {
-			names = append(names, qutil.ObjToString(data["s_entname"]))
-		}
-		fullData := getEntMsgByNames(names)
-
-		for _, item := range *res {
-			entName, _ := item["s_entname"].(string)
-			rowMap := map[string]interface{}{
-				"fid":             util.EncodeId(mongodb.BsonIdToSId(item["_id"])),
-				"s_entname":       entName,
-				"i_apppushunread": item["i_apppushunread"],
-				"l_lastpushtime":  item["l_lastpushtime"],
-				"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
+		if group != "" {
+			var iGroup bool
+			if strings.Contains(group, "A") && (qutil.IntAll(item["i_group"]) == 0) {
+				iGroup = true
 			}
-			if supplement, ok := fullData[entName]; ok {
-				//企业id
-				if entId, _ := supplement["_id"].(string); entId != "" {
-					rowMap["s_entId"] = util.EncodeId(entId)
-				}
-				rowMap["l_establishdate"] = supplement["establish_date"] //成立时间
-				rowMap["f_capital"] = supplement["capital"]              //注册资本
-				rowMap["s_area"] = supplement["company_area"]            //企业省份
-				rowMap["s_city"] = supplement["company_city"]            //城市
-				rowMap["s_phone"] = supplement["company_phone"]          //企业电话
+			if !iGroup && strings.Contains(group, "B") && (qutil.IntAll(item["i_group"]) == 1 || qutil.IntAll(item["i_group"]) == 3) {
+				iGroup = true
+			}
+			if !iGroup && strings.Contains(group, "C") && (qutil.IntAll(item["i_group"]) == 2 || qutil.IntAll(item["i_group"]) == 3) {
+				iGroup = true
 			}
-			followData = append(followData, rowMap)
+			if !iGroup {
+				continue
+			}
+		}
+		entId := qutil.ObjToString(item["s_entId"])
+		if entId == "" { //dev3.6.2 前关注企业未存入企业id
+			//查询企业entid
+			entId = this.updateFollowed(item)
+		}
+
+		rowMap := map[string]interface{}{
+			"fid":             util.EncodeId(qutil.InterfaceToStr(item["id"])),
+			"s_entId":         util.EncodeId(entId),
+			"f_capital":       item["f_capital"],
+			"l_establishdate": item["l_establishdate"],
+			"s_area":          item["s_area"],
+			"s_city":          item["s_city"],
+			"s_employeeno":    item["s_employeeno"],
+			"s_entname":       item["s_entname"],
+			"s_phone":         item["s_phone"],
+			"i_apppushunread": item["i_apppushunread"],
+			"l_lastpushtime":  item["l_lastpushtime"],
+			"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
 		}
+		followDataAll = append(followDataAll, rowMap)
 	}
+	total = len(followDataAll)
+	//分页
+	if (pNum+1)*pSize >= len(followDataAll) {
+		followData = followDataAll[pNum*pSize:]
+	} else {
+		followData = followDataAll[pNum*pSize : (pNum+1)*pSize]
+	}
+	hasNext = qutil.If((pNum+1)*pSize >= len(followDataAll), false, true).(bool)
+	/*if this.HasPower { //购买企业情报的用户直接查询
+	  	res, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1}`, `{"_id":1,"s_entname":1,"s_area":1,"s_city":1,"s_phone":1,"f_capital":1,"s_employeeno":1,"l_establishdate":1,"i_apppushunread":1,"s_entId":1,"l_lastpushtime":1,"i_group":1}`, false, pNum*size, pSize)
+	  	if res == nil || len(*res) == 0 {
+	  		err = errors.New("查询异常")
+	  		return
+	  	}
+	  	//followData = *res
+	  	//加密entId
+	  	for _, item := range *res {
+	  		entId := qutil.ObjToString(item["s_entId"])
+	  		if entId == "" { //dev3.6.2 前关注企业未存入企业id
+	  			//查询企业entid
+	  			entId = this.updateFollowed(item)
+	  		}
+	  		followData = append(followData, map[string]interface{}{
+	  			"fid":             util.EncodeId(mongodb.BsonIdToSId(item["_id"])),
+	  			"s_entId":         util.EncodeId(entId),
+	  			"f_capital":       item["f_capital"],
+	  			"l_establishdate": item["l_establishdate"],
+	  			"s_area":          item["s_area"],
+	  			"s_city":          item["s_city"],
+	  			"s_employeeno":    item["s_employeeno"],
+	  			"s_entname":       item["s_entname"],
+	  			"s_phone":         item["s_phone"],
+	  			"i_apppushunread": item["i_apppushunread"],
+	  			"l_lastpushtime":  item["l_lastpushtime"],
+	  			"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
+	  		})
+	  	}
+	  } else { //免费用户根据企业名称 二次查询企业id、成立时间等数据
+	  	res, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1}`, `{"_id":1,"s_entname":1,"i_apppushunread":1,"l_lastpushtime":1,"i_group":1}`, false, pNum*size, pSize)
+	  	if res == nil || len(*res) == 0 {
+	  		err = errors.New("查询异常")
+	  		return
+	  	}
+	  	//根据企业名字查询企业信息
+	  	var names []string
+	  	for _, data := range *res {
+	  		names = append(names, qutil.ObjToString(data["s_entname"]))
+	  	}
+	  	fullData := getEntMsgByNames(names)
+
+	  	for _, item := range *res {
+	  		entName, _ := item["s_entname"].(string)
+	  		rowMap := map[string]interface{}{
+	  			"fid":             util.EncodeId(mongodb.BsonIdToSId(item["_id"])),
+	  			"s_entname":       entName,
+	  			"i_apppushunread": item["i_apppushunread"],
+	  			"l_lastpushtime":  item["l_lastpushtime"],
+	  			"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
+	  		}
+	  		if supplement, ok := fullData[entName]; ok {
+	  			//企业id
+	  			if entId, _ := supplement["_id"].(string); entId != "" {
+	  				rowMap["s_entId"] = util.EncodeId(entId)
+	  			}
+	  			rowMap["l_establishdate"] = supplement["establish_date"] //成立时间
+	  			rowMap["f_capital"] = supplement["capital"]              //注册资本
+	  			rowMap["s_area"] = supplement["company_area"]            //企业省份
+	  			rowMap["s_city"] = supplement["company_city"]            //城市
+	  			rowMap["s_phone"] = supplement["company_phone"]          //企业电话
+	  		}
+	  		followData = append(followData, rowMap)
+	  	}
+	  }*/
 	return
 }
 
 func (this *EntFollow) GetEntFollowAndChangeList(num int) (followData []map[string]interface{}, err error) {
-	res, _ := db.Mgo.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, `{"l_lastpushtime":-1}`, `{"s_entname":1,"i_apppushunread":1,"s_entId":1,"l_lastpushtime":1}`, false, 0, num)
+	res := db.Base.Find(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}, "l_lastpushtime,s_entname,i_apppushunread,s_entId,l_lastpushtime", ``, 0, num)
 	if res == nil || len(*res) == 0 {
 		return
 	}
@@ -295,7 +322,7 @@ func (this *EntFollow) GetEntFollowAndChangeList(num int) (followData []map[stri
 }
 
 func (this *EntFollow) updateFollowed(follow map[string]interface{}) string {
-	folloid, entName := mongodb.BsonIdToSId(follow["_id"]), qutil.ObjToString(follow["s_entname"])
+	folloid, entName := follow["id"], qutil.ObjToString(follow["s_entname"])
 	if entName == "" {
 		return ""
 	}
@@ -326,89 +353,61 @@ func (this *EntFollow) updateFollowed(follow map[string]interface{}) string {
 	}
 	//更新企业情报表
 	if entId != "" && folloid != "" {
-		go db.Mgo.UpdateById(this.SaveTable, folloid, map[string]interface{}{"$set": map[string]interface{}{"s_entId": entId}})
+		go db.Base.Update(this.SaveTable, map[string]interface{}{"id": folloid}, map[string]interface{}{"s_entId": entId})
 	}
 	return entId
 }
 
-//AddFollowEnt 添加关注企业
-
+// AddFollowEnt 添加关注企业
 func (this *EntFollow) AddFollowEnt(entId, group string, getOldData ...bool) error {
 	groupFlag := getGroup(group)
-	if this.HasPower {
-		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entId": entId}) > 0 {
-			return errors.New("已关注此企业")
-		}
-		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}) >= this.MaxNum {
-			return errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", this.MaxNum))
-		}
-		res, _ := db.Mgo_Ent.FindOneByField("qyxy_std", map[string]interface{}{"_id": entId}, `{"company_name":1,"company_area":1,"company_city":1,"establish_date":1,"capital":1,"employee_no":1,"company_phone":1}`)
-		if res == nil || len(*res) == 0 {
-			return errors.New("查找企业异常")
-		}
-		followData := map[string]interface{}{
-			"s_entId":        mongodb.BsonIdToSId((*res)["_id"]), //dev3.6.2 企业画像根据entId查询
-			"s_entname":      (*res)["company_name"],
-			"s_area":         qutil.If((*res)["company_area"] == nil, "", (*res)["company_area"]),
-			"s_city":         qutil.If((*res)["company_city"] == nil, "", (*res)["company_city"]),
-			"s_phone":        qutil.If((*res)["company_phone"] == nil, "", (*res)["company_phone"]),
-			"f_capital":      qutil.If((*res)["capital"] == nil, 0.0, (*res)["capital"]),
-			"s_employeeno":   qutil.If((*res)["employee_no"] == nil, 0, (*res)["employee_no"]),
-			"l_createdate":   time.Now().Unix(),
-			"s_userid":       this.UserId,
-			"l_lastpushtime": time.Now().Unix(),
-		}
+	//if this.HasPower {
+	if db.Base.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entId": entId}) > 0 {
+		return errors.New("已关注此企业")
+	}
+	if db.Base.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}) >= qutil.Int64All(this.MaxNum) {
+		return errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", this.MaxNum))
+	}
+	res, _ := db.Mgo_Ent.FindOneByField("qyxy_std", map[string]interface{}{"_id": entId}, `{"company_name":1,"company_area":1,"company_city":1,"establish_date":1,"capital":1,"employee_no":1,"company_phone":1}`)
+	if res == nil || len(*res) == 0 {
+		return errors.New("查找企业异常")
+	}
+	followData := map[string]interface{}{
+		"s_entId":        mongodb.BsonIdToSId((*res)["_id"]), //dev3.6.2 企业画像根据entId查询
+		"s_entname":      (*res)["company_name"],
+		"s_area":         qutil.If((*res)["company_area"] == nil, "", (*res)["company_area"]),
+		"s_city":         qutil.If((*res)["company_city"] == nil, "", (*res)["company_city"]),
+		"s_phone":        qutil.If((*res)["company_phone"] == nil, "", (*res)["company_phone"]),
+		"f_capital":      qutil.If((*res)["capital"] == nil, 0.0, (*res)["capital"]),
+		"s_employeeno":   qutil.If((*res)["employee_no"] == nil, 0, (*res)["employee_no"]),
+		"l_createtime":   time.Now().Unix(),
+		"s_userid":       this.UserId,
+		"l_lastpushtime": time.Now().Unix(),
+	}
 
-		if len(getOldData) > 0 && getOldData[0] {
-			followent, ok := db.Mgo.FindOne("jylab_followent", map[string]interface{}{"s_userid": this.UserId, "s_entname": (*res)["company_name"]})
-			if followent != nil && ok && len(*followent) > 0 {
-				followData["s_id"] = qutil.If((*followent)["s_id"] == nil, "", (*followent)["s_id"])
-				followData["l_lastpushtime"] = qutil.If((*followent)["s_id"] == nil, 0, (*followent)["l_lastpushtime"])
-			}
+	if len(getOldData) > 0 && getOldData[0] {
+		followent := db.Base.FindOne(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entname": (*res)["company_name"]}, "s_id,l_lastpushtime", "")
+		if followent != nil && len(*followent) > 0 {
+			followData["s_id"] = qutil.If((*followent)["s_id"] == nil, "", (*followent)["s_id"])
+			followData["l_lastpushtime"] = qutil.If((*followent)["s_id"] == nil, 0, (*followent)["l_lastpushtime"])
 		}
+	}
 
-		establishdate := qutil.ObjToString((*res)["establish_date"])
-		if establishdate != "" {
-			t, err := time.Parse(qutil.Date_Short_Layout, establishdate)
-			if err == nil {
-				followData["l_establishdate"] = t.Unix()
-			}
+	establishdate := qutil.ObjToString((*res)["establish_date"])
+	if establishdate != "" {
+		t, err := time.Parse(qutil.Date_Short_Layout, establishdate)
+		if err == nil {
+			followData["l_establishdate"] = t.Unix()
 		}
+	}
 
-		//设置分组
-		if groupFlag > -1 {
-			followData["i_group"] = groupFlag
-		}
-		followId := db.Mgo.Save(this.SaveTable, followData)
-		if followId == "" || len(followId) == 0 {
-			return errors.New("保存关注企业异常")
-		}
-	} else { //免费用户关注企业
-		entName := getEntNameById(entId)
-		if entName == "" {
-			return errors.New("企业信息异常")
-		}
-		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entname": entName}) > 0 {
-			return errors.New("已关注此企业")
-		}
-		if db.Mgo.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}) >= this.MaxNum {
-			return errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", this.MaxNum))
-		}
-		followData := map[string]interface{}{
-			"s_entname":       entName,
-			"s_userid":        this.UserId,
-			"l_createtime":    time.Now().Unix(),
-			"l_lastpushtime":  time.Now().Unix(),
-			"i_apppushunread": 0,
-		}
-		//设置分组
-		if groupFlag > -1 {
-			followData["i_group"] = groupFlag
-		}
-		followId := db.Mgo.Save(this.SaveTable, followData)
-		if followId == "" || len(followId) == 0 {
-			return errors.New("保存关注企业异常")
-		}
+	//设置分组
+	if groupFlag > -1 {
+		followData["i_group"] = groupFlag
+	}
+	followId := db.Base.Insert(this.SaveTable, followData)
+	if followId == -1 {
+		return errors.New("保存关注企业异常")
 	}
 	go func(userId string) {
 		//首页潜在竞争对手缓存
@@ -445,7 +444,7 @@ func getGroup(groupStr string) (s int) {
 	return
 }
 
-//格式化分组字段
+// 格式化分组字段
 func parseGroupStr(gFlag int) string {
 	switch gFlag {
 	case 1:
@@ -459,19 +458,19 @@ func parseGroupStr(gFlag int) string {
 	}
 }
 
-//ChangeFollowGroup 更换关注企业分组
+// ChangeFollowGroup 更换关注企业分组
 func (this *EntFollow) ChangeFollowGroup(fid, group string) error {
 	groupValue := getGroup(group)
 	if groupValue == -1 {
 		groupValue = 0
 	}
-	if !db.Mgo.UpdateById(this.SaveTable, fid, map[string]interface{}{"$set": map[string]interface{}{"i_group": groupValue}}) {
+	if !db.Base.Update(this.SaveTable, map[string]interface{}{"id": fid}, map[string]interface{}{"i_group": groupValue}) {
 		return fmt.Errorf("设置分组失败")
 	}
 	return nil
 }
 
-//删除关注企业
+// 删除关注企业
 func (this *EntFollow) DelFollowEnt(entId, fid string) error {
 	if entId == "" && fid == "" {
 		return fmt.Errorf("筛选条件异常")
@@ -479,34 +478,21 @@ func (this *EntFollow) DelFollowEnt(entId, fid string) error {
 	query := map[string]interface{}{
 		"s_userid": this.UserId,
 	}
-	if this.HasPower {
-		if entId != "" {
-			query["s_entId"] = entId
-		}
-		if fid != "" {
-			query["_id"] = mongodb.StringTOBsonId(fid)
-		}
-		if db.Mgo.Delete(this.SaveTable, query) < 0 {
-			return errors.New("取关企业失败")
-		}
+	if entId != "" {
+		query["s_entId"] = entId
+	}
+	if fid != "" {
+		query["id"] = fid
+	}
+	data := db.Base.FindOne(this.SaveTable, query, "id,s_entId,s_entname,s_area,s_city,s_phone,f_capital,s_employeeno,l_createtime,s_userid,l_lastpushtime", "")
+	if data != nil && db.Base.Delete(this.SaveTable, query) {
+		(*data)["s_followid"] = (*data)["id"]
+		delete(*data, "id")
+		db.Mgo.Save("jylab_followent_back", data)
 	} else {
-		if fid != "" {
-			query["_id"] = mongodb.StringTOBsonId(fid)
-		} else if entId != "" {
-			if entName := getEntNameById(entId); entName != "" {
-				query["s_entname"] = entName
-			} else {
-				return fmt.Errorf("未获取到企业信息")
-			}
-		}
-		data, ok := db.Mgo.FindOne("jylab_followent", query)
-		if ok && data != nil && len(*data) > 0 && db.Mgo.Del("jylab_followent", map[string]interface{}{"_id": (*data)["_id"]}) {
-			(*data)["s_followid"] = mongodb.BsonIdToSId((*data)["_id"])
-			db.Mgo.Save("jylab_followent_back", data)
-		} else {
-			return fmt.Errorf("操作失败")
-		}
+		return errors.New("取关企业失败")
 	}
+
 	go func(userId string) {
 		//首页潜在竞争对手缓存
 		redis.Del("other", fmt.Sprintf("CRIndex_R_%s", userId))
@@ -514,8 +500,7 @@ func (this *EntFollow) DelFollowEnt(entId, fid string) error {
 	return nil
 }
 
-//企业情报====================================================================
-
+// 企业情报====================================================================
 func (this *EntFollow) GetEntIdByName(entName string) (string, error) {
 	if entName == "" {
 		return "", errors.New("企业名称异常")
@@ -527,7 +512,7 @@ func (this *EntFollow) GetEntIdByName(entName string) (string, error) {
 	return entId, nil
 }
 
-//GetEntChangeList 获取企业变更信息
+// GetEntChangeList 获取企业变更信息
 func (this *EntFollow) GetEntChangeList(entId string, showPart int) ([]map[string][]EntChangeSort, int, error) {
 	if entId == "" {
 		return nil, -1, errors.New("企业名称异常")
@@ -577,7 +562,7 @@ func (this *ArrEntChanges) Less(i, j int) bool {
 	return (*this)[i].Change_date > (*this)[j].Change_date
 }
 
-//企业变更信息 初始化排序
+// 企业变更信息 初始化排序
 func InitializeSort(data []map[string]interface{}) []map[string][]EntChangeSort {
 	array := &ArrEntChanges{}
 	for _, v := range data {
@@ -619,6 +604,9 @@ func getEntNameById(entId string) (entName string) {
 }
 
 func getEntMsgByNames(names []string) (detail map[string]map[string]interface{}) {
+	if len(names) == 0 {
+		return nil
+	}
 	detail = make(map[string]map[string]interface{})
 	names_str := `"` + strings.Join(names, `","`) + `"`
 	rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"must":[{"terms":{"company_name":[%s]}}]}},"_source":["company_name","_id","company_area","company_city","company_phone","capital","establish_date"],"size":%d}`, names_str, len(names)))

+ 263 - 180
src/jfw/modules/bigmember/src/entity/followProject.go

@@ -7,12 +7,13 @@ import (
 	"errors"
 	"fmt"
 	"log"
-	. "mongodb"
 	qutil "qfw/util"
 	"qfw/util/elastic"
 	"qfw/util/jy"
 	"qfw/util/redis"
 	"qfw/util/rpc"
+	"sort"
+	"strconv"
 	"strings"
 	"sync"
 	"time"
@@ -30,11 +31,20 @@ func CreateProjectFollowManager(userid string, mustBuy ...bool) (*ProjectFollow,
 	if len(mustBuy) > 0 && !isBuy {
 		return nil, errors.New("非法请求")
 	}
-	if isBuy { //收费版
-		uid := qutil.If(bigMsg.Pid == "", userid, bigMsg.Pid).(string) //若为子账号则存储为主账号userid
-		return &ProjectFollow{true, uid, bigMsg.ProNum, "follow_project_bigvip"}, nil
+	//兼容商机管理用户存储
+	var (
+		buy    = true
+		proNum = config.Config.FollowProject.Normal
+	)
+	if isBuy {
+		if bigMsg.Pid != "" { //若为子账号则存储为主账号userid
+			userid = bigMsg.Pid
+		}
+		proNum = bigMsg.ProNum
+	} else if bigMsg.EntnicheStatus != 1 { //无权限且非商机管理用户修改
+		buy = false
 	}
-	return &ProjectFollow{false, userid, config.Config.FollowProject.Normal, "follow_project"}, nil //免费版
+	return &ProjectFollow{buy, userid, proNum, "follow_project_monitor"}, nil
 }
 
 type ProjectFollow struct {
@@ -71,69 +81,75 @@ func (this *ProjectFollow) SaveProject(sid string) (string, error) {
 		return "", err
 	}
 	data := map[string]interface{}{}
-	projectName, nowTimeStamp := "", time.Now().Unix()
+	nowTimeStamp := time.Now().Unix()
 
-	if this.Buy {
-		//if this.VipStatus > 0 && this.VipStatus != 4 { //大会员用户
-		data = map[string]interface{}{
-			"s_id":           sid,          //信息id
-			"s_userid":       this.UserId,  //用户id
-			"i_remind":       0,            //开标提醒
-			"l_createtime":   nowTimeStamp, //关注时间
-			"l_lastpushtime": nowTimeStamp, //关注时间
-			"a_visited":      []string{},   //浏览记录
-		}
-	} else { //非大会员用户和试用会员
-		//根据信息id查询项目信息
-		res, _ := db.Mgo_Bidding.FindById("bidding", sid, `{"publishtime":1,"projectname":1,area":1,"title":1,"href":1,"toptype":1,"subtype":1}`)
+	//if this.Buy {
+	//if this.VipStatus > 0 && this.VipStatus != 4 { //大会员用户
+	data = map[string]interface{}{
+		"s_id":           sid,          //信息id
+		"s_userid":       this.UserId,  //用户id
+		"i_remind":       0,            //开标提醒
+		"l_createtime":   nowTimeStamp, //关注时间
+		"l_lastpushtime": nowTimeStamp, //关注时间
+		"a_visited":      "",           //浏览记录
+	}
+	//} else { //非大会员用户和试用会员
+	//	根据信息id查询项目信息
+	res, _ := db.Mgo_Bidding.FindById("bidding", sid, `{"publishtime":1,"projectname":1,area":1,"title":1,"href":1,"toptype":1,"subtype":1}`)
+	if res == nil || len(*res) == 0 {
+		res, _ = db.Mgo_Bidding.FindById("bidding_back", sid, `{"publishtime":1,"projectname":1,area":1,"title":1,"href":1,"toptype":1,"subtype":1}`)
 		if res == nil || len(*res) == 0 {
-			res, _ = db.Mgo_Bidding.FindById("bidding_back", sid, `{"publishtime":1,"projectname":1,area":1,"title":1,"href":1,"toptype":1,"subtype":1}`)
-			if res == nil || len(*res) == 0 {
-				return "", errors.New("项目关注异常")
-			}
-		}
-		projectName = qutil.ObjToString((*res)["projectname"])
-		data = map[string]interface{}{
-			"s_id":          sid,          //信息id
-			"s_userid":      this.UserId,  //用户id
-			"i_remind":      0,            //开标提醒
-			"l_createtime":  nowTimeStamp, //关注时间
-			"a_visited":     []string{},   //浏览记录
-			"s_projectname": projectName,
-			"s_area":        (*res)["area"],
-			"l_publishtime": (*res)["publishtime"],
-			"a_relationinfo": []map[string]interface{}{
-				{
-					"s_title":       (*res)["title"],
-					"s_url":         (*res)["href"],
-					"s_id":          sid,
-					"s_eid":         util.EncodeId(sid),
-					"l_publishtime": (*res)["publishtime"],
-					"s_subtype":     (*res)["subtype"],
-					"s_toptype":     (*res)["toptype"],
-				},
-			},
+			return "", errors.New("项目关注异常")
 		}
 	}
-	followId := db.Mgo.Save(this.SaveTable, data)
-	if projectName != "" && followId != "" { //非大会员用户调用rpc 更新推送项目
+	projectName := qutil.ObjToString((*res)["projectname"])
+	//	data = map[string]interface{}{
+	//		"s_id":          sid,          //信息id
+	//		"s_userid":      this.UserId,  //用户id
+	//		"i_remind":      0,            //开标提醒
+	//		"l_createtime":  nowTimeStamp, //关注时间
+	//		"a_visited":     []string{},   //浏览记录
+	//		"s_projectname": projectName,
+	//		"s_area":        (*res)["area"],
+	//		"l_publishtime": (*res)["publishtime"],
+	//		"a_relationinfo": []map[string]interface{}{
+	//			{
+	//				"s_title":       (*res)["title"],
+	//				"s_url":         (*res)["href"],
+	//				"s_id":          sid,
+	//				"s_eid":         util.EncodeId(sid),
+	//				"l_publishtime": (*res)["publishtime"],
+	//				"s_subtype":     (*res)["subtype"],
+	//				"s_toptype":     (*res)["toptype"],
+	//			},
+	//		},
+	//	}
+	//}
+	id := db.Base.Insert(this.SaveTable, data)
+	followId := strconv.FormatInt(id, 10)
+	if id == 0 {
+		followId = ""
+	}
+	if !this.Buy && projectName != "" && followId != "" { //非大会员用户调用rpc 更新推送项目
 		go util.FollowPush(&rpc.FollowPush{
 			ProjectName: projectName,
 			ProjectCode: "",
 			InfoId:      sid,
-			FollowId:    followId,
+			FollowId:    qutil.ObjToString(followId),
 			UserId:      this.UserId,
 		})
 	}
-	if len(followId) == 0 {
+
+	if followId == "" {
 		return "", errors.New("关注项目出错")
 	}
+
 	return followId, nil
 }
 
-//项目关注上限校验
+// 项目关注上限校验
 func (this *ProjectFollow) followMaxCheck() error {
-	if db.Mgo.Count(this.SaveTable, `{"s_userid":"`+this.UserId+`"}`) >= this.MaxNum {
+	if db.Base.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId}) >= qutil.Int64All(this.MaxNum) {
 		return errors.New(fmt.Sprintf("您关注的项目已达%d个,无法关注更多", this.MaxNum))
 	}
 	return nil
@@ -145,14 +161,18 @@ func (this *ProjectFollow) FollowedCheck(sid string) (string, bool, error) {
 	if len(*list) == 0 {
 		return "", false, errors.New("未找到项目信息")
 	}
-	followArr, _ := db.Mgo.Find(this.SaveTable, `{"s_userid":"`+this.UserId+`"}`, `{"_id":1}`, `{"s_id":1}`, false, -1, -1)
+	query := map[string]interface{}{
+		"s_userid": this.UserId,
+	}
+	followArr := db.Base.Find(this.SaveTable, query, `id,s_id`, "", -1, 0)
 	if followArr == nil || len(*followArr) == 0 {
 		return "", true, nil
 	}
-	var followMap = map[string]string{}
+	followMap := make(map[string]string)
 	for _, followInof := range *followArr {
 		if fidStr, ok := followInof["s_id"].(string); ok {
-			followMap[fidStr] = BsonIdToSId(followInof["_id"])
+			str := qutil.InterfaceToStr(followInof["id"])
+			followMap[fidStr] = str
 		}
 	}
 	projectInfo := (*list)[0]
@@ -173,20 +193,26 @@ func (this *ProjectFollow) FollowedCheck(sid string) (string, bool, error) {
 // GetDetailByFid 已关注查询信息
 func (this *ProjectFollow) GetDetailByFid(fid string) (returnData map[string]interface{}, projectInfo map[string]interface{}, err error) {
 	isDel := false
-	fields := `{"s_id":1,"i_remind":1,a_visited":1,"l_bidopentime":1,"l_remindtime":1,"a_relationinfo":1,"s_projectname":1,"i_apppushunread":1}`
-	data, _ := db.Mgo.FindById(this.SaveTable, fid, fields)
+	query := map[string]interface{}{
+		"id": fid,
+	}
+	data := db.Base.FindOne(this.SaveTable, query, "", "")
 	if data == nil || len(*data) == 0 {
-		data, _ = db.Mgo.FindOneByField(this.SaveTable+"_back", `{"s_followid":"`+fid+`"}`, fields)
+		querys := map[string]interface{}{
+			"s_followid": fid,
+		}
+		data, _ = db.Mgo.FindOne(this.SaveTable+"_back", querys)
 		isDel = true
 	}
 	if data == nil || len(*data) == 0 {
 		return nil, nil, errors.New("未找到关注项目信息")
 	}
 	returnData = map[string]interface{}{}
-	returnData["isfollow"] = !isDel                      //是否关注
-	returnData["sid"] = (*data)["s_id"]                  //关注项目的来源信息id
-	returnData["remind"] = (*data)["i_remind"]           //是否开启提醒
-	returnData["visit"] = (*data)["a_visited"]           //是否开启提醒
+	returnData["isfollow"] = !isDel            //是否关注
+	returnData["sid"] = (*data)["s_id"]        //关注项目的来源信息id
+	returnData["remind"] = (*data)["i_remind"] //是否开启提醒
+	visit := qutil.InterfaceToStr((*data)["a_visited"])
+	returnData["visit"] = strings.Split(visit, ",")      //是否开启提醒
 	returnData["bidopentime"] = (*data)["l_bidopentime"] //开标时间
 	returnData["remindtime"] = (*data)["l_remindtime"]   //提醒时间
 	if qutil.ObjToString((*data)["s_id"]) == "" {        //兼容旧版本手动添加的关注
@@ -205,12 +231,8 @@ func (this *ProjectFollow) GetDetailByFid(fid string) (returnData map[string]int
 	}
 	//更新未已读
 	if !isDel && qutil.IntAll((*data)["i_apppushunread"]) > 0 {
-		go db.Mgo.UpdateById(this.SaveTable, fid, map[string]interface{}{
-			"$set": map[string]interface{}{
-				"i_apppushunread": 0,
-				"s_userid":        this.UserId,
-			},
-		})
+		go db.Base.Update(this.SaveTable, map[string]interface{}{"id": fid}, map[string]interface{}{
+			"i_apppushunread": 0})
 	}
 	return
 }
@@ -234,10 +256,11 @@ func (this *ProjectFollow) GetProjectDetailBySid(sid string) (res map[string]int
 	thisList := []map[string]interface{}{}
 	tmpList, ok := finalDate["list"].([]interface{})
 	if ok && len(tmpList) > 0 {
-		for _, v := range qutil.ObjArrToMapArr(tmpList) {
+		for i := len(qutil.ObjArrToMapArr(tmpList)) - 1; i > 0; i-- {
 			if len(thisList) >= 50 {
 				break
 			}
+			v := qutil.ObjArrToMapArr(tmpList)[i]
 			thisList = append(thisList, map[string]interface{}{
 				"l_publishtime": v["publishtime"],
 				"s_title":       v["title"],
@@ -248,6 +271,11 @@ func (this *ProjectFollow) GetProjectDetailBySid(sid string) (res map[string]int
 				"s_id":          v["infoid"],
 			})
 		}
+		if len(thisList) > 0 {
+			sort.Slice(thisList, func(i, j int) bool {
+				return qutil.Int64All(thisList[i]["l_publishtime"]) < qutil.Int64All(thisList[j]["l_publishtime"])
+			})
+		}
 	}
 	finalDate["list"] = thisList
 	//redis缓存一星期
@@ -263,112 +291,176 @@ func (this *ProjectFollow) SetFollowRead(sid, fid, flag string) bool {
 		})
 	}
 	//项目关注详情页
-	return db.Mgo.UpdateById(this.SaveTable, fid, map[string]interface{}{
-		"$addToSet": map[string]interface{}{"a_visited": sid},
-	})
+	query := map[string]interface{}{
+		"id": fid,
+	}
+	data := db.Base.FindOne(this.SaveTable, query, "", "")
+	if data == nil || len(*data) < 1 {
+		return false
+	}
+	visited, _ := (*data)["a_visited"].(string)
+	vis := []string{}
+	vis = append(vis, visited, sid)
+	return db.Base.Update(this.SaveTable, query, map[string]interface{}{"a_visited": strings.Join(vis, ",")})
 }
 
+var (
+	Entniche_customer      = "entniche_customer"
+	Entniche_user_customer = "entniche_user_customer"
+)
+
 // GetFollowList 获取列表页
-func (this *ProjectFollow) GetFollowList(pNum, pSize int) (followData []map[string]interface{}, hasNext bool, count int, err error) {
+func (this *ProjectFollow) GetFollowList(pNum, pSize, entUserId int) (followData []map[string]interface{}, hasNext bool, count int, err error) {
 	query := map[string]interface{}{
 		"s_userid": this.UserId,
 	}
-	count = db.Mgo.Count(this.SaveTable, query)
+	count = qutil.IntAll(db.Base.Count(this.SaveTable, query))
 	if count == 0 {
 		return
 	}
-	if pNum*pSize > count {
-		err = errors.New("非法查询")
-		return
-	}
-	hasNext = (pNum+1)*pSize < count
-	followList, _ := db.Mgo.Find(this.SaveTable, query, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"l_lastpushtime":1,"s_id":1,"i_remind":1,"_id":1,"l_createtime":1,"i_apppushunread":1}`, false, pNum*pSize, pSize)
-	if followList == nil || len(*followList) == 0 {
-		err = errors.New("查询异常")
-		return
-	}
-	sidArr := []string{}
-	followSetting := map[string]map[string]interface{}{}
-	for _, followOne := range *followList {
-		sid := qutil.ObjToString(followOne["s_id"])
-		if followOne["l_lastpushtime"] != nil && followOne["l_lastpushtime"] != "" {
-			followOne["l_createtime"] = followOne["l_lastpushtime"]
-		} else if followOne["l_lastpushtime"] == nil {
-			followOne["l_lastpushtime"] = followOne["l_createtime"]
+	//if pNum*pSize > count {
+	//	err = errors.New("非法查询")
+	//	return
+	//}
+	//if count > this.MaxNum {
+	//	count = this.MaxNum
+	//}
+	////非大会员用户处理
+	//if this.MaxNum < (pNum+1)*pSize {
+	//	pSize = this.MaxNum
+	//} else {
+	//	hasNext = (pNum+1)*pSize < count
+	//}
+	//"l_lastpushtime,s_id,i_remind,id,l_createtime,i_apppushunread"
+	t1 := time.Now()
+	followList := db.Base.Find(this.SaveTable, query, "l_lastpushtime,s_id,i_remind,id,l_createtime,i_apppushunread", "l_createtime desc", 0, pSize)
+	log.Println("查询耗时:", time.Since(t1))
+	if followList != nil && len(*followList) > 0 {
+		sidArr := []string{}
+		sidStr := ""
+		followSetting := map[string]map[string]interface{}{}
+		for _, followOne := range *followList {
+			st := time.Date(2000, 1, 1, 0, 0, 0, 0, time.Local).Unix()
+
+			sid := qutil.ObjToString(followOne["s_id"])
+			if qutil.Int64All(followOne["l_lastpushtime"]) > st {
+				followOne["l_createtime"] = followOne["l_lastpushtime"]
+			} else if followOne["l_lastpushtime"] == nil || followOne["l_lastpushtime"] == 1 {
+				followOne["l_lastpushtime"] = followOne["l_createtime"]
+			}
+			//if followOne["l_lastpushtime"] != nil && followOne["l_lastpushtime"] != "" && qutil.Int64All(followOne["l_lastpushtime"]) > st {
+			//	followOne["l_createtime"] = followOne["l_lastpushtime"]
+			//} else if followOne["l_lastpushtime"] == nil {
+			//	followOne["l_lastpushtime"] = followOne["l_createtime"]
+			//}
+			//if qutil.Int64All(followOne["l_lastpushtime"]) < st {
+			//	delete(followOne, "l_lastpushtime")
+			//}
+			sidArr = append(sidArr, sid)
+			sidStr = sidStr + "," + sid
+
+			followSetting[sid] = followOne
 		}
-		sidArr = append(sidArr, sid)
-		followSetting[sid] = followOne
-	}
-	projectInfos := []map[string]interface{}{}
 
-	pool := make(chan bool, 10)
-	wait := &sync.WaitGroup{}
-	var lock sync.Mutex
-	for _, v := range SplitArray(sidArr, 50) {
-		pool <- true
-		wait.Add(1)
-		go func(arr []string) error {
-			defer func() {
-				wait.Done()
-				<-pool
-			}()
-			//es查询
-			projectInfos_, err := getProjectsBySid(arr)
-			lock.Lock()
-			projectInfos = append(projectInfos, projectInfos_...)
-			lock.Unlock()
-			if err != nil {
-				err = errors.New("项目信息查询异常")
-				return err
+		log.Println("是否认领耗时:", time.Since(t1))
+		projectInfos := []map[string]interface{}{}
+
+		pool := make(chan bool, 10)
+		wait := &sync.WaitGroup{}
+		var lock sync.Mutex
+		for _, v := range SplitArray(sidArr, 50) {
+			pool <- true
+			wait.Add(1)
+			go func(arr []string) error {
+				defer func() {
+					wait.Done()
+					<-pool
+				}()
+				//es查询
+				projectInfos_, err := getProjectsBySid(arr)
+				lock.Lock()
+				projectInfos = append(projectInfos, projectInfos_...)
+				lock.Unlock()
+				if err != nil {
+					err = errors.New("项目信息查询异常")
+					return err
+				}
+				return nil
+			}(v)
+		}
+		wait.Wait()
+		log.Println("es查询耗时:", time.Since(t1))
+		for _, projectinfo := range projectInfos { //补充设置信息
+			for _, k := range qutil.ObjArrToStringArr(projectinfo["ids"].([]interface{})) {
+				if info, ok := followSetting[k]; ok {
+					info["area"] = projectinfo["area"]
+					info["buyerclass"] = projectinfo["buyerclass"]
+					info["budget"] = qutil.Float64All(projectinfo["budget"])
+					info["title"] = projectinfo["projectname"]
+					info["status"] = projectinfo["bidstatus"]
+					info["projectcode"] = projectinfo["projectcode"]
+					info["buyer"] = projectinfo["buyer"]
+					if projectinfo["industry"] == nil && projectinfo["s_subscopeclass"] != nil {
+						ind := strings.Split(qutil.InterfaceToStr(projectinfo["s_subscopeclass"]), ",")[0]
+						info["s_industry"] = strings.Split(ind, "_")[0]
+					} else {
+						info["s_industry"] = projectinfo["industry"]
+					}
+					break
+				}
 			}
-			return nil
-		}(v)
-	}
-	wait.Wait()
-	// projectInfos, err := getProjectsBySid(sidArr)
-	// if err != nil {
-	// 	err = errors.New("项目信息查询异常")
-	// 	return nil, false, 0, err
-	// }
-	for _, projectinfo := range projectInfos { //补充设置信息
-		for _, k := range qutil.ObjArrToStringArr(projectinfo["ids"].([]interface{})) {
-			if info, ok := followSetting[k]; ok {
-				info["area"] = projectinfo["area"]
-				info["buyerclass"] = projectinfo["buyerclass"]
-				info["budget"] = qutil.Float64All(projectinfo["budget"])
-				info["title"] = projectinfo["projectname"]
-				info["status"] = projectinfo["bidstatus"]
-				info["projectcode"] = projectinfo["projectcode"]
-				break
+		}
+		log.Println("----查询耗时:", time.Since(t1))
+		for _, sid := range sidArr {
+			thisRow := followSetting[sid]
+			fid := qutil.InterfaceToStr(thisRow["id"])
+			thisRow["fid"] = util.EncodeId(fid)
+			thisRow["sid"] = util.EncodeId(sid)
+			if thisRow["title"] == nil {
+				log.Println("异常数据:", sid, fid)
+				//大会员有项目进度监控权限删除异常项目(包括:非会员时 手动添加的没有招标信息的项目) 否则不显示不处理
+				if this.Buy {
+					//删除异常数据
+					go this.CancelFollow(sid, fid)
+				}
+				continue
+			}
+			delete(thisRow, "id")
+			delete(thisRow, "s_id")
+			if entUserId != 0 {
+				bdinfos := db.Mysql.SelectBySql(fmt.Sprintf("SELECT  ecn.id  FROM %s ecn,%s  euu WHERE  ecn.state=1 and  ecn.id = euu.customer_id AND euu.user_id =? AND ecn.`name` = ? AND (euu.source_type =1 or  euu.source_type =4)", Entniche_customer, Entniche_user_customer), entUserId, thisRow["buyer"])
+				if bdinfos != nil && len(*bdinfos) > 0 {
+					thisRow["isClaim"] = 1
+				} else {
+					thisRow["isClaim"] = 2
+				}
 			}
+			followData = append(followData, thisRow)
 		}
+		log.Println("++++查询耗时:", time.Since(t1))
 	}
-	for _, sid := range sidArr {
-		thisRow := followSetting[sid]
-		fid := BsonIdToSId(thisRow["_id"])
-		thisRow["fid"] = util.EncodeId(fid)
-		thisRow["sid"] = util.EncodeId(sid)
-		if thisRow["title"] == nil {
-			log.Println("异常数据:", sid, fid)
-			//大会员有项目进度监控权限删除异常项目(包括:非会员时 手动添加的没有招标信息的项目) 否则不显示不处理
-			if this.Buy {
-				//删除异常数据
-				go this.CancelFollow(sid, fid)
-			}
+	return
+}
+
+// 获取sql语句的in操作相关参数
+func GetInForComma(ids string) ([]interface{}, string) {
+	args := []interface{}{}
+	ws := []string{}
+	for _, v := range strings.Split(ids, ",") {
+		if v == "" {
 			continue
 		}
-		delete(thisRow, "_id")
-		delete(thisRow, "s_id")
-		followData = append(followData, thisRow)
+		args = append(args, v)
+		ws = append(ws, "?")
 	}
-	return
+	return args, strings.Join(ws, ",")
 }
 
-//根据多个信息id查询对应的项目信息
+// 根据多个信息id查询对应的项目信息
 func getProjectsBySid(sids []string) ([]map[string]interface{}, error) {
 	sidStr := strings.Join(sids, `","`)
-	list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"terms": {"list.infoid": ["`+sidStr+`"]}}]}},"_source":["projectname","_id","area","buyerclass","budget","ids","bidstatus","projectcode"],"from": 0,"size": `+fmt.Sprint(len(sids))+`}`)
-	if len(*list) == 0 {
+	list := elastic.Get("projectset", "projectset", `{"query": {"bool": {"must": [{"terms": {"list.infoid": ["`+sidStr+`"]}}]}},"_source":["projectname","_id","area","buyerclass","budget","ids","bidstatus","projectcode","buyer","s_subscopeclass"],"from": 0,"size": `+fmt.Sprint(len(sids))+`}`)
+	if list == nil || len(*list) == 0 {
 		return nil, errors.New("获取项目信息查询出错")
 	}
 	return *list, nil
@@ -386,18 +478,18 @@ func (this *ProjectFollow) CancelFollow(sid, fid string) error {
 		query["s_id"] = sid
 	}
 	if fid != "" {
-		query["_id"] = StringTOBsonId(fid)
+		query["id"] = fid
 	}
 	// log.Println(query)
-	data, _ := db.Mgo.FindOne(this.SaveTable, query)
+	data := db.Base.FindOne(this.SaveTable, query, "", "")
 	if data == nil || len(*data) == 0 {
 		return errors.New("未找到相应数据")
 	}
-	(*data)["s_followid"] = BsonIdToSId((*data)["_id"])
+	(*data)["s_followid"] = qutil.InterfaceToStr((*data)["id"])
 	(*data)["i_status"] = 1
-	delete(*data, "_id")
+	delete(*data, "id")
 	db.Mgo.Save(this.SaveTable+"_back", data)
-	if !db.Mgo.Del(this.SaveTable, query) {
+	if !db.Base.Delete(this.SaveTable, query) {
 		return errors.New("取消关注失败")
 	}
 	//删除项目推送
@@ -407,26 +499,21 @@ func (this *ProjectFollow) CancelFollow(sid, fid string) error {
 
 // Remove30DayNoUpdate 批量删除30天未更新
 func (this *ProjectFollow) Remove30DayNoUpdate() (int, error) {
-	query := map[string]interface{}{
-		"s_userid": this.UserId,
-		"l_lastpushtime": map[string]interface{}{
-			"$lt": time.Now().AddDate(0, 0, -30).Unix(),
-		},
-	}
-	fData, _ := db.Mgo.Find(this.SaveTable, query, nil, nil, false, -1, -1)
+	lt := time.Now().AddDate(0, 0, -30).Unix()
+
+	fData := db.Base.SelectBySql(`SELECT * FROM follow_project_monitor WHERE s_userid=? AND l_lastpushtime < ?`, this.UserId, lt)
+	//fData := db.Mysql.Find(this.SaveTable, query, "", "", -1, -1)
 	if fData == nil || len(*fData) == 0 {
 		return 0, nil
 	}
 	for _, data := range *fData {
-		data["s_followid"] = BsonIdToSId(data["_id"])
-		delete(data, "_id")
+		data["s_followid"] = qutil.InterfaceToStr(data["id"])
+		delete(data, "id")
 	}
-	if !db.Mgo.SaveBulk(this.SaveTable+"_back", (*fData)...) {
+	if !db.Mgo.SaveBulk(this.SaveTable+"_back", *fData...) {
 		log.Println("批量删除备份出错")
 	}
-	if !db.Mgo.Del(this.SaveTable, query) {
-		return -1, errors.New("批量取关未更新项目失败")
-	}
+	db.Base.SelectBySql(`delete from follow_project_monitor WHERE s_userid=? AND l_lastpushtime < ?`, this.UserId, lt)
 	return len(*fData), nil
 }
 
@@ -441,11 +528,9 @@ func (this *ProjectFollow) AddTime(fid string, bidopentime, remindtime int64) bo
 	if remindtime != 0 {
 		update["l_remindtime"] = remindtime
 	}
-	return db.Mgo.Update(this.SaveTable, map[string]interface{}{
-		"_id": StringTOBsonId(fid),
-	}, map[string]interface{}{
-		"$set": update,
-	}, false, false)
+	return db.Base.Update(this.SaveTable, map[string]interface{}{
+		"id": fid,
+	}, update)
 }
 
 // RemindSwitch 项目提醒开关
@@ -458,12 +543,10 @@ func (this *ProjectFollow) RemindSwitch(fid string, open bool) bool {
 	} else {
 		update["i_remind"] = 0
 	}
-	return db.Mgo.UpdateById(this.SaveTable, fid, map[string]interface{}{
-		"$set": update,
-	})
+	return db.Base.Update(this.SaveTable, map[string]interface{}{"id": fid}, update)
 }
 
-//删除redis相关数据
+// 删除redis相关数据
 func delRelRedis(userid interface{}, relationinfo interface{}) {
 	defer qutil.Catch()
 	uid, _ := userid.(string)
@@ -478,7 +561,7 @@ func delRelRedis(userid interface{}, relationinfo interface{}) {
 }
 
 // Area 获取已关注项目的地区
-//项目提醒开关
+// 项目提醒开关
 func (this *ProjectFollow) Area(list []map[string]interface{}) []string {
 	areaM := map[string]int{}
 	area := []string{}

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

@@ -90,6 +90,9 @@ func (this *FollowEnt) List() {
 		if err != nil {
 			return nil, err
 		}
+		if entList == nil {
+			entList = []map[string]interface{}{}
+		}
 		return map[string]interface{}{
 			"count":     count,                   //已关注数量
 			"total":     total,                   //筛选总数
@@ -199,7 +202,7 @@ func (this *FollowEnt) EntChangeList() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
-//ChangeGroup 更换关注企业分组
+// ChangeGroup 更换关注企业分组
 func (this *FollowEnt) ChangeGroup() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {

+ 44 - 9
src/jfw/modules/bigmember/src/service/follow/project.go

@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"log"
 	qutil "qfw/util"
+	"strings"
 	"util"
 
 	"github.com/go-xweb/xweb"
@@ -107,6 +108,11 @@ func (this *FollowProject) FollowCheck() {
 // FollowList 项目关注列表
 func (this *FollowProject) FollowList() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
+	entUserId := qutil.IntAll(this.GetSession("entUserId"))
+	isClaim := qutil.IntAll(this.GetString("isClaim"))
+	name := this.GetString("name")
+	area := this.GetString("area")
+	areaAll := strings.Split(area, ",")
 	rData, errMsg := func() (interface{}, error) {
 		projectManager, err := entity.CreateProjectFollowManager(userId)
 		if err != nil {
@@ -114,18 +120,37 @@ func (this *FollowProject) FollowList() {
 		}
 		pNum, _ := this.GetInteger("pageNum")   //当前页码
 		pSize, _ := this.GetInteger("pageSize") //每页数据量
-		if pSize == 0 || pSize > 100 {          //默认一页50条数据
-			pSize = 50
-		}
-		pList, hasNext, count, err := projectManager.GetFollowList(pNum, pSize)
+		pList, _, count, err := projectManager.GetFollowList(pNum, projectManager.MaxNum, entUserId)
 		//是否有下一页??
 		if err != nil {
 			return nil, err
 		}
+		log.Println("----:", len(pList))
+		var list []map[string]interface{}
+		for _, v := range pList {
+			if isClaim != 0 && qutil.IntAll(v["isClaim"]) != isClaim {
+				continue
+			}
+			if name != "" && !strings.Contains(qutil.InterfaceToStr(v["title"]), name) {
+				continue
+			}
+			if area != "" && !IsArea(areaAll, qutil.InterfaceToStr(v["area"])) {
+				continue
+			}
+			list = append(list, v)
+		}
+
+		var sList []map[string]interface{}
+		if (pNum+1)*pSize >= len(list) {
+			sList = list[pNum*pSize:]
+		} else {
+			sList = list[pNum*pSize : (pNum+1)*pSize]
+		}
+
 		return map[string]interface{}{
 			"total":     count,
-			"hasNext":   hasNext,
-			"List":      pList,
+			"hasNext":   qutil.If((pNum+1)*pSize >= len(list), false, true),
+			"List":      sList,
 			"followMax": projectManager.MaxNum,
 		}, nil
 	}()
@@ -135,6 +160,15 @@ func (this *FollowProject) FollowList() {
 	this.ServeJson(NewResult(rData, errMsg))
 }
 
+func IsArea(areaAll []string, area string) bool {
+	for _, v := range areaAll {
+		if v == area {
+			return true
+		}
+	}
+	return false
+}
+
 // FollowDetail 关注项目详情页&设置
 func (this *FollowProject) FollowDetail() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
@@ -192,8 +226,8 @@ func mergeFollowDetail(followInfo, projectInfo map[string]interface{}, sid strin
 			followInfo["bidopentime"] = projectInfo["bidopentime"]
 		}
 		//设置已读未读
-		if finfo, ok := followInfo["visit"].([]interface{}); ok {
-			visitArr = qutil.ObjArrToStringArr(finfo)
+		if finfo, ok := followInfo["visit"].(string); ok {
+			visitArr = strings.Split(finfo, ",")
 		}
 		delete(followInfo, "visit")
 	}
@@ -328,12 +362,13 @@ func (this *FollowProject) RemindSwitch() {
 // ScreenArea 获取已关注的项目地区
 func (this *FollowProject) ScreenArea() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
+	entUserId := qutil.IntAll(this.GetSession("entUserId"))
 	rData, errMsg := func() (interface{}, error) {
 		projectManager, err := entity.CreateProjectFollowManager(userId)
 		if err != nil {
 			return nil, err
 		}
-		pList, _, _, err := projectManager.GetFollowList(0, 500)
+		pList, _, _, err := projectManager.GetFollowList(0, projectManager.MaxNum, entUserId)
 		return projectManager.Area(pList), nil
 	}()
 	if errMsg != nil {

+ 19 - 17
src/jfw/modules/bigmember/src/service/use/use.go

@@ -598,23 +598,24 @@ var level_map = map[int]string{
 }
 
 type UserInfo struct {
-	Combo           string `json:"combo"`           //大会员购买版本名称
-	BigMemberStatus int    `json:"memberStatus"`    //大会员状态
-	IsSubCount      bool   `json:"isSubCount"`      //是否是子账号
-	IsMemberTrial   bool   `json:"is_member_trial"` //是否是大会员试用用户
-	IsUsed          bool   `json:"isUsed"`          //是否首次使用大会员
-	Powers          []int  `json:"power"`           //大会员用户权限集合
-	EntName         string `json:"entname"`         //用户相关企业信息
-	EntNiche        bool   `json:"entniche"`        //是否是商机管理用户
-	VipStatus       int    `json:"vipStatus"`       //超级订阅用户状态
-	Viper           bool   `json:"viper"`           //超级订阅升级用户
-	FileNum         int    `json:"fileNum"`         //超级订阅用户附件下载包的剩余次数
-	IsFree          bool   `json:"isFree"`          //是否是免费用户
-	FreeHasKey      bool   `json:"freeHasKey"`      //免费用户是否有关键词
-	FreeEntPort     int    `json:"freeEntPort"`     //免费用户可查看企业画像次数
-	FreeBuyerPort   int    `json:"freeBuyerPort"`   //免费用户可查看采购单位画像次数
-	FreeFile        int    `json:"freeFile"`        //免费用户可以进行附件下载次数
-	IsFreeUpgrade   bool   `json:"isUpgrade"`       //新免费用户
+	Combo           string                `json:"combo"`           //大会员购买版本名称
+	BigMemberStatus int                   `json:"memberStatus"`    //大会员状态
+	IsSubCount      bool                  `json:"isSubCount"`      //是否是子账号
+	IsMemberTrial   bool                  `json:"is_member_trial"` //是否是大会员试用用户
+	IsUsed          bool                  `json:"isUsed"`          //是否首次使用大会员
+	Powers          []int                 `json:"power"`           //大会员用户权限集合
+	EntName         string                `json:"entname"`         //用户相关企业信息
+	EntNiche        bool                  `json:"entniche"`        //是否是商机管理用户
+	VipStatus       int                   `json:"vipStatus"`       //超级订阅用户状态
+	Viper           bool                  `json:"viper"`           //超级订阅升级用户
+	FileNum         int                   `json:"fileNum"`         //超级订阅用户附件下载包的剩余次数
+	IsFree          bool                  `json:"isFree"`          //是否是免费用户
+	FreeHasKey      bool                  `json:"freeHasKey"`      //免费用户是否有关键词
+	FreeEntPort     int                   `json:"freeEntPort"`     //免费用户可查看企业画像次数
+	FreeBuyerPort   int                   `json:"freeBuyerPort"`   //免费用户可查看采购单位画像次数
+	FreeFile        int                   `json:"freeFile"`        //免费用户可以进行附件下载次数
+	IsFreeUpgrade   bool                  `json:"isUpgrade"`       //新免费用户
+	CustomerService []config.CustomerInfo `json:"customers"`
 }
 
 //是否使用过首次使用
@@ -718,6 +719,7 @@ func (u *Use) IsAdd() {
 				userInfo.FreeEntPort, userInfo.FreeBuyerPort, userInfo.FreeFile = jy.FreeExperience(userid)
 			}
 		}
+		userInfo.CustomerService = config.Config.Customers
 		return Result{Data: userInfo}
 	}()
 	u.ServeJson(r)

+ 11 - 1
src/jfw/modules/common/src/qfw/util/jy/bigVipPower.go

@@ -10,6 +10,7 @@ import (
 	"qfw/util/mysql"
 	"qfw/util/redis"
 	"strings"
+	"time"
 )
 
 //大会员状态redis缓存
@@ -58,6 +59,10 @@ const (
 	FilePackNumKey            = "file_pack_num_%s_%s" //附件下载包本月  剩余次数  %s:userid   %s 当前月份-fmt.Sprint(time.Now().Month())
 	BaseInfoCacheDb           = "newother"
 	IsGetUserBaseInfoRedisKey = "baseinfo_%s"
+	RedisMenuKeyPC            = "jy_workdesktopmenu_10000_PC_%s"  //剑鱼appid:10000
+	RedisMenuKeyWX            = "jy_workdesktopmenu_10000_WX_%s"  //剑鱼appid:10000
+	RedisMenuKeyAPP           = "jy_workdesktopmenu_10000_APP_%s" //剑鱼appid:10000
+	UserPowerRedisKey         = "jy_userpowerredis_10000_%d_%s"   //工作桌面 用户功能缓存(类似bigmember_power_3_%s)
 )
 
 //初始化大会员权益
@@ -92,7 +97,11 @@ func InitBigVipService(mysql *mysql.Mysql) {
 func ClearBigVipUserPower(userId string) bool {
 	cacheKey := fmt.Sprintf(PowerCacheKey, userId)
 	baseInfoCacheKey := fmt.Sprintf(IsGetUserBaseInfoRedisKey, userId)
-	return redis.Del(BaseInfoCacheDb, cacheKey) && redis.Del(BaseInfoCacheDb, baseInfoCacheKey)
+	redisMenuKeyPC := fmt.Sprintf(RedisMenuKeyPC, userId)
+	redisMenuKeyWX := fmt.Sprintf(RedisMenuKeyWX, userId)
+	redisMenuKeyAPP := fmt.Sprintf(RedisMenuKeyAPP, userId)
+	userPowerRedisKey := fmt.Sprintf(UserPowerRedisKey, time.Now().Day(), userId)
+	return redis.Del(BaseInfoCacheDb, cacheKey) && redis.Del(BaseInfoCacheDb, baseInfoCacheKey) && redis.Del(BaseInfoCacheDb, redisMenuKeyPC) && redis.Del(BaseInfoCacheDb, redisMenuKeyWX) && redis.Del(BaseInfoCacheDb, redisMenuKeyAPP) && redis.Del(BaseInfoCacheDb, userPowerRedisKey)
 }
 
 //获取商机管理个人基本信息
@@ -256,6 +265,7 @@ func (this *BigVipBaseMsg) checkPower(reqFlag string, servicesPower map[string][
 			return true
 		}
 	}
+
 	return false
 }
 

+ 16 - 13
src/jfw/modules/common/src/qfw/util/jy/subscribepush.go

@@ -57,17 +57,19 @@ const (
 	mongodb_fields      = `{"_id":1,"area":1,"publishtime":1,"s_subscopeclass":1,"subtype":1,"title":1,"toptype":1,"type":1, "buyerclass":1,"budget":1,"bidamount":1,"s_winner":1,"bidopentime":1,"buyer":1,"projectname":1,"spidercode":1,"site":1}`
 	querys              = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","title","detail","area","city","publishtime","projectname","buyer","buyerclass","s_winner","bidamount","subtype","toptype","href","projectcode","buyerperson","buyertel","budget","bidopentime","agency","projectscope","winnerperson","winnertel","spidercode","site"]}`
 
-	MemberFlag   = "m"
-	SubVipFlag   = "v"
-	EntnicheFlag = "s"
-	SubFreeFlag  = ""
+	MemberFlag     = "m"
+	SubVipFlag     = "v"
+	EntnicheFlag   = "s"
+	SubFreeFlag    = ""
+	SubNewFreeFlag = "f"
 )
 
 var aboutDbMsg map[string]*AboutDbMsg = map[string]*AboutDbMsg{
-	SubFreeFlag:  &AboutDbMsg{"pushsubscribe", "subpush"},
-	SubVipFlag:   &AboutDbMsg{"pushsubscribe", "subpush"},
-	MemberFlag:   &AboutDbMsg{"pushmember", "memberpush"},
-	EntnicheFlag: &AboutDbMsg{"pushentniche", "entnichepush"},
+	SubNewFreeFlag: &AboutDbMsg{"pushsubscribe", "subpush"},
+	SubFreeFlag:    &AboutDbMsg{"pushsubscribe", "subpush"},
+	SubVipFlag:     &AboutDbMsg{"pushsubscribe", "subpush"},
+	MemberFlag:     &AboutDbMsg{"pushmember", "memberpush"},
+	EntnicheFlag:   &AboutDbMsg{"pushentniche", "entnichepush"},
 }
 
 type AboutDbMsg struct {
@@ -114,8 +116,9 @@ type SubPushQueryParam struct {
 	FileExists    string        //是否有附件;默认全部;1:有附件;-1:无附件
 }
 
+//spqp.SelectTime == "all"  满足PC端超级订阅和免费用户 第一次进入订阅列表无数据 默认匹配部分数据的问题
 func (spqp *SubPushQueryParam) IsEmpty() bool {
-	return spqp.SelectTime == "" && spqp.Area == "" && spqp.City == "" && spqp.Buyerclass == "" && spqp.Subscopeclass == "" && spqp.Subtype == "" && spqp.Key == "" && spqp.Price == "" && spqp.FileExists == ""
+	return (spqp.SelectTime == "" || spqp.SelectTime == "all") && spqp.Area == "" && spqp.City == "" && spqp.Buyerclass == "" && spqp.Subscopeclass == "" && spqp.Subtype == "" && spqp.Key == "" && spqp.Price == "" && spqp.FileExists == ""
 }
 
 type subscribePush struct {
@@ -852,13 +855,13 @@ type ViewKeyWord struct {
 	MatchWay int      `json:"matchway"`  //匹配模式
 }
 
-func (s *subscribePush) MakeHistoryDatasNew(PushMysql *mysql.Mysql, userId string, entId int, DefaultPushList func(userId, moduleFlag string, entId int) (keyword []byte, list *[]map[string]interface{}, deptId int)) (bool, []*SubPushList) {
+func (s *subscribePush) MakeHistoryDatasNew(PushMysql *mysql.Mysql, userId string, entId int, DefaultPushList func(userId, moduleFlag string, entId int) (keyword []byte, list *[]map[string]interface{}, deptId int)) (bool, []*SubPushList, int) {
 	log.Println(s.ModuleFlag, "匹配最近7天数据", userId, entId)
 	//
 	t1 := time.Now()
 	kw, list, deptId := DefaultPushList(userId, s.ModuleFlag, entId)
 	if list == nil || len(*list) == 0 {
-		return false, nil
+		return false, nil, 0
 	}
 	var isNext = false
 	log.Println("es查询耗时:", time.Since(t1))
@@ -866,7 +869,7 @@ func (s *subscribePush) MakeHistoryDatasNew(PushMysql *mysql.Mysql, userId strin
 	if list != nil && len(*list) > 0 {
 		keyword := []ViewKeyWord{}
 		if err := json.Unmarshal(kw, &keyword); err != nil {
-			return false, nil
+			return false, nil, 0
 		}
 		//超过50条先处理50条 返回前50条
 		listOne := *list
@@ -881,7 +884,7 @@ func (s *subscribePush) MakeHistoryDatasNew(PushMysql *mysql.Mysql, userId strin
 		}
 	}
 	log.Println("第一批推送信息处理耗时:", time.Since(t1).Seconds(), len(resultList))
-	return isNext, resultList
+	return isNext, resultList, len(*list)
 }
 
 //

+ 30 - 4
src/jfw/modules/followent/src/db.json

@@ -1,20 +1,46 @@
 {
 	"mongodb": {
 		"main": {
-			"address": "192.168.3.128:27080",
+			"address": "192.168.3.206:27080",
 	 		"size": 5,
 	 		"dbName": "qfw"
 		}
 	},
 	"elasticsearch": {
 		"main":{
-			"address": "http://192.168.3.128:9800",
+			"address": "http://192.168.3.206:9800",
 	    	"size": 30
 		}
     },
     "redis": {
     	"main": {
-			"address": "other=192.168.3.128:1712,push=192.168.3.128:1712,sso=192.168.3.128:1712,session=192.168.3.128:1712,recovery=192.168.3.128:1712"
+			"address": "other=192.168.3.206:1712,push=192.168.3.206:1712,sso=192.168.3.206:1712,session=192.168.3.206:1712,recovery=192.168.3.206:1712"
 		}
+    },
+  "mysql": {
+    "main": {
+      "dbName": "jianyu",
+      "address": "192.168.3.11:3366",
+      "userName": "root",
+      "passWord": "Topnet123",
+      "maxOpenConns": 5,
+      "maxIdleConns": 5
+    },
+    "base": {
+      "dBName": "base_service",
+      "address": "192.168.3.217:4000",
+      "userName": "root",
+      "passWord": "=PDT49#80Z!RVv52_z",
+      "maxOpenConns": 5,
+      "maxIdleConns": 5
+    },
+    "push": {
+      "dbName": "jianyu",
+      "address": "192.168.3.11:3366",
+      "userName": "root",
+      "passWord": "Topnet123",
+      "maxOpenConns": 5,
+      "maxIdleConns": 5
     }
-}
+  }
+}

+ 39 - 25
src/jfw/modules/followent/src/followent/followent.go

@@ -8,6 +8,7 @@ import (
 	"jfw/wx"
 	. "mongodb"
 	"qfw/util"
+	"qfw/util/jy"
 	"qfw/util/redis"
 	"strconv"
 	"strings"
@@ -16,6 +17,7 @@ import (
 )
 
 var mongodb = public.MQFW
+var base = public.BaseMysql
 var se = util.SE
 
 type FollowEnt struct {
@@ -57,22 +59,22 @@ func (f *FollowEnt) EntList() error {
 		return f.Redirect("/swordfish/about")
 	}
 
-	followEntLimit, _ := strconv.Atoi(config.Sysconfig["followentlimit"].(string))
-	datas, ok := mongodb.Find("jylab_followent", `{"s_userid":"`+userid+`","s_entname":{"$ne":""}}`, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"_id":1,"s_entname":1,"s_userid":1,"s_openid":1,"l_createtime":1,"l_lastpushtime":1,"s_id":1,"i_ispush":1}`, false, 0, 10)
-	f.T["flag"] = false
-	if ok && datas != nil && len(*datas) > 0 {
-		for _, v := range *datas {
-			v["_id"] = util.EncodeArticleId2ByCheck(BsonIdToSId(v["_id"]))
-			v["s_id"] = util.EncodeArticleId2ByCheck(BsonIdToSId(v["s_id"]))
-			if v["l_lastpushtime"] == "" || v["l_lastpushtime"] == nil {
-				v["l_lastpushtime"] = v["l_createtime"]
-			}
-		}
-		f.T["datas"] = datas
-		if len(*datas) >= followEntLimit {
-			f.T["flag"] = true
-		}
-	}
+	followEntLimit := CreateEntFollowManager(userid)
+	//datas, ok := mongodb.Find("jylab_followent", `{"s_userid":"`+userid+`","s_entname":{"$ne":""}}`, `{"l_lastpushtime":-1,"l_createtime":-1}`, `{"_id":1,"s_entname":1,"s_userid":1,"s_openid":1,"l_createtime":1,"l_lastpushtime":1,"s_id":1,"i_ispush":1}`, false, 0, 10)
+	//f.T["flag"] = false
+	//if ok && datas != nil && len(*datas) > 0 {
+	//	for _, v := range *datas {
+	//		v["_id"] = util.EncodeArticleId2ByCheck(BsonIdToSId(v["_id"]))
+	//		v["s_id"] = util.EncodeArticleId2ByCheck(BsonIdToSId(v["s_id"]))
+	//		if v["l_lastpushtime"] == "" || v["l_lastpushtime"] == nil {
+	//			v["l_lastpushtime"] = v["l_createtime"]
+	//		}
+	//	}
+	//	f.T["datas"] = datas
+	//	if len(*datas) >= followEntLimit {
+	//		f.T["flag"] = true
+	//	}
+	//}
 	f.T["followEntLimit"] = followEntLimit
 	f.T["signature"] = wx.SignJSSDK(f.Site() + f.Url())
 	f.T["openid"] = se.EncodeString(util.ObjToString(f.GetSession("s_m_openid")))
@@ -83,6 +85,18 @@ func (f *FollowEnt) EntList() error {
 	return f.Render("/weixin/list.html", &f.T)
 }
 
+type EntFollow struct {
+	HasPower  bool
+	UserId    string //用户id
+	MaxNum    int    //最大关注数量
+	SaveTable string //关注企业数量
+}
+
+func CreateEntFollowManager(userid string) int {
+	bigMsg := jy.GetBigVipUserBaseMsg(userid, public.Mysql, public.MQFW)
+	return util.IntAll(util.If(bigMsg.Customers > util.IntAll(config.Sysconfig["followentlimit"]), bigMsg.ProNum, util.IntAll(config.Sysconfig["followentlimit"])))
+}
+
 func (f *FollowEnt) AddEnt() error {
 	f.T["signature"] = wx.SignJSSDK(f.Site() + f.Url())
 	f.T["openid"] = se.EncodeString(util.ObjToString(f.GetSession("s_m_openid")))
@@ -119,16 +133,17 @@ func (f *FollowEnt) Detail(followId string) error {
 	followId = util.DecodeArticleId2ByCheck(followId)[0]
 	winner := ""
 	var a_visited interface{}
-	oneQy, ok := mongodb.FindOneByField("jylab_followent", map[string]interface{}{
-		"_id": StringTOBsonId(followId),
-	}, `{"s_entname":1,"s_id":1,"a_visited":1,"s_userid":1}`)
+	oneQy := base.FindOne("follow_ent_monitor", map[string]interface{}{
+		"id": followId,
+	}, `s_entname,s_id,s_userid`, "")
+	fmt.Println(oneQy)
 	follow := "n"
-	if !ok || oneQy == nil || len(*oneQy) == 0 {
-		oneQy, ok = mongodb.FindOneByField("jylab_followent_back", map[string]interface{}{
+	if oneQy == nil || len(*oneQy) == 0 {
+		oneQy, _ = mongodb.FindOneByField("jylab_followent_back", map[string]interface{}{
 			"s_followid": followId,
 		}, `{"s_entname":1,"s_id":1,"a_visited":1,"s_userid":1}`)
 	}
-	if !ok || oneQy == nil || len(*oneQy) == 0 {
+	if oneQy == nil || len(*oneQy) == 0 {
 		return f.Render("_error.html")
 	} else if util.ObjToString((*oneQy)["s_userid"]) != userId {
 		return f.Redirect(fmt.Sprintf("/jylab/followent/newInfo/%s", util.ObjToString((*oneQy)["s_entname"])))
@@ -150,7 +165,7 @@ func (f *FollowEnt) Detail(followId string) error {
 	return f.Render("/weixin/set.html", &f.T)
 }
 
-//企业最新信息
+// 企业最新信息
 func (f *FollowEnt) NewInfo(param string) error {
 	defer util.Catch()
 	userId := util.ObjToString(f.GetSession("userId"))
@@ -179,7 +194,7 @@ func (f *FollowEnt) NewInfo(param string) error {
 	return f.Render("/weixin/set.html", &f.T)
 }
 
-//取消企业关注
+// 取消企业关注
 func (f *FollowEnt) QgFollow() error {
 	defer util.Catch()
 	userid := util.ObjToString(f.GetSession("userId"))
@@ -200,7 +215,6 @@ func (f *FollowEnt) QgFollow() error {
 	return nil
 }
 
-//
 func (f *FollowEnt) Followent() error {
 	//data := mongodb.FindById("user", "597ec30861fd00271cff7154", nil)
 	//data := elastic.GetPage("bidding", "bidding", "{}", `{"publishtime":-1}`, `"_id","title","publishtime","toptype","subtype","type","area","href"`, 0, 2)

+ 15 - 20
src/jfw/modules/followent/src/web/templates/weixin/add.html

@@ -70,7 +70,7 @@
                 $(".opation").addClass("disabled");
                 $("#recList").hide();
             }else{
-                $(".opation").removeClass("disabled");
+                // $(".opation").removeClass("disabled");
                 getRecList(this.value);
             }
         });
@@ -85,20 +85,15 @@
                 return;
             }
             $(this).addClass("disabled");
-            $.post("/jylab/followent/addfwent",{winner:entName,id:winner_id},function(r){
-                if(r.status == "y" || r.status == "e"){
-                    if(sessionStorage){
-                        sessionStorage.version="1";
-                    }
-                    //window.location.href = "/followeEnt/set/add/"+r.id;
-                    //window.location.href = "/jylab/followent/entList";
-					window.history.back();
-                }else if(r.status == "m"){
-                    EasyAlert.show("最多可关注<br>10个企业!");
-                }else{
-                    EasyAlert.show("数据提交失败!");
-                    $(".opation").removeClass("disabled");
+            $.post("/bigmember/follow/ent/addFollow",{group:"A",entId:winner_id},function(r){
+              if(r.data == "success" && r.error_code == 0){
+                if(sessionStorage){
+                  sessionStorage.version="1";
                 }
+                window.history.back();
+              }else{
+                EasyAlert.show(r.error_msg);
+              }
             });
         });
     });
@@ -106,13 +101,13 @@
 	function getRecList(entName_key) {
 		$("#recList").html("");
     if(getRecListXHR) getRecListXHR.abort();//取消请求响应
-		getRecListXHR=$.post("/jylab/followent/recList",{entName:entName_key},function(r){
+		getRecListXHR=$.post("/bigmember/follow/ent/association",{entName:entName_key},function(r){
 			if(r){
-				if(typeof(r.recList)!="undefined" && r.recList != null && r.recList.length > 0){
-					var recList = r.recList;
+				if(typeof(r.data)!="undefined" && r.data != null && r.data.length > 0){
+					var recList = r.data;
 					for(var i=0;i<recList.length;i++){
-					    var entName = recList[i].name;
-					    var id = recList[i]._id;
+					    var entName = recList[i].entName;
+					    var id = recList[i].entId;
 						if(entName!="" && entName.length>20){
 							entName = entName.substr(0,20)+"...";
 						}
@@ -150,4 +145,4 @@
 	</from>
 	{{include "/common/baiducc.html"}}
 </body>
-</html>
+</html>

+ 44 - 33
src/jfw/modules/followent/src/web/templates/weixin/list.html

@@ -85,26 +85,26 @@ if(sessionStorage){
             })
         }
         var IframeOnClick = {
-            resolution: 200,  
-            iframes: [],  
-            interval: null,  
-            Iframe: function() {  
-                    this.element = arguments[0];  
-                    this.cb = arguments[1];   
-                    this.hasTracked = false;  
-            },  
-            track: function(element, cb) {  
-                    this.iframes.push(new this.Iframe(element, cb));  
-                    var _this = this;  
-                            this.interval = setInterval(function() { _this.checkClick(); }, this.resolution);  
-            },  
-            checkClick: function() {  
-                if (document.activeElement) {  
-                    var activeElement = document.activeElement;  
-                    for (var i in this.iframes) {  
-                        if (activeElement === this.iframes[i].element) { // user is in this Iframe  
-                                if (this.iframes[i].hasTracked == false) {   
-                                        this.iframes[i].cb.apply(window, []);   
+            resolution: 200,
+            iframes: [],
+            interval: null,
+            Iframe: function() {
+                    this.element = arguments[0];
+                    this.cb = arguments[1];
+                    this.hasTracked = false;
+            },
+            track: function(element, cb) {
+                    this.iframes.push(new this.Iframe(element, cb));
+                    var _this = this;
+                            this.interval = setInterval(function() { _this.checkClick(); }, this.resolution);
+            },
+            checkClick: function() {
+                if (document.activeElement) {
+                    var activeElement = document.activeElement;
+                    for (var i in this.iframes) {
+                        if (activeElement === this.iframes[i].element) { // user is in this Iframe
+                                if (this.iframes[i].hasTracked == false) {
+                                        this.iframes[i].cb.apply(window, []);
                                         this.iframes[i].hasTracked = true;
                                         $.ajax({
                                                 type: 'POST',
@@ -118,13 +118,13 @@ if(sessionStorage){
                                                         console.log(res)
                                                 }
                                         })
-                                }  
-                        } else {  
-                                this.iframes[i].hasTracked = false;  
-                        }  
-                    }  
-                }  
-            }  
+                                }
+                        } else {
+                                this.iframes[i].hasTracked = false;
+                        }
+                    }
+                }
+            }
 			};
     </script>
     <!-- 多条广告如下脚本只需引入一次 -->
@@ -159,9 +159,21 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
             }
         });
         //
-        {{if .T.datas}}
+      var followEntLimit = {{.T.followEntLimit}};
+      $.post("/bigmember/follow/ent/list?t="+new Date().getTime(),null,function(r) {
+        const res = r.data
+        $("#addDiv").click(function(){
+          if(res.list.length >=followEntLimit){
+            EasyAlert.show("最多可关注<br>"+followEntLimit+"个企业!");
+            return;
+          }
+          window.location.href = "/jyapp/followent/addEnt";
+        });
+        if (res.list.length == 0) {
+          return;
+        }
         var allHtml = "";
-        var data = {{.T.datas}};
+        var data = res.list
         var jyno = 0;
         var fronthtml = "";
         var lasthtml = "";
@@ -205,7 +217,7 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
             if(typeof (entname)=="undefined"){
                 entname = "";
             }
-            fronthtml +="<li data-id='"+frontarr[f]["_id"]+"' Sort='"+lastpushtime+"'>"
+            fronthtml +="<li data-id='"+frontarr[f]["fid"]+"' Sort='"+lastpushtime+"'>"
                 +"<div class='jyfwlistno'>"+listno+".</div>"
                 +"<div class='jyfwlisttitle'>"+entname+"</div>"
                 +"<div style='clear:both;'></div>"+rem
@@ -233,7 +245,7 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
             }
 
             var listno = parseInt(l)+parseInt(1)+jyno;
-            lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["_id"]+"'>"
+            lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["fid"]+"'>"
             +"<div class='jyfwlistno'>"+listno+".</div>"
             +"<div class='jyfwlisttitle'>"+lastarr[l]["s_entname"]+"</div>"
             +"<div style='clear:both;'></div>"+rem
@@ -244,7 +256,6 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
             html = fronthtml + lasthtml;
         $(".listpage ul").append(html);
 
-        {{end}}
 		$(".tip").show();
 
         $(".listpage li").click(function(){
@@ -255,7 +266,6 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
         });
 
         var flag = {{.T.flag}};
-        var followEntLimit = {{.T.followEntLimit}};
         $("#addDiv").click(function(){
             if(flag){
                 EasyAlert.show("最多可关注<br>"+followEntLimit+"个企业!");
@@ -263,6 +273,7 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
             }
             window.location.href = "/jylab/followent/addEnt";
         });
+      })
 
         $(".jylistbottom").click(function(){
             easyPopup.show("easypopup");

+ 41 - 34
src/jfw/modules/followent/src/web/templates/weixin/set.html

@@ -52,8 +52,8 @@ if(sessionStorage){
 <script type="text/javascript">
 	var data = {{.T.data}};
 	var winner = {{.T.winner}}; //企业名称
-	var follow = {{.T.follow}};   
-	var isOld = 0; 
+	var follow = {{.T.follow}};
+	var isOld = 0;
 	initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avatar}});
 	$(function(){
 		$(window).bind("pageshow", function(event){
@@ -65,27 +65,33 @@ if(sessionStorage){
 	    });
 		$(".qyxx").css("padding-top",$(".noticehead").outerHeight());
 		//解决样式回显问题
-		$.post(
-			"/jylab/followent/ajaxSearch",
-			{"winner":winner},
-			function(r){
-				follow = r.follow;
-				if(follow == "n"){
-					$(".gz-followcancel").removeClass("hidden");
-				}else{
-					$(".qy-followcancel").removeClass("hidden");
-				}
-			}
-		)
-		
-		
+    follow = follow;
+    if(follow == "n"){
+      $(".gz-followcancel").removeClass("hidden");
+    }else{
+      $(".qy-followcancel").removeClass("hidden");
+    }
+		// $.post(
+		// 	"/jylab/followent/ajaxSearch",
+		// 	{"winner":winner},
+		// 	function(r){
+		// 		follow = r.follow;
+		// 		if(follow == "n"){
+		// 			$(".gz-followcancel").removeClass("hidden");
+		// 		}else{
+		// 			$(".qy-followcancel").removeClass("hidden");
+		// 		}
+		// 	}
+		// )
+
+
 		//alert(follow);
 		//if(follow == "n"){
 		//	$(".gz-followcancel").removeClass("hidden");
 		//}else{
 		///	$(".qy-followcancel").removeClass("hidden");
 		//}
-		
+
 		var easyPopup = new EasyPopup("easypopup");
 		if(data.length > 0){
 			for(var i = 0; i < data.length; i++){
@@ -96,9 +102,9 @@ if(sessionStorage){
 				var typeStr = '';
 				var title = data[i]["title"];
 				var amount = data[i]["bidamount"];
-			
+
 				if(data[i]["publishtime"]){
-					noticetime = new Date(Number(data[i]["publishtime"]+"000")).Format("MM-dd");	
+					noticetime = new Date(Number(data[i]["publishtime"]+"000")).Format("MM-dd");
 				}
 				if(typeof(data[i]["subtype"]) != "undefined" && data[i]["subtype"] != "" && data[i]["subtype"] != null){
 					type = data[i]["subtype"];
@@ -109,7 +115,7 @@ if(sessionStorage){
 				}else{
 					typeStr = '<span class="typenull">'+type+'</span>';
 				}
-				
+
 				if(typeof(amount) != "undefined" && amount != null && amount != ""){
 					amount = parseInt(amount)/10000;
 					amountHtml = '<span class="priceStyle">'+amount+'万元中标</span>';
@@ -127,13 +133,13 @@ if(sessionStorage){
 									+amountHtml
 				       			+'</div>'
 				    		+'</div>'
-				$(".jynotice").append(listhtml);			
+				$(".jynotice").append(listhtml);
 			}
 		}else{
 			$(".qyxx").addClass("hidden");
 			$(".nullXx").removeClass("hidden");
 		}
-		
+
 		//取消企业关注
 		$(".qy-followcancel").click(function(){
 			easyPopup.show();
@@ -142,11 +148,12 @@ if(sessionStorage){
 		$("#sure").click(function(){
 			easyPopup.hide();
 			//发送Ajax请求,取消关注
+      const eid = window.location.href.split("/")[6]
 			$.post(
-				"/jylab/followent/qgFollow",
-				{"name":winner},
+				"/bigmember/follow/ent/delFollow",
+        {"fid":eid},
 				function(r){
-					if(r.status == "y"){
+					if(r.data == "success"){
 						if(sessionStorage){
 							sessionStorage.followSetReload = "1";
 						}
@@ -159,17 +166,17 @@ if(sessionStorage){
 							}else{
 								window.location.href = "/jylab/followent/entList";
 							}
-							
+
 						},1000)
 					}
-				}				
-			)	
+				}
+			)
 		});
 		//取消
 		$("#cancel").click(function(){
 			easyPopup.hide();
 		});
-		
+
 		//关注企业
 		$(".gz-followcancel").click(function(){
 			$.post(
@@ -184,7 +191,7 @@ if(sessionStorage){
   						sessionStorage.version="1";
   						setTimeout(function(){
   							window.location.href = "/jylab/followent/entList";
-  						},1000)	
+  						},1000)
          		}else if(r.status == "m"){
               EasyAlert.show("最多可关注10个企业!");
          		}else{
@@ -192,7 +199,7 @@ if(sessionStorage){
           	}
 				}
 			)
-    })	
+    })
     // 有大会员招标决策权限时隐藏入口
     // $.ajax({
     //   type: 'GET',
@@ -206,7 +213,7 @@ if(sessionStorage){
     //   }
     // })
 	})
-	
+
 function isVisited(sid){
   var a_visited = {{.T.a_visited}};
   var visited = visitedPath.pathVisited(
@@ -244,7 +251,7 @@ function beforeRedirect(obj,sid,link,isOld){
         投标决策分析
       </span>
     </li> -->
-		<li class="jynotice">	
+		<li class="jynotice">
 		</li>
 	</ul>
 	<div class = "nullXx hidden" style="text-align:center;padding-bottom:8px;">
@@ -265,4 +272,4 @@ function beforeRedirect(obj,sid,link,isOld){
 	</div>
 {{include "/common/baiducc.html"}}
 </body>
-</html>
+</html>

+ 1 - 0
src/jfw/modules/publicapply/src/ad/entity/struct.go

@@ -17,6 +17,7 @@ type AdInfo struct {
 		Width     string `json:"width"`     //宽度
 		StartTime string `json:"startTime"` //开始时间
 		EndTime   string `json:"endTime"`   //结束时间
+		IosHref   string `json:"iosHref"`   //根据客户端不同 是否访问不同地址
 	} `json:"o_extend"` //拓展属性
 	S_script string `json:"s_script"` //脚本
 }

+ 6 - 3
src/jfw/modules/publicapply/src/bidcollection/entity/entity.go

@@ -507,7 +507,7 @@ type InfoList struct {
 
 //根据id取内容
 func GetInfoById(Mgo_bidding mg.MongodbSim, bidding, bidding_back string, idlist []map[string]interface{}) []*InfoList {
-	array := make([]*InfoList, len(idlist))
+	var array []*InfoList
 	if len(idlist) == 0 {
 		return array
 	}
@@ -573,12 +573,15 @@ func GetInfoById(Mgo_bidding mg.MongodbSim, bidding, bidding_back string, idlist
 		}
 	}
 	//
-	for k, v := range idlist {
+	for _, v := range idlist {
 		info := infos[qu.ObjToString(v["bid"])]
+		if qu.ObjToString(info["title"]) == "" {
+			continue
+		}
 		if info == nil {
 			info = map[string]interface{}{}
 		}
-		array[k] = InfoFormat(qu.ObjToString(v["bid"]), &info)
+		array = append(array, InfoFormat(qu.ObjToString(v["bid"]), &info))
 	}
 	return array
 }

+ 5 - 1
src/jfw/modules/publicapply/src/config.json

@@ -46,5 +46,9 @@
     "followPushRpc": "127.0.0.1:8759",
     "file_number": 10,
     "smsServiceRpc":"127.0.0.1:932",
-    "fileSignBool":true
+    "fileSignBool":true,
+    "followCustomer": {
+      "customerNumb": 10,
+      "enterpriseNumb": 500
+    }
 }

+ 4 - 0
src/jfw/modules/publicapply/src/config/config.go

@@ -23,6 +23,10 @@ type config struct {
 	FollowPushRpc         string
 	SmsServiceRpc         string
 	FileSignBool          bool
+	FollowCustomer        struct {
+		CustomerNumb   int
+		EnterpriseNumb int
+	}
 }
 type BidColl struct {
 	PayUserCollLimit      int    //付费用户收藏数量最大限制

+ 83 - 18
src/jfw/modules/publicapply/src/customer/entity/entiy.go

@@ -1,6 +1,7 @@
 package entity
 
 import (
+	"config"
 	"db"
 	"fmt"
 	qu "qfw/util"
@@ -13,6 +14,7 @@ import (
 
 type CustomerOperation struct {
 	UserId   string `json:"userId"`
+	EntId    int    `json:"entId"`
 	Name     string `json:"name"`
 	Province string `json:"province"`
 	City     string `json:"city"`
@@ -38,9 +40,10 @@ type CustomerInfo struct {
 	Province   string `json:"province"`
 	Buyerclass string `json:"buyerclass"`
 	Followdate string `json:"followdate"`
+	CustomerId string `json:"customerId"`
 }
 
-//是否关注此企业客户
+// 是否关注此企业客户
 func (this *CustomerOperation) CheckIsFollow() bool {
 	return db.Mgo.Count(fc, map[string]interface{}{
 		"userId": this.UserId,
@@ -48,7 +51,7 @@ func (this *CustomerOperation) CheckIsFollow() bool {
 	}) > 0
 }
 
-//不是我的客户
+// 不是我的客户
 func (this *CustomerOperation) Exclude() (B bool) {
 	timeNow := time.Now()
 	updateMap := map[string]interface{}{
@@ -73,12 +76,11 @@ func (this *CustomerOperation) Exclude() (B bool) {
 	return B
 }
 
-//列表
-func (this *CustomerOperation) CList(pageSize, pageNo int, keyword string) ([]*CustomerInfo, int, int) {
-	var cinfoarr = []*CustomerInfo{}
-	startPage := pageSize * (pageNo - 1)
+// 列表
+func (this *CustomerOperation) CList(pageSize, pageNo, entUserId int, keyword, isCliam string) ([]*CustomerInfo, int, int, int) {
+	var cinfoarr, cinfoarrAll = []*CustomerInfo{}, []*CustomerInfo{}
 	entnames := []string{}
-	count, total := 0, 0
+	total := 0
 	query := map[string]interface{}{
 		"userId": this.UserId,
 	}
@@ -87,28 +89,59 @@ func (this *CustomerOperation) CList(pageSize, pageNo int, keyword string) ([]*C
 		total = db.Mgo.Count(fc, query)
 		redis.Put(redisName, fmt.Sprintf(redisCountKey, this.UserId), total, 2*60*60)
 	}
-	if keyword != "" {
-		query["name"] = map[string]interface{}{
-			"$regex": keyword,
+
+	//大会员客户关注上限
+	BigMsg := jy.GetBigVipUserBaseMsg(this.UserId, db.Mysql, db.Mgo)
+	entVip := jy.GetEntnicheState(this.UserId, db.Mysql, db.Mgo)
+	customerMap := map[string]interface{}{}
+	if entVip.EntnicheStatus > 0 {
+		//非大会员商机管理用户兼容查询商机管理权限
+		if BigMsg.Customers < config.Config.FollowCustomer.CustomerNumb {
+			BigMsg.Customers = config.Config.FollowCustomer.CustomerNumb
+		}
+		customerList := db.Mysql.SelectBySql("SELECT ec.name,euu.customer_id FROM entniche_user_customer euu LEFT JOIN entniche_customer ec ON ec.id = euu.customer_id  WHERE user_id = ? AND (source_type =1 or source_type =4) ", entUserId)
+		for _, value := range *customerList {
+			customerMap[qu.ObjToString(value["name"])] = value["customer_id"]
 		}
 	}
-	count = db.Mgo.Count(fc, query)
-	clist, ok := db.Mgo.Find(fc, query, `{"date":-1}`, `{"name":1,"date":1}`, false, startPage, pageSize)
+
+	clist, ok := db.Mgo.Find(fc, query, `{"date":-1}`, `{"name":1,"date":1}`, false, 0, BigMsg.Customers)
 	if ok && clist != nil && len(*clist) > 0 {
+		total = len(*clist)
 		for _, v := range *clist {
+			if keyword != "" && !strings.Contains(qu.ObjToString(v["name"]), keyword) {
+				continue
+			}
+			switch isCliam {
+			case "0":
+				if customerMap[qu.ObjToString(v["name"])] != nil {
+					continue
+				}
+			case "1":
+				if customerMap[qu.ObjToString(v["name"])] == nil {
+					continue
+				}
+			}
 			entnames = append(entnames, v["name"].(string))
 			date := v["date"]
-			cinfoarr = append(cinfoarr, &CustomerInfo{
+			cinfoarrAll = append(cinfoarrAll, &CustomerInfo{
 				Name:       v["name"].(string),
 				Followdate: qu.FormatDateWithObj(&date, "2006/01/02"),
 			})
 		}
 	}
+	if (pageNo+1)*pageSize >= len(cinfoarrAll) {
+		cinfoarr = cinfoarrAll[pageNo*pageSize:]
+	} else {
+		cinfoarr = cinfoarrAll[pageNo*pageSize : (pageNo+1)*pageSize]
+	}
+	count := len(cinfoarrAll)
 	entinfolist := GetEntCusInfo(entnames)
 	if len(entinfolist) > 0 {
 	L:
 		for _, v := range entinfolist {
 			for _, ev := range cinfoarr {
+				(*ev).CustomerId = qu.SE.Encode2HexByCheck(fmt.Sprint(customerMap[(*ev).Name]))
 				if (*ev).Name == qu.ObjToString(v["buyer_name"]) {
 					(*ev).Province = qu.ObjToString(v["province"])
 					(*ev).Buyerclass = qu.ObjToString(v["buyerclass"])
@@ -117,20 +150,19 @@ func (this *CustomerOperation) CList(pageSize, pageNo int, keyword string) ([]*C
 			}
 		}
 	}
-	return cinfoarr, count, total
+	return cinfoarr, total, BigMsg.Customers, count
 }
 
-//
 var pcquery = `{"query": {"bool": {"must": [{"terms": {"%s": [%s]}}],"must_not": [],"should": []}},"sort": []}`
 
-//获取企业-客户信息
+// 获取企业-客户信息
 func GetEntCusInfo(entnames []string) []map[string]interface{} {
 	query := fmt.Sprintf(pcquery, "buyer_name", `"`+strings.Join(entnames, `","`)+`"`)
 	list := *elastic.Get("buyer", "buyer", query)
 	return list
 }
 
-//权限查询
+// 权限查询
 func (this *CustomerOperation) CheckPower() string {
 	msg := ""
 	if this.UserId == "" {
@@ -148,6 +180,10 @@ func (this *CustomerOperation) CheckPower() string {
 			if count >= userPower.Customers {
 				msg = fmt.Sprintf("对不起,您最多可关注%d个客户", userPower.Customers)
 			}
+		} else if entUser := jy.GetEntnicheState(this.UserId, db.Mysql, db.Mgo); entUser.EntnicheStatus > 0 {
+			//兼容商机管理用户权限搜索
+			return EntCheckPower(this.UserId, this.EntId)
+
 		} else {
 			msg = "暂无关注客户权限"
 		}
@@ -155,7 +191,36 @@ func (this *CustomerOperation) CheckPower() string {
 	return msg
 }
 
-//
+func EntCheckPower(userId string, entId int) (msg string) {
+	query := map[string]interface{}{
+		"ent_id": entId,
+	}
+
+	res, _ := db.Mgo.Find(fc, query, nil, `{"name":1}`, false, -1, -1)
+	if len((*res)) > config.Config.FollowCustomer.EnterpriseNumb {
+		data := map[string]interface{}{}
+		i := 0
+		for _, value := range *res {
+			if data[qu.ObjToString(value["name"])] == nil {
+				i++
+				data[qu.ObjToString(value["name"])] = 1
+			}
+		}
+		if i >= config.Config.FollowCustomer.EnterpriseNumb {
+			msg = fmt.Sprintf("您的企业关注客户数量已经超过%d,请取消关注部分后再操作。", config.Config.FollowCustomer.EnterpriseNumb)
+		}
+	}
+
+	query = map[string]interface{}{
+		"userId": userId,
+	}
+	delete(query, "ent_id")
+	count := db.Mgo.Count(fc, query)
+	if count >= config.Config.FollowCustomer.EnterpriseNumb {
+		msg = fmt.Sprintf("您的关注客户数量已经超过%d,请取消关注部分后再操作。", config.Config.FollowCustomer.CustomerNumb)
+	}
+	return
+}
 func (this *CustomerOperation) Coperation() (B bool) {
 	queryMap := map[string]interface{}{
 		"userId": this.UserId,

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

@@ -7,7 +7,7 @@ import (
 	qu "qfw/util"
 )
 
-//是否关注此企业客户
+// 是否关注此企业客户
 func (this *ServiceStruct) Check() {
 	userId, _ := this.GetSession("userId").(string)
 	defer qu.Catch()
@@ -30,7 +30,7 @@ func (this *ServiceStruct) Check() {
 	this.ServeJson(r)
 }
 
-//不是我的客户
+// 不是我的客户
 func (this *ServiceStruct) Exclude() {
 	userId, _ := this.GetSession("userId").(string)
 	defer qu.Catch()
@@ -53,7 +53,7 @@ func (this *ServiceStruct) Exclude() {
 	this.ServeJson(r)
 }
 
-//关注客户列表
+// 关注客户列表
 func (this *ServiceStruct) CstList() {
 	userId, _ := this.GetSession("userId").(string)
 	defer qu.Catch()
@@ -63,26 +63,26 @@ func (this *ServiceStruct) CstList() {
 		}
 		cotion := entity.NewCustomerOperation()
 		cotion.UserId = userId
+		entUserId := qu.IntAll(this.GetSession("entUserId")) //获取企业id
 		pageSize, _ := this.GetInteger("pagesize")
 		pageNo, _ := this.GetInteger("pageno")
 		keyword := this.GetString("keyword")
+		isCliam := this.GetString("isCliam")
 		if pageSize <= 0 {
 			pageSize = 20
 		}
-		if pageNo <= 0 {
-			pageNo = 1
-		}
-		res, count, total := cotion.CList(pageSize, pageNo, keyword)
+		res, total, maxNum, count := cotion.CList(pageSize, pageNo, entUserId, keyword, isCliam)
 		return Result{Data: map[string]interface{}{
-			"list":  res,
-			"count": count,
-			"total": total,
+			"list":     res,
+			"count":    count,
+			"total":    total,
+			"countMax": maxNum,
 		}}
 	}()
 	this.ServeJson(r)
 }
 
-//关注or取关客户
+// 关注or取关客户
 func (this *ServiceStruct) CstAtt() {
 	userId, _ := this.GetSession("userId").(string)
 	defer qu.Catch()
@@ -100,6 +100,8 @@ func (this *ServiceStruct) CstAtt() {
 			return Result{Data: nil, Error_msg: Error_msg_1003}
 		}
 		cotion.UserId = userId
+		cotion.EntId = qu.IntAll(this.GetSession("entId"))
+
 		msg := cotion.CheckPower()
 		if !cotion.B && msg != "" {
 			return Result{Data: false, Error_msg: msg}

+ 4 - 1
src/jfw/modules/publicapply/src/dataexport/service/action.go

@@ -196,8 +196,11 @@ func (des *DataExportStruct) ByPushHistory() {
 		if vipType == "" { //默认取已切换的企业
 			vipType = jy.SwitchService.GetEntniche(des.Session(), db.Mgo, db.Mysql)
 		}
+		if vipType == jy.SwitchService.Entniche {
+			userId = fmt.Sprint(util.IntAll(des.GetSession("entUserId")))
+		}
+		//entId := util.IntAll(sp.GetSession("entId"))
 		exportNum, _ := des.GetInteger("exportNum")
-
 		spqp := &jy.SubPushQueryParam{
 			Mgo_bidding:   db.Mgo_Bidding,
 			Bidding:       db.DbConf.Mongodb.Bidding.Collection,

+ 1 - 1
src/jfw/modules/publicapply/src/db.json

@@ -42,7 +42,7 @@
 	},
 	"redis": {
 		"main":{
-			"address": "other=192.168.3.206:1712,session=192.168.3.206:1712,pushcache_1=192.168.3.206:5000,pushcache_2_a=192.168.3.206:5001,pushcache_2_b=192.168.3.206:5002"
+			"address": "other=192.168.3.206:1712,session=192.168.3.206:1712,pushcache_1=192.168.3.206:5000,pushcache_2_a=192.168.3.206:5001,pushcache_2_b=192.168.3.206:5002,newother=192.168.3.206:1712"
 		}
 	},
 	"mysql": {

+ 2 - 2
src/jfw/modules/publicapply/src/db/db.go

@@ -190,8 +190,8 @@ func init() {
 			jy.PushMapping.Init(MysqlEntnichePush)
 		}
 		//初始化基础服务mysql base_service
-		if DbConf.Mysql.Main != nil {
-			log.Println("初始化 mysql base_service")
+		if DbConf.Mysql.SupplyInfo != nil {
+			log.Println("初始化 mysql SupplyInfo")
 			MysqlSupplyInfo = &mysql.Mysql{
 				Address:      DbConf.Mysql.SupplyInfo.Address,
 				UserName:     DbConf.Mysql.SupplyInfo.UserName,

+ 15 - 1
src/jfw/modules/publicapply/src/subscribePush/service/pushList.go

@@ -166,7 +166,7 @@ func (sp *SubscribePush) HasPushHistory() {
 	//免费用户无推送记录生成推送记录=>默认推送调整-付费用户默认1000条 免费不变
 	if spqp.PageNum <= 1 && len(list) == 0 && spqp.IsEmpty() {
 		//flag, data := jy.NewSubscribePush().MakeHistoryDatas(db.Mgo, db.MysqlPush, userId, entity.PushView)
-		flag, data := jy.NewSubscribePush(vipType).MakeHistoryDatasNew(spqp.PushMysql, userId, entId, entity.DefaultPushList)
+		flag, data, _ := jy.NewSubscribePush(vipType).MakeHistoryDatasNew(spqp.PushMysql, userId, entId, entity.DefaultPushList)
 		if data != nil {
 			hasNextPage = flag
 			jsonBytes, err := json.Marshal(data)
@@ -216,6 +216,7 @@ func (sp *SubscribePush) HistoryPaging() {
 	if vipType == jy.SwitchService.Entniche {
 		userId = fmt.Sprint(util.IntAll(sp.GetSession("entUserId")))
 	}
+	entId := util.IntAll(sp.GetSession("entId"))
 	pageNum, _ := sp.GetInteger("pageNum")
 	PageSize, _ := sp.GetInteger("pageSize")
 	if pageNum == 1 {
@@ -246,6 +247,19 @@ func (sp *SubscribePush) HistoryPaging() {
 		spqp.PushMysql = db.MysqlPush
 	}
 	hasNextPage, total, list := jy.NewSubscribePush(vipType).Datas(spqp)
+	//免费用户无推送记录生成推送记录=>默认推送调整-付费用户默认1000条 免费不变
+	if spqp.PageNum <= 1 && len(list) == 0 && spqp.IsEmpty() {
+		flag, data, count := jy.NewSubscribePush(vipType).MakeHistoryDatasNew(spqp.PushMysql, userId, entId, entity.DefaultPushList)
+		if data != nil {
+			hasNextPage = flag
+			total = int64(count)
+			jsonBytes, err := json.Marshal(data)
+			err = json.Unmarshal(jsonBytes, &list)
+			if err != nil {
+				log.Println("err:", err)
+			}
+		}
+	}
 	//查询是否收藏
 	jy.NewSubscribePush().MakeCollection(userId, db.Mysql, list, config.Config.FileSignBool)
 	//是否有关键词

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

@@ -75,4 +75,6 @@ func init() {
 	xweb.AddRouter("/jypay", &service.AreaPack{})
 	//公共资源包
 	xweb.AddRouter("/jypay", &service.ResourcePack{})
+
+	xweb.AddRouter("/jypay", &service.SalesCreateOrder{})
 }

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

@@ -112,6 +112,17 @@
 	"nsq":"192.168.3.240:4260",
   "nsq_topic": "jy_event",
   "userCenterApi":"https://web-zxl.jydev.jianyu360.com",
+  "vipKeyMaxLength":300,
+  "activityOrderCountdown":30,
   "companySize": 10,
-  "vipKeyMaxLength":300
+  "webSiteParameter": {
+    "addr": "https://webdev-qmx_admin.jydev.jianyu360.com/api/admin/",
+    "action": "/message/sendMessageApi",
+    "title": "你有新的未支付订单",
+    "content": "购买超级订阅,立享专属限时优惠!点击前往支付>>",
+    "link": "/front/vipOrder/vipOrderDetail?order_code=%s",
+    "androidUrl": "/jyapp/vipsubscribe/toOrderDetailPage?orderCode=%s",
+    "iosUrl": "/jyapp/vipsubscribe/toOrderDetailPage?orderCode=%s",
+    "weChatUrl": "/front/vipsubscribe/toOrderDetailPage?orderCode=%s"
+  }
 }

+ 38 - 26
src/jfw/modules/subscribepay/src/config/config.go

@@ -58,25 +58,36 @@ type config struct {
 		Pwd  string
 		User string
 	}
-	ExpireRemind       []int
-	WxTplExpire        string
-	TermValidity       int
-	OrderCountdown     interface{}
-	AllPayMoney        int
-	AutoMergeTime      int64
-	ProfitTitle        string
-	ProfitDescript     string
-	AccountMergeOnline string
-	OptimalTime        string
-	ActivityName       string
-	ShareRedisName     string
-	Product            map[string]bool
-	SmsServiceRpc      string
-	Nsq                string
-	Nsq_Topic          string
-	UserCenterApi      string
-	CompanySize        int64
-	VipKeyMaxLength    int64
+	VipKeyMaxLength        int64
+	ExpireRemind           []int
+	WxTplExpire            string
+	TermValidity           int
+	OrderCountdown         interface{}
+	AllPayMoney            int
+	AutoMergeTime          int64
+	ProfitTitle            string
+	ProfitDescript         string
+	AccountMergeOnline     string
+	OptimalTime            string
+	ActivityName           string
+	ShareRedisName         string
+	Product                map[string]bool
+	SmsServiceRpc          string
+	Nsq                    string
+	Nsq_Topic              string
+	UserCenterApi          string
+	ActivityOrderCountdown int64
+	CompanySize            int64
+	WebSiteParameter       struct {
+		Addr       string
+		Action     string
+		Title      string
+		Content    string
+		Link       string
+		AndroidUrl string
+		IosUrl     string
+		WeChatUrl  string
+	}
 }
 type mgoConf struct {
 	Address           string
@@ -102,13 +113,14 @@ type timeTaskConfig struct {
 		LiveActiveAfterOrder  int64 //直播活动下单后n小时提醒
 		LiveActiveAfterOrders int64 //直播活动下单后n小时提醒(2次提醒)
 	}
-	CourseTask                     string //更新课程已下线状态
-	MemberExpire                   string //大会员gengx到期时间
-	MemberIsStart                  string //大会员用户开启时间
-	MemberServiceIsExpire          string //大会员用户服务开启或到期时间
-	DataExportSendMailDuringMinute int    //数据导出发送邮件定时任务
-	UpdateDEStatus                 string //定时更新超时订单状态-2
-	ProvinceExpire                 string //省份订阅包
+	CourseTask                         string //更新课程已下线状态
+	MemberExpire                       string //大会员gengx到期时间
+	MemberIsStart                      string //大会员用户开启时间
+	MemberServiceIsExpire              string //大会员用户服务开启或到期时间
+	DataExportSendMailDuringMinute     int    //数据导出发送邮件定时任务
+	UpdateDEStatus                     string //定时更新超时订单状态-2
+	ProvinceExpire                     string //省份订阅包
+	UpdateTimeLimitActivityOrderStatus string //限时活动取消订单定时任务
 }
 type messageConfig struct {
 	WxTpl_OnTrial_SoonExpire   *WxTplMsg //微信-超级订阅-试用即将到期

+ 6 - 10
src/jfw/modules/subscribepay/src/entity/aiForecastPack.go

@@ -14,15 +14,9 @@ type aiForecastPackStruct struct{}
 var AiForecastPackStruct aiForecastPackStruct
 var serviceId = 15
 
-//AI预测包支付完成回调方法
+// AI预测包支付完成回调方法
 func (a *aiForecastPackStruct) PayCallBack(param *CallBackParam) bool {
-	query := map[string]interface{}{}
-	if param.OrderCode != "" { //线下支付
-		query["order_code"] = param.OrderCode
-	} else { //支付宝微信回调
-		query["out_trade_no"] = param.OutTradeno
-	}
-	orderdata := util.Mysql.FindOne("dataexport_order", query, "id,filter,order_status,user_id,vip_type", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,order_status,user_id,vip_type", "")
 	if orderdata == nil {
 		return false
 	}
@@ -43,6 +37,8 @@ func (a *aiForecastPackStruct) PayCallBack(param *CallBackParam) bool {
 				"pay_money":    param.CashFee,
 				"pay_time":     nowFormat,
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 			if update {
 				//取消其他订单
@@ -53,7 +49,7 @@ func (a *aiForecastPackStruct) PayCallBack(param *CallBackParam) bool {
 	return true
 }
 
-//更新大会员服务表 信息 服务id=15
+// 更新大会员服务表 信息 服务id=15
 func UpdateAiCount(count int, userId, now string) {
 	log.Println("----------UpdateAiCount------------15")
 	if util.Mysql.UpdateOrDeleteBySql(`UPDATE `+jy.BigmemberUserPowerTable+` SET
@@ -63,7 +59,7 @@ func UpdateAiCount(count int, userId, now string) {
 	RechargeList(count, userId) //保存充值记录
 }
 
-//充值记录
+// 充值记录
 func RechargeList(count int, userId string) {
 	servcieInfos := util.Mysql.SelectBySql(`SELECT * FROM `+jy.BigmemberUserPowerTable+` a WHERE a.s_userid = ? AND a.i_status = 0 AND a.s_serviceid = ?;`, userId, serviceId)
 	if len(*servcieInfos) > 0 {

+ 11 - 10
src/jfw/modules/subscribepay/src/entity/areaPack.go

@@ -12,7 +12,7 @@ import (
 
 var AreaPackPrice areaPackPrice
 
-//价格表
+// 价格表
 type areaPackPrice struct {
 	Month struct {
 		OneProvince_allBuyerClass int `json:"oneProvince_allBuyerClass"` //一个省份全部行业
@@ -48,7 +48,7 @@ type AreaPackFilter struct {
 }
 
 /*
-	获取价格
+获取价格
 */
 func (this *AreaPackFilter) Price() int {
 	switch this.Cycleunit {
@@ -117,10 +117,8 @@ func (this *AreaPackFilter) UpgradePrice(userid string) int {
 
 // PayCallBack 支付完成回调
 func (this *areaPackPrice) PayCallBack(param *CallBackParam) bool {
-	orderData := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
-		"out_trade_no": param.OutTradeno,
-		"product_type": "省份订阅包",
-	}, "id,order_status,order_code,filter,user_id,d_relation_id,dis_word,order_money,vip_starttime,vip_endtime", "")
+	orderData := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(map[string]interface{}{"product_type": "省份订阅包"}),
+		"id,order_status,order_code,filter,user_id,d_relation_id,dis_word,order_money,vip_starttime,vip_endtime", "")
 	if orderData != nil {
 		userId := qutil.ObjToString((*orderData)["user_id"])
 		now := time.Now()
@@ -129,6 +127,8 @@ func (this *areaPackPrice) PayCallBack(param *CallBackParam) bool {
 			"pay_money":    param.CashFee,
 			"pay_time":     payTime,
 			"order_status": 1,
+			//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+			"out_trade_no": param.OutTradeno,
 		}
 		if order_status := qutil.IntAll((*orderData)["order_status"]); order_status == 0 {
 			st := qutil.ObjToString((*orderData)["vip_starttime"])
@@ -186,7 +186,7 @@ func (this *areaPackPrice) PayCallBack(param *CallBackParam) bool {
 	return false
 }
 
-//修改用户权益
+// 修改用户权益
 func (this *AreaPackFilter) Power(userid string, startime, endtime time.Time) bool {
 	setMap := map[string]interface{}{
 		"o_jy.o_buyset_p":  map[string]interface{}{"areacount": this.Num},
@@ -208,7 +208,7 @@ func (this *AreaPackFilter) Power(userid string, startime, endtime time.Time) bo
 	return false
 }
 
-//获取产品id
+// 获取产品id
 func (this *AreaPackFilter) ProductId() string {
 	switch this.Cycleunit {
 	case 1:
@@ -221,7 +221,7 @@ func (this *AreaPackFilter) ProductId() string {
 	return "省份订阅包"
 }
 
-//月份转化 1月 2季 3年
+// 月份转化 1月 2季 3年
 func (this *AreaPackFilter) ToMonth() int {
 	switch this.Cycleunit {
 	case 1:
@@ -234,7 +234,8 @@ func (this *AreaPackFilter) ToMonth() int {
 	return -1
 }
 
-/*getDate方法的参数1:年 2:月 4:季度
+/*
+getDate方法的参数1:年 2:月 4:季度
 参数转化
 i:日期单位 1月 2季 3年
 */

+ 6 - 10
src/jfw/modules/subscribepay/src/entity/bidfile.go

@@ -15,15 +15,9 @@ type bidfile struct{}
 var Bidfile bidfile
 var bidfileServiceId = 11
 
-//招标文件解读支付完成回调方法
+// 招标文件解读支付完成回调方法
 func (b *bidfile) PayCallBack(param *CallBackParam) bool {
-	query := map[string]interface{}{}
-	if param.OrderCode != "" { //线下支付
-		query["order_code"] = param.OrderCode
-	} else { //支付宝微信回调
-		query["out_trade_no"] = param.OutTradeno
-	}
-	orderdata := util.Mysql.FindOne("dataexport_order", query, "id,filter,order_status,user_id,product_type", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,order_status,user_id,product_type", "")
 	if orderdata == nil {
 		return false
 	}
@@ -50,6 +44,8 @@ func (b *bidfile) PayCallBack(param *CallBackParam) bool {
 				"pay_money":    param.CashFee,
 				"pay_time":     nowFormat,
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 			if update {
 				//取消其他订单
@@ -61,7 +57,7 @@ func (b *bidfile) PayCallBack(param *CallBackParam) bool {
 	return true
 }
 
-//count 使用次数, isBig是否是大会员订单
+// count 使用次数, isBig是否是大会员订单
 func UpdateCount(count int, userId, endtime string, isBig bool) bool {
 	now := time.Now()
 	nowFormat := qutil.FormatDate(&now, qutil.Date_Full_Layout)
@@ -76,7 +72,7 @@ func UpdateCount(count int, userId, endtime string, isBig bool) bool {
 		l_endtime := GetTime("2006年01月02日15:04:05", dt).Format(qutil.Date_Full_Layout)
 		servcieInfos := util.Mysql.SelectBySql(`SELECT * FROM `+jy.BigmemberUserPowerTable+` a WHERE a.s_userid = ? AND a.i_status = 0 AND a.s_serviceid = ?;`, userId, bidfileServiceId)
 		if len(*servcieInfos) <= 0 {
-			util.Mysql.InsertBySql(`INSERT INTO bigmember_service_user 
+			util.Mysql.InsertBySql(`INSERT INTO bigmember_service_user
 					  (s_userid,s_serviceid,i_frequency,l_starttime,l_endtime,i_status,l_createtime,l_updatetime)
                        VALUES
                        (?,?,?,?,?,?,?,?);`, userId, 11, 0, nowFormat, l_endtime, 0, nowFormat, nowFormat)

+ 9 - 9
src/jfw/modules/subscribepay/src/entity/dataExportPackStruct.go

@@ -20,7 +20,7 @@ import (
 	"github.com/go-xweb/httpsession"
 )
 
-//剑鱼数据流量包
+// 剑鱼数据流量包
 type dataExportPackStruct struct{}
 
 var JyDataExportPack dataExportPackStruct
@@ -62,10 +62,8 @@ func init() {
 
 // PayCallBack 支付完成回调
 func (this *dataExportPackStruct) PayCallBack(param *CallBackParam) bool {
-	orderData := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
-		"out_trade_no": param.OutTradeno,
-		"product_type": "数据流量包",
-	}, "id,order_status,order_code,filter,user_id,d_relation_id,dis_word,order_money", "")
+	orderData := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(map[string]interface{}{"product_type": "数据流量包"}),
+		"id,order_status,order_code,filter,user_id,d_relation_id,dis_word,order_money", "")
 	if orderData != nil {
 		now := time.Now()
 		if order_status := qutil.IntAll((*orderData)["order_status"]); order_status == 0 {
@@ -76,6 +74,8 @@ func (this *dataExportPackStruct) PayCallBack(param *CallBackParam) bool {
 				"pay_money":    param.CashFee,
 				"pay_time":     payTime,
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 			if update {
 				filter := qutil.ObjToString((*orderData)["filter"])
@@ -151,7 +151,7 @@ func (this *dataExportPackStruct) GetPackDetailById(packId string) (*PackDetail,
 	return packDetail, nil
 }
 
-//GetAccountMsg 查询账户和企业数据包情况
+// GetAccountMsg 查询账户和企业数据包情况
 func (this *dataExportPackStruct) GetAccountMsg(sess *httpsession.Session, userId string) (map[string]interface{}, error) {
 	//每日限量包
 	packDetail := map[string]interface{}{}
@@ -557,7 +557,7 @@ func (this *dataExportPackStruct) PerRechargeList(userId string, pageNum, pageSi
 	return perPackRecharge(userId, pageNum, pageSize)
 }
 
-//查询企业账户余额
+// 查询企业账户余额
 func getCurrEntCount(entName, entPhone string) int {
 	current, ok := util.Mgo_Qyfw.FindOne("user", map[string]interface{}{"phone": entPhone, "username": entName})
 	if current == nil || !ok {
@@ -570,7 +570,7 @@ func getCurrEntCount(entName, entPhone string) int {
 	return qutil.IntAll(plan["current"])
 }
 
-//根据筛选id获取筛选条件
+// 根据筛选id获取筛选条件
 func getSearchValueById(filterId string) (searchMap map[string]interface{}) {
 	filter, _ := util.MQFW.FindById("export_search", filterId, `{"buyerclass":1,"publishtime":1,"area":1,"comeinfrom":1}`)
 	if filter != nil && len(*filter) > 0 {
@@ -584,7 +584,7 @@ func getSearchValueById(filterId string) (searchMap map[string]interface{}) {
 	return
 }
 
-//根据用户id查询用户名
+// 根据用户id查询用户名
 func getUserName(userId string) string {
 	userRow, _ := util.MQFW.FindById("user", userId, `{"s_nickname":1,"s_phone":1,"s_jyname":1}`)
 	if userRow != nil && len(*userRow) > 0 {

+ 7 - 7
src/jfw/modules/subscribepay/src/entity/dataReportStruct.go

@@ -15,15 +15,13 @@ import (
 	"util"
 )
 
-//数据报告
+// 数据报告
 type dataReportStruct struct{}
 
 var JyDataReportStruct dataReportStruct
 
 func (this *dataReportStruct) PayCallBack(param *CallBackParam) (update bool) {
-	orderdata := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
-		"out_trade_no": param.OutTradeno,
-	}, "id,order_money,order_status,create_time,user_mail,user_openid,product_type,order_code,filter,dis_word,user_id", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,order_money,order_status,create_time,user_mail,user_openid,product_type,order_code,filter,dis_word,user_id", "")
 	if orderdata != nil {
 		now := time.Now()
 		order_status := qutil.IntAll((*orderdata)["order_status"])
@@ -35,6 +33,8 @@ func (this *dataReportStruct) PayCallBack(param *CallBackParam) (update bool) {
 				"pay_money":    param.CashFee,
 				"pay_time":     payTime,
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 			if update {
 				//发送数据
@@ -71,7 +71,7 @@ func (this *dataReportStruct) PayCallBack(param *CallBackParam) (update bool) {
 	return
 }
 
-//创建订单
+// 创建订单
 func (this *dataReportStruct) NewOrder(param frpc.JyPayOrderParam) (ordercode string, err error) {
 	//插入数据库
 	now := time.Now()
@@ -108,7 +108,7 @@ func (this *dataReportStruct) NewOrder(param frpc.JyPayOrderParam) (ordercode st
 	return
 }
 
-//更新订单
+// 更新订单
 func (this *dataReportStruct) FlushOrder(param frpc.JyPayOrderChangeParam) (string, error) {
 	productSign, ok := pay.PayWayAndSign["datareport"][param.PayWay]
 	if !ok || productSign == "" {
@@ -130,7 +130,7 @@ func (this *dataReportStruct) FlushOrder(param frpc.JyPayOrderChangeParam) (stri
 	pay.CloseOrder(qutil.ObjToString((*res)["pay_way"]), qutil.ObjToString((*res)["out_trade_no"]))
 
 	//创建支付串
-	tradeno, prepayid, payParam, payErr := pay.CreateOrderPay(price, productSign, param.Ip, param.Openid, param.PayWay)
+	tradeno, prepayid, payParam, payErr := pay.CreateOrderPay(price, productSign, param.Ip, param.Openid, param.PayWay, param.OrderCode)
 	if payErr != nil {
 		return "", payErr
 	}

+ 11 - 15
src/jfw/modules/subscribepay/src/entity/dataexport.go

@@ -40,7 +40,7 @@ func init() {
 
 type dataExportStruct struct{}
 
-//VIP订单
+// VIP订单
 type VipFilter struct {
 	Area               map[string]interface{} `json:"area"`     //地区
 	Industry           []string               `json:"industry"` //
@@ -57,17 +57,11 @@ type VipFilter struct {
 
 var JyDataExportStruct dataExportStruct
 
-//数据导出支付完成回调方法
+// 数据导出支付完成回调方法
 func (d *dataExportStruct) PayCallBack(param *CallBackParam) bool {
 	now := time.Now()
 	update := false
-	query := map[string]interface{}{}
-	if param.OrderCode != "" { //线下支付
-		query["order_code"] = param.OrderCode
-	} else { //支付宝微信回调
-		query["out_trade_no"] = param.OutTradeno
-	}
-	orderdata := util.Mysql.FindOne("dataexport_order", query, "id,filter,user_mail,product_type,data_spec,user_phone,filter_id,order_code,data_count,order_status,order_money,out_trade_no,create_time,pay_way,dis_word,user_id,download_url,d_relation_id", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,user_mail,product_type,data_spec,user_phone,filter_id,order_code,data_count,order_status,order_money,out_trade_no,create_time,pay_way,dis_word,user_id,download_url,d_relation_id", "")
 	pay_time := qutil.FormatDate(&now, qutil.Date_Full_Layout)
 	if orderdata != nil {
 		order_code := qutil.ObjToString((*orderdata)["order_code"])
@@ -86,6 +80,8 @@ func (d *dataExportStruct) PayCallBack(param *CallBackParam) bool {
 				"pay_money":    param.CashFee,
 				"pay_time":     pay_time,
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			}
 			orderCode := qutil.ObjToString((*orderdata)["order_code"])
 			download_url := qutil.ObjToString((*orderdata)["download_url"])
@@ -137,7 +133,7 @@ func (d *dataExportStruct) PayCallBack(param *CallBackParam) bool {
 
 var finaceLock *sync.Mutex = &sync.Mutex{}
 
-//给北京财务人员发邮件
+// 给北京财务人员发邮件
 func SendMailToBJFinance(order *map[string]interface{}, pay_time, transaction_id string, mailType int, auth []*mail.GmailAuth) {
 	defer qutil.Catch()
 	finaceLock.Lock()
@@ -688,7 +684,7 @@ func GetPackDataExportMailContent(filterId, download_url string) (content string
 	return content, nil
 }
 
-//获取邮件内容
+// 获取邮件内容
 func GetDataExportMailContent(orderCode string) (content string, err error) {
 	orderData := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
 		"order_code": orderCode,
@@ -818,7 +814,7 @@ func GetDataExportMailContent(orderCode string) (content string, err error) {
 }
 
 /*
-   获取-筛选条件-金额
+获取-筛选条件-金额
 */
 func GetPriceDes_SieveCondition(minPrice, maxPrice string) string {
 	des := "全部"
@@ -833,7 +829,7 @@ func GetPriceDes_SieveCondition(minPrice, maxPrice string) string {
 	return des
 }
 
-//数据报告发送邮件
+// 数据报告发送邮件
 func SendDatareportMailToPayUser(report_id int, price, out_trade_no, user_mail, order_code, phone, company, create_time, pay_time string, auth []*mail.GmailAuth) {
 	res := util.Mysql.FindOne("jy_datareport", map[string]interface{}{
 		"report_id": report_id,
@@ -858,7 +854,7 @@ func SendDatareportMailToPayUser(report_id int, price, out_trade_no, user_mail,
 	}
 }
 
-//获取支付单号
+// 获取支付单号
 func getPayTransactionId(payWay, tradeNo string) (transaction_id string) {
 	if payWay == "" || tradeNo == "" {
 		return
@@ -881,7 +877,7 @@ func getPayTransactionId(payWay, tradeNo string) (transaction_id string) {
 	return
 }
 
-//升级续费逻辑升级后的 转换
+// 升级续费逻辑升级后的 转换
 func newbuysetConversion(newbuyset map[string]interface{}) (subscription_area, industry string) {
 	areacount := qutil.Int64All(newbuyset["areacount"])
 	newcityscount := len(newbuyset["newcitys"].([]interface{})) //分布

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

@@ -13,11 +13,9 @@ type entnicheStruct struct{}
 
 var EntnicheStruct entnicheStruct
 
-//数据导出支付完成回调方法
+// 数据导出支付完成回调方法
 func (e *entnicheStruct) PayCallBack(param *CallBackParam) bool {
-	orderdata := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
-		"out_trade_no": param.OutTradeno,
-	}, "id,filter,order_status,user_id,vip_type", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,order_status,user_id,vip_type", "")
 	if orderdata == nil {
 		return false
 	}
@@ -115,6 +113,8 @@ func (e *entnicheStruct) PayCallBack(param *CallBackParam) bool {
 			"pay_money":    param.CashFee,
 			"pay_time":     nowFormat,
 			"order_status": 1,
+			//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+			"out_trade_no": param.OutTradeno,
 		})
 
 		if update {
@@ -125,7 +125,7 @@ func (e *entnicheStruct) PayCallBack(param *CallBackParam) bool {
 	return true
 }
 
-//续费
+// 续费
 func RenewEnt(id, end int64, cycle int) bool {
 	end_time := time.Unix(end, 0).Format("2006-01-02 15:04:05")
 	loc, _ := time.LoadLocation("Local")

+ 5 - 9
src/jfw/modules/subscribepay/src/entity/integral.go

@@ -19,15 +19,9 @@ type integral struct{}
 
 var Integral integral
 
-//剑鱼币支付完成回调方法
+// 剑鱼币支付完成回调方法
 func (b *integral) PayCallBack(param *CallBackParam) bool {
-	query := map[string]interface{}{}
-	if param.OrderCode != "" { //线下支付
-		query["order_code"] = param.OrderCode
-	} else { //支付宝微信回调
-		query["out_trade_no"] = param.OutTradeno
-	}
-	orderdata := util.Mysql.FindOne("dataexport_order", query, "id,filter,order_code,order_status,user_id,product_type,discount_price,d_relation_id", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,order_code,order_status,user_id,product_type,discount_price,d_relation_id", "")
 	if orderdata == nil {
 		return false
 	}
@@ -77,6 +71,8 @@ func (b *integral) PayCallBack(param *CallBackParam) bool {
 				"pay_time":     nowFormat,
 				"order_status": 1,
 				"filter_id":    SerialNumber, //流水号
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 			if update {
 				//取消其他订单
@@ -96,7 +92,7 @@ func (b *integral) PayCallBack(param *CallBackParam) bool {
 	return true
 }
 
-//验证价格
+// 验证价格
 func (b *integral) GetIntegralMoney(userId string, price, score int) (int, int) {
 	original_score := score
 	if original_score < 0 {

+ 8 - 8
src/jfw/modules/subscribepay/src/entity/jyCourseOnlineStruct.go

@@ -22,13 +22,11 @@ type jyCourseOnline struct{}
 
 var JyCourseOnline jyCourseOnline
 
-//支付完成回调
+// 支付完成回调
 func (this *jyCourseOnline) PayCallBack(param *CallBackParam) bool {
 	now := time.Now()
 	update := false
-	orderdata := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
-		"out_trade_no": param.OutTradeno,
-	}, "id,order_status,order_money,order_code,filter_id,user_id,dis_word", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,order_status,order_money,order_code,filter_id,user_id,dis_word", "")
 	pay_time := qutil.FormatDate(&now, qutil.Date_Full_Layout)
 	if orderdata != nil {
 		order_status := qutil.IntAll((*orderdata)["order_status"])
@@ -39,6 +37,8 @@ func (this *jyCourseOnline) PayCallBack(param *CallBackParam) bool {
 				"pay_money":    param.CashFee,
 				"pay_time":     pay_time,
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 			courseId := qutil.ObjToString((*orderdata)["filter_id"])
 			if update && courseId != "" {
@@ -81,7 +81,7 @@ func (this *jyCourseOnline) PayCallBack(param *CallBackParam) bool {
 	return update
 }
 
-//生成订单
+// 生成订单
 func (this *jyCourseOnline) NewOrder(param frpc.JyPayOrderParam) (ordercode string, err error) {
 	productSign, ok := pay.PayWayAndSign["onlineCourse"][param.PayWay]
 	// 获取分销口令
@@ -134,7 +134,7 @@ func (this *jyCourseOnline) NewOrder(param frpc.JyPayOrderParam) (ordercode stri
 		}
 	}
 	//创建支付串
-	tradeno, prepayid, payParam, payErr := pay.CreateOrderPay(totalfee, productSign, param.Ip, param.Openid, param.PayWay)
+	tradeno, prepayid, payParam, payErr := pay.CreateOrderPay(totalfee, productSign, param.Ip, param.Openid, param.PayWay, ordercode)
 	if payErr != nil {
 		err = payErr
 		return
@@ -183,7 +183,7 @@ func (this *jyCourseOnline) NewOrder(param frpc.JyPayOrderParam) (ordercode stri
 	return
 }
 
-//更新订单
+// 更新订单
 func (this *jyCourseOnline) FlushOrder(param frpc.JyPayOrderChangeParam) (string, error) {
 	productSign, ok := pay.PayWayAndSign["onlineCourse"][param.PayWay]
 	if !ok || productSign == "" {
@@ -199,7 +199,7 @@ func (this *jyCourseOnline) FlushOrder(param frpc.JyPayOrderChangeParam) (string
 		return "", errors.New("查询金额异常" + param.OrderCode)
 	}
 	//创建支付串
-	tradeno, prepayid, payParam, payErr := pay.CreateOrderPay(price, productSign, param.Ip, param.Openid, param.PayWay)
+	tradeno, prepayid, payParam, payErr := pay.CreateOrderPay(price, productSign, param.Ip, param.Openid, param.PayWay, param.OrderCode)
 	if payErr != nil {
 		return "", payErr
 	}

+ 6 - 6
src/jfw/modules/subscribepay/src/entity/jyCourseStruct.go

@@ -65,7 +65,7 @@ func init() {
 	}
 }
 
-//给运营人员发送邮件通知   0:支付成功 1:对公转账凭证提交  2:申请退款
+// 给运营人员发送邮件通知   0:支付成功 1:对公转账凭证提交  2:申请退款
 func SendMailToOperation(ic int, orderCode, productType string, auth []*mail.GmailAuth) {
 	var mail_title = "剑鱼标讯-" + productType
 	var subject = "支付成功"
@@ -87,13 +87,11 @@ func SendMailToOperation(ic int, orderCode, productType string, auth []*mail.Gma
 	}
 }
 
-//支付完成回调
+// 支付完成回调
 func (this *jyCourse) PayCallBack(param *CallBackParam) bool {
 	now := time.Now()
 	update := false
-	orderdata := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
-		"out_trade_no": param.OutTradeno,
-	}, "id,order_status,order_money,order_code", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,order_status,order_money,order_code", "")
 	pay_time := qutil.FormatDate(&now, qutil.Date_Full_Layout)
 	if orderdata != nil {
 		order_status := qutil.IntAll((*orderdata)["order_status"])
@@ -105,6 +103,8 @@ func (this *jyCourse) PayCallBack(param *CallBackParam) bool {
 				"pay_money":    param.CashFee,
 				"pay_time":     pay_time,
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 		} else {
 			update = true
@@ -117,7 +117,7 @@ func (this *jyCourse) PayCallBack(param *CallBackParam) bool {
 	return update
 }
 
-//根据课程id和团购人数获取课程信息和总价
+// 根据课程id和团购人数获取课程信息和总价
 func (this *jyCourse) GetCourseMsgAndPrice(courseId string, orderNum int) (rData *map[string]interface{}, price int) {
 	rData, _ = util.MQFW.FindById("jy_course", courseId, `"i_type":1,"s_address":1,"i_status":1,"s_name":1,"i_price":1,"l_starttime":1,"l_endtime":1,"s_content":1`)
 	if rData == nil || len(*rData) == 0 {

+ 4 - 9
src/jfw/modules/subscribepay/src/entity/member.go

@@ -43,15 +43,9 @@ func init() {
 	log.Println("初始化大会员权益已结束")
 }
 
-//大会员支付完成回调方法
+// 大会员支付完成回调方法
 func (m *memberStruct) PayCallBack(param *CallBackParam) bool {
-	query := map[string]interface{}{}
-	if param.OrderCode != "" { //线下支付
-		query["order_code"] = param.OrderCode
-	} else { //支付宝微信回调
-		query["out_trade_no"] = param.OutTradeno
-	}
-	orderdata := util.Mysql.FindOne("dataexport_order", query, "id,filter,order_code,order_status,user_id,vip_type,prepay_time", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,order_code,order_status,user_id,vip_type,prepay_time", "")
 	if orderdata == nil {
 		return false
 	}
@@ -81,6 +75,8 @@ func (m *memberStruct) PayCallBack(param *CallBackParam) bool {
 				"order_status":  1,
 				"vip_starttime": nowFormat,
 				"vip_endtime":   qutil.FormatDate(&enddate, qutil.Date_Full_Layout),
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			})
 			if update {
 				util.MsgRemind.BigMemberPaySuccess(qutil.IntAll((*orderdata)["id"]), qutil.ObjToString((*orderdata)["order_code"]), qutil.ObjToString((*orderdata)["user_id"]), qutil.ObjToString((*orderdata)["prepay_time"]), qutil.IntAllDef((*orderdata)["vip_type"], -1))
@@ -92,7 +88,6 @@ func (m *memberStruct) PayCallBack(param *CallBackParam) bool {
 	return true
 }
 
-//
 func normal_member(level int, enddate time.Time, userId string) {
 	//修改用户表权限
 	set := map[string]interface{}{

+ 141 - 128
src/jfw/modules/subscribepay/src/entity/order.go

@@ -73,6 +73,16 @@ type OrderInfo struct {
 	PayWay            string `json:"pay_way,omitempty"`
 	PrepayId          string `json:"prepay_id",omitempty`
 	CodeUrl           string `json:"code_url,omitempty"`
+	ExpirationTime    string `json:"expiration_time,omitempty"` //倒计时时间,目前只有活动订单使用
+}
+
+// RequestCheck 创建订单校验
+func (this *commonOrderStruct) RequestCheck(product string, m map[string]interface{}, sess *httpsession.Session) (errMsg string) {
+	switch product {
+	case "历史数据":
+		errMsg = dataExportCheck(m, sess)
+	}
+	return
 }
 
 /*
@@ -85,12 +95,12 @@ type OrderInfo struct {
 		insertMap:创建订单的参数
 		msg:错误信息
 */
-func (this *commonOrderStruct) InserMap(product, productId, userid, lotteryId, discountId string, m map[string]interface{}, sess *httpsession.Session) (orderinfo *OrderInfo, msg string) {
+func (this *commonOrderStruct) InserMap(product, productId, userid, lotteryId, discountId string, m map[string]interface{}) (orderinfo *OrderInfo, msg string) {
 	switch product {
 	case "历史数据":
-		orderinfo, msg = dataExportOrder(m, sess)
+		orderinfo, msg = dataExportOrder(m, userid)
 	case "VIP订阅":
-		orderinfo, msg = vipOrder(m, userid, sess)
+		orderinfo, msg = vipOrder(m, userid)
 	case "企业商机管理":
 		orderinfo, msg = entnicheOrder(m, userid)
 	case "大会员":
@@ -98,17 +108,17 @@ func (this *commonOrderStruct) InserMap(product, productId, userid, lotteryId, d
 	case "剑鱼币":
 		orderinfo, msg = integralOrder(m, userid)
 	case "数据流量包":
-		orderinfo, msg = dataexportPackOrder(m, userid, sess)
+		orderinfo, msg = dataexportPackOrder(m, userid)
 	case "省份订阅包":
-		orderinfo, msg = areaPackOrder(m, userid, sess)
+		orderinfo, msg = areaPackOrder(m, userid)
 	case "附件下载包":
-		orderinfo, msg = filePackOrder(m, userid, sess)
+		orderinfo, msg = filePackOrder(m, userid)
 	case "采购单位画像包":
-		orderinfo, msg = buyerPortraitPackOrder(m, userid, sess)
+		orderinfo, msg = buyerPortraitPackOrder(m, userid)
 	case "数据报告":
-		orderinfo, msg = newDataReportOrder(m, userid, sess)
+		orderinfo, msg = newDataReportOrder(m, userid)
 	case "中标必听课":
-		orderinfo, msg = courseOnlineOrder(m, userid, sess)
+		orderinfo, msg = courseOnlineOrder(m, userid)
 	default:
 		orderinfo, msg = nil, "产品类型有误"
 	}
@@ -126,11 +136,7 @@ func (this *commonOrderStruct) InserMap(product, productId, userid, lotteryId, d
 				orderinfo.DiscountPrice = reduce_price
 				orderinfo.OrderMoney = orderinfo.OrderMoney - reduce_price
 			} else {
-				disCount_int := int(math.Ceil(discount * 1000))                               //折扣
-				DiscountPrice := (float64)(orderinfo.OrderMoney*(10000-disCount_int)) / 10000 //优惠金额
-				DiscountPrice_float, _ := decimal.NewFromFloat(DiscountPrice / 100).Round(2).Float64()
-				orderinfo.DiscountPrice = int(decimal.NewFromFloat(DiscountPrice_float * 100).Round(2).IntPart()) //算出价格
-				orderinfo.OrderMoney = orderinfo.OrderMoney - int(orderinfo.DiscountPrice)                        //优惠后价格
+				orderinfo.OrderMoney, orderinfo.DiscountPrice = discountPrice(discount, orderinfo.OrderMoney)
 			}
 			orderinfo.DrelationId = userLotteryId
 		}
@@ -146,50 +152,109 @@ func (this *commonOrderStruct) InserMap(product, productId, userid, lotteryId, d
 	if product == "数据流量包" {
 		giveArr := GiveInfo(userid, i_product, 0, 0) //获取满赠时长
 		if giveArr != nil && len(giveArr) > 0 {
-			filterM["give_cycle"] = qu.IntAll(giveArr[0]["Time"])
-			filterM["give_type"] = qu.IntAll(giveArr[0]["DiscountId"])
-			discountId = strconv.Itoa(qu.IntAll(giveArr[0]["DiscountId"]))
-			if strings.Contains(qu.ObjToString(giveArr[0]["ActivityName"]), config.Config.ActivityName) {
-				filterM["badge"] = "202111" //双十一角标展示
+			isReceive, _ := giveArr[0]["IsReceive"].(bool)     //是否可用
+			stockNum := qu.Int64All(giveArr[0]["StockNumber"]) //库存数
+			begintime, endtime := qu.Int64All(giveArr[0]["BeginDate"]), qu.Int64All(giveArr[0]["EndDate"])
+			now := time.Now().Unix()
+			if isReceive && stockNum > 0 && (now >= begintime && now < endtime) {
+				filterM["give_cycle"] = qu.IntAll(giveArr[0]["Time"])
+				filterM["give_type"] = qu.IntAll(giveArr[0]["DiscountId"])
+				discountId = strconv.Itoa(qu.IntAll(giveArr[0]["DiscountId"]))
+				if strings.Contains(qu.ObjToString(giveArr[0]["ActivityName"]), config.Config.ActivityName) {
+					filterM["badge"] = "202111" //双十一角标展示
+				}
+				filterByte, _ := json.Marshal(filterM)
+				orderinfo.Filter = string(filterByte)
 			}
-			filterByte, _ := json.Marshal(filterM)
-			orderinfo.Filter = string(filterByte)
 		}
 	}
 	//赠品相关
 	if i_discountId > 0 {
-		if timeNum, timeType, _ := util.GiveInfo(userid, i_product, 0, i_discountId); timeNum > 0 {
-			filterM["give_cycle"] = timeNum
-			filterM["give_type"] = timeType
-			filterByte, _ := json.Marshal(filterM)
-			orderinfo.Filter = string(filterByte)
-			if orderinfo.VipEndTime != "" {
-				endTime, _ := time.ParseInLocation(qu.Date_Full_Layout, orderinfo.VipEndTime, time.Local)
-				if timeType == 1 {
-					endTime = endTime.AddDate(0, 0, timeNum)
-				} else if timeType == 2 {
-					endTime = endTime.AddDate(0, timeNum, 0)
+		activityType, timeNum, timeType, promotionalPrice, reduce, discount, _, isUsed := util.GiveInfo(userid, i_product, 0, i_discountId)
+		//活动类型:0满减、1折扣券、2满赠、3促销、4限时折扣、5限时减免
+		log.Println(activityType, timeNum, timeType, promotionalPrice, reduce, discount, isUsed)
+		if isUsed {
+			switch activityType {
+			case 2:
+				filterM["give_cycle"] = timeNum
+				filterM["give_type"] = timeType
+				filterByte, _ := json.Marshal(filterM)
+				orderinfo.Filter = string(filterByte)
+				if orderinfo.VipEndTime != "" {
+					endTime, _ := time.ParseInLocation(qu.Date_Full_Layout, orderinfo.VipEndTime, time.Local)
+					if timeType == 1 {
+						endTime = endTime.AddDate(0, 0, timeNum)
+					} else if timeType == 2 {
+						endTime = endTime.AddDate(0, timeNum, 0)
+					}
+					orderinfo.VipEndTime = endTime.Format(qu.Date_Full_Layout)
 				}
-				orderinfo.VipEndTime = endTime.Format(qu.Date_Full_Layout)
+			case 3:
+				if promotionalPrice > 0 {
+					orderinfo.OrderMoney = promotionalPrice
+					orderinfo.DiscountPrice = orderinfo.OriginalPrice - promotionalPrice
+				}
+			case 4:
+				if discount != 0 {
+					orderinfo.OrderMoney, orderinfo.DiscountPrice = discountPrice(discount, orderinfo.OrderMoney)
+				}
+			case 5:
+				if reduce > 0 {
+					orderinfo.OrderMoney = orderinfo.OriginalPrice - reduce
+					orderinfo.DiscountPrice = reduce
+				}
+			}
+			//只有限时活动才有倒计时字段
+			if activityType == 3 || activityType == 4 || activityType == 5 {
+				orderinfo.ExpirationTime = time.Now().Add(time.Duration(config.Config.ActivityOrderCountdown) * time.Minute).Format(qu.Date_Full_Layout)
+
 			}
 		}
-	} //获取满赠
+	}
+	//获取满赠
 	//绑定卡券
 	if (userLotteryId != "" && lotteryId != "") || (discountId != "" && discountId != "0") {
-		go func() {
-			phone, nickname := util.GetMyPhoneAndName(userid)
-			if !util.UpdateCouponState(userid, userLotteryId, nickname, phone, orderinfo.OrderCode, product, discountId, 3, 0) {
-				log.Println(fmt.Sprintf("单号%s-绑定失败-卡卷%s", orderinfo.OrderCode, userLotteryId))
-			}
-		}()
+		phone, nickname := util.GetMyPhoneAndName(userid)
+		if !util.UpdateCouponState(userid, userLotteryId, nickname, phone, orderinfo.OrderCode, product, discountId, 3, 0) {
+			log.Println(fmt.Sprintf("单号%s-绑定失败-卡卷%s", orderinfo.OrderCode, userLotteryId))
+		}
+
 	}
 	return
 }
 
+func dataExportCheck(m map[string]interface{}, sess *httpsession.Session) string {
+	user_phone, user_mail, user_mail_status := JyCommonOrderStruct.DataExportPhoneAndMailCheck(sess)
+	if user_mail == "" || user_phone == "" || !user_mail_status {
+		log.Println("身份参数异常! user_mail,user_phone, user_mail_status", user_mail, user_phone, user_mail_status)
+		return "参数不合法"
+	}
+
+	if user_mail != qu.ObjToString(m["order_email"]) {
+		return "邮箱验证未通过"
+	}
+
+	sess.Set("DataExportVerifyPhone_val", user_phone)
+	nickname, _ := sess.Get("s_nickname").(string)
+	user_mail, _ = sess.Get("DataExportVerifyEmail_val").(string)
+	//保存结构化数据信息 记录
+	go func() {
+		if sess.Get("Structed") != nil && sess.Get("Structed").(bool) {
+			user_phone, _ := sess.Get("DataExportVerifyPhone").(string)
+			if user_phone == "" {
+				user_phone, _ = sess.Get("DataExportVerifyPhone_val").(string)
+			}
+			util.StructedDataByExportData(nickname, user_mail, user_phone)
+			//清除存储标识
+			sess.Del("Structed")
+		}
+	}()
+	return ""
+}
+
 //历史数据
-func dataExportOrder(m map[string]interface{}, sess *httpsession.Session) (*OrderInfo, string) {
+func dataExportOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	id := qu.SE.Decode4Hex(qu.ObjToString(m["id"]))
-	userId := qu.ObjToString(sess.Get("userId"))
 	if id == "" {
 		return nil, "id错误"
 	}
@@ -208,7 +273,7 @@ func dataExportOrder(m map[string]interface{}, sess *httpsession.Session) (*Orde
 		log.Println("未查询到检索信息", id, userId)
 		return nil, "未查询到检索信息"
 	}
-	user_phone, user_mail, user_mail_status := JyCommonOrderStruct.DataExportPhoneAndMailCheck(sess)
+
 	order_money_, original_price_ := float64(0), float64(0)
 	if data_spec == "标准字段包" {
 		original_price_ = float64(data_count) * config.ExConf.UnitPrice_normal
@@ -227,8 +292,8 @@ func dataExportOrder(m map[string]interface{}, sess *httpsession.Session) (*Orde
 
 	filter_keys, filter_publishtime, filter, disWord := "", "", "", ""
 
-	if user_mail == "" || user_phone == "" || !user_mail_status || data_spec == "" || order_money <= 0 || data_count <= 0 || original_price <= 0 {
-		log.Println("参数不合法! user_mail,user_phone, user_mail_status, data_spec, order_money, data_count, original_price", user_mail, user_phone, user_mail_status, data_spec, order_money, data_count, original_price)
+	if data_spec == "" || order_money <= 0 || data_count <= 0 || original_price <= 0 {
+		log.Println("参数不合法! data_spec, order_money, data_count, original_price", data_spec, order_money, data_count, original_price)
 		return nil, "参数不合法"
 	}
 	userfilter, ok := util.MQFW.FindById("export_search", id, nil)
@@ -249,7 +314,6 @@ func dataExportOrder(m map[string]interface{}, sess *httpsession.Session) (*Orde
 		delete(*userfilter, "selectIds")
 		filterByte, _ := json.Marshal(userfilter)
 		filter = string(filterByte)
-
 	} else {
 		log.Println("id is not find in mongodb", id)
 		return nil, "查询失败"
@@ -271,37 +335,19 @@ func dataExportOrder(m map[string]interface{}, sess *httpsession.Session) (*Orde
 	}()
 	now := time.Now()
 
-	sess.Set("DataExportVerifyPhone_val", user_phone)
-	nickname, _ := sess.Get("s_nickname").(string)
-	user_mail, _ = sess.Get("DataExportVerifyEmail_val").(string)
-	openId, _ := sess.Get("s_m_openid").(string)
-	//保存结构化数据信息 记录
-	go func() {
-		if sess.Get("Structed") != nil && sess.Get("Structed").(bool) {
-			user_phone, _ := sess.Get("DataExportVerifyPhone").(string)
-			if user_phone == "" {
-				user_phone, _ = sess.Get("DataExportVerifyPhone_val").(string)
-			}
-			util.StructedDataByExportData(nickname, user_mail, user_phone)
-			//清除存储标识
-			sess.Del("Structed")
-		}
-	}()
 	return &OrderInfo{
 		UserId:            userId,
 		OrderCode:         ordercode,
+		UserPhone:         qu.ObjToString(m["order_phone"]),
+		UserMail:          qu.ObjToString(m["order_email"]),
 		ProductType:       "历史数据",
 		OrderMoney:        order_money,
 		OrderStatus:       0,
 		ServiceStatus:     0,
-		UserNickname:      nickname,
-		UserOpenid:        openId,
 		Filter:            filter,
 		CreateTime:        qu.FormatDate(&now, qu.Date_Full_Layout),
 		OriginalPrice:     original_price,
 		DataSpec:          data_spec,
-		UserMail:          user_mail,
-		UserPhone:         user_phone,
 		DataCount:         data_count,
 		FilterPublishtime: filter_publishtime,
 		FilterKeys:        filter_keys,
@@ -460,23 +506,21 @@ func DecodeEntId(encodeId string) int {
 }
 
 //超级订阅
-func vipOrder(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
+func vipOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	types := qu.ObjToString(m["type"])
 	switch types {
 	case "firstBuy": //首次购买
-		return vipFirstBuy(m, userId, sess)
+		return vipFirstBuy(m, userId)
 	case "renew": //续费
-		return vipRenew(m, userId, sess)
+		return vipRenew(m, userId)
 	case "upgrade": //升级
-		return vipUpgrade(m, userId, sess)
-
+		return vipUpgrade(m, userId)
 	}
 	return nil, "未知类型"
 }
 
 //超级订阅首次购买
-func vipFirstBuy(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
-	openId, _ := sess.Get("s_m_openid").(string)
+func vipFirstBuy(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	area := qu.ObjToMap(m["area"])         //地区
 	date := qu.ObjToString(m["time"])      // 时间
 	orderType := qu.IntAll(m["orderType"]) //1 简单付费,5 升降级续费
@@ -558,7 +602,7 @@ func vipFirstBuy(m map[string]interface{}, userId string, sess *httpsession.Sess
 		filter.OldBuyset = oldBuyset
 	}
 	//插入订单表
-	mgo_id := JyVipSubStruct.SaveSelectLog(userId, openId, &filter)
+	mgo_id := JyVipSubStruct.SaveSelectLog(userId, "", &filter)
 	if mgo_id == "" {
 		return nil, "创建订单出错"
 	}
@@ -580,8 +624,6 @@ func vipFirstBuy(m map[string]interface{}, userId string, sess *httpsession.Sess
 	return &OrderInfo{
 		OrderMoney:    totalfee,
 		OrderStatus:   0,
-		UserNickname:  qu.ObjToString(sess.Get("s_nickname")),
-		UserOpenid:    openId,
 		OrderCode:     ordercode,
 		ProductType:   "VIP订阅",
 		CreateTime:    qu.FormatDate(&now, qu.Date_Full_Layout),
@@ -595,9 +637,8 @@ func vipFirstBuy(m map[string]interface{}, userId string, sess *httpsession.Sess
 }
 
 //超级订阅续费
-func vipRenew(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
+func vipRenew(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	disWord := qu.ObjToString(m["disWord"])
-	openId, _ := sess.Get("s_m_openid").(string)
 	req_price := qu.IntAll(m["price"])
 	if disWord != "" {
 		if len(strings.Split(disWord, "_")) > 1 {
@@ -658,7 +699,7 @@ func vipRenew(m map[string]interface{}, userId string, sess *httpsession.Session
 		OrderType:  2,
 		DisWord:    disWord,
 	}
-	mgo_id := JyVipSubStruct.SaveSelectLog(userId, openId, &filter)
+	mgo_id := JyVipSubStruct.SaveSelectLog(userId, "", &filter)
 	if mgo_id == "" {
 		return nil, "创建订单出错"
 	}
@@ -674,8 +715,6 @@ func vipRenew(m map[string]interface{}, userId string, sess *httpsession.Session
 	return &OrderInfo{
 		OrderMoney:    totalfee,
 		OrderStatus:   0,
-		UserNickname:  qu.ObjToString(m["s_nickname"]),
-		UserOpenid:    openId,
 		OrderCode:     ordercode,
 		ProductType:   "VIP订阅",
 		CreateTime:    qu.FormatDate(&now, qu.Date_Full_Layout),
@@ -692,12 +731,11 @@ func vipRenew(m map[string]interface{}, userId string, sess *httpsession.Session
 }
 
 //超级订阅升级
-func vipUpgrade(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
-	area_count := qu.IntAll(m["area_count"]) //地区
-	area := qu.ObjToMap(m["area"])           //地区
-	timeRenew := qu.ObjToString(m["time"])   //周期
-	req_price := qu.IntAll(m["price"])       //前端展示金额
-	openId := qu.ObjToString(sess.Get("s_m_openid"))
+func vipUpgrade(m map[string]interface{}, userId string) (*OrderInfo, string) {
+	area_count := qu.IntAll(m["area_count"])        //地区
+	area := qu.ObjToMap(m["area"])                  //地区
+	timeRenew := qu.ObjToString(m["time"])          //周期
+	req_price := qu.IntAll(m["price"])              //前端展示金额
 	order_phone := qu.ObjToString(m["order_phone"]) //p19.3用户信息采集 手机号
 	if order_phone != "" && !jy.PhoneReg.MatchString(order_phone) {
 		return nil, "手机号格式异常"
@@ -818,7 +856,6 @@ func vipUpgrade(m map[string]interface{}, userId string, sess *httpsession.Sessi
 	orderinfo := &OrderInfo{
 		OrderMoney:    final_price,
 		OrderStatus:   order_status,
-		UserOpenid:    openId,
 		OrderCode:     ordercode,
 		ProductType:   "VIP订阅",
 		CreateTime:    qu.FormatDate(&now, qu.Date_Full_Layout),
@@ -929,7 +966,7 @@ func integralOrder(m map[string]interface{}, userId string) (*OrderInfo, string)
 }
 
 //数据流量包
-func dataexportPackOrder(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
+func dataexportPackOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	packId := qu.ObjToString(m["packId"])
 	// 获取用户分销口令
 	disWordStr := ""
@@ -959,14 +996,10 @@ func dataexportPackOrder(m map[string]interface{}, userId string, sess *httpsess
 	if err != nil {
 		return nil, "数据异常"
 	}
-	nickname := qu.ObjToString(sess.Get("s_nickname"))
-	openId := qu.ObjToString(sess.Get("s_m_openid"))
 	return &OrderInfo{
 		OrderMoney:    orderMoney,
 		OrderStatus:   0,
 		ServiceStatus: 0,
-		UserNickname:  nickname,
-		UserOpenid:    openId,
 		UserPhone:     qu.ObjToString(m["order_phone"]),
 		OrderCode:     orderCode,
 		ProductType:   "数据流量包",
@@ -979,7 +1012,7 @@ func dataexportPackOrder(m map[string]interface{}, userId string, sess *httpsess
 }
 
 //省份订阅包
-func areaPackOrder(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
+func areaPackOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	orderType := qu.IntAll(m["orderType"])
 	area := qu.ObjToMap(m["area"])
 	unit := qu.IntAll(m["unit"]) //1月 2季 3年
@@ -1007,14 +1040,11 @@ func areaPackOrder(m map[string]interface{}, userId string, sess *httpsession.Se
 	if totalfee <= 0 {
 		return nil, "订单金额异常"
 	}
-	nickname := qu.ObjToString(sess.Get("s_nickname"))
-	openId := qu.ObjToString(sess.Get("s_m_openid"))
+
 	orderinfo := &OrderInfo{
 		OrderMoney:    totalfee,
 		OrderStatus:   0,
 		ServiceStatus: 0,
-		UserOpenid:    openId,
-		UserNickname:  nickname,
 		UserPhone:     qu.ObjToString(m["order_phone"]),
 		OrderCode:     orderCode,
 		ProductType:   "省份订阅包",
@@ -1073,9 +1103,7 @@ func areaPackOrder(m map[string]interface{}, userId string, sess *httpsession.Se
 }
 
 //附件下载包
-func filePackOrder(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
-	openId := qu.ObjToString(sess.Get("s_m_openid"))
-	nickname := qu.ObjToString(sess.Get("s_nickname"))
+func filePackOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	if jy.GetBigVipUserBaseMsg(userId, util.Mysql, util.MQFW).VipStatus <= 0 {
 		return nil, "非超级订阅用户,暂无权益"
 	}
@@ -1108,8 +1136,6 @@ func filePackOrder(m map[string]interface{}, userId string, sess *httpsession.Se
 		OrderMoney:    price,
 		OrderStatus:   0,
 		ServiceStatus: 0,
-		UserNickname:  nickname,
-		UserOpenid:    openId,
 		UserPhone:     order_phone,
 		OrderCode:     orderCode,
 		ProductType:   "附件下载包",
@@ -1151,10 +1177,8 @@ func GiveInfo(userid string, useProduct, useProductType, discountId int) []map[s
 }
 
 //采购单位画像包 -超级订阅升级版用户可以购买使用
-func buyerPortraitPackOrder(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
+func buyerPortraitPackOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	uData := jy.GetBigVipUserBaseMsg(userId, util.Mysql, util.MQFW)
-	openId := qu.ObjToString(sess.Get("s_m_openid"))
-	nickname := qu.ObjToString(sess.Get("s_nickname"))
 	if uData.VipStatus <= 0 || uData.Vip_BuySet.Upgrade <= 0 {
 		return nil, "非新版超级订阅用户,暂无权益"
 	}
@@ -1188,8 +1212,6 @@ func buyerPortraitPackOrder(m map[string]interface{}, userId string, sess *https
 		OrderMoney:    price,
 		OrderStatus:   0,
 		ServiceStatus: 0,
-		UserNickname:  nickname,
-		UserOpenid:    openId,
 		UserPhone:     order_phone,
 		OrderCode:     orderCode,
 		ProductType:   "采购单位画像包",
@@ -1201,7 +1223,7 @@ func buyerPortraitPackOrder(m map[string]interface{}, userId string, sess *https
 }
 
 //数据报告
-func newDataReportOrder(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
+func newDataReportOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	reportId := qu.IntAll(m["reportId"]) //报告id
 	email := qu.ObjToString(m["email"])
 	phone := qu.ObjToString(m["order_phone"])
@@ -1225,8 +1247,6 @@ func newDataReportOrder(m map[string]interface{}, userId string, sess *httpsessi
 			disWord = fmt.Sprint((*infoList)[0]["password"])
 		}
 	}
-	openid := qu.ObjToString(sess.Get("s_m_openid"))
-	nickname := qu.ObjToString(sess.Get("s_nickname"))
 	startTime := qu.Int64All((*r)["start_time"])
 	//生成订单号
 	orderCode := pay.GetOrderCode(userId)
@@ -1249,8 +1269,6 @@ func newDataReportOrder(m map[string]interface{}, userId string, sess *httpsessi
 		OrderMoney:    qu.IntAll((*r)["i_price"]),
 		OrderStatus:   0,
 		ServiceStatus: 0,
-		UserNickname:  nickname,
-		UserOpenid:    openid,
 		UserPhone:     phone,
 		OrderCode:     orderCode,
 		ProductType:   "数据报告",
@@ -1265,10 +1283,9 @@ func newDataReportOrder(m map[string]interface{}, userId string, sess *httpsessi
 }
 
 //中标必听课
-func courseOnlineOrder(m map[string]interface{}, userId string, sess *httpsession.Session) (*OrderInfo, string) {
+func courseOnlineOrder(m map[string]interface{}, userId string) (*OrderInfo, string) {
 	pay_way := "wx_app"
 	_id := qu.ObjToString(m["id"])
-	ip := qu.ObjToString(m["Ip"])
 	order_phone := qu.ObjToString(m["order_phone"])
 	data, _ := util.MQFW.FindById("jy_course", _id, false)
 	productSign, ok := pay.PayWayAndSign["onlineCourse"][pay_way]
@@ -1291,16 +1308,8 @@ func courseOnlineOrder(m map[string]interface{}, userId string, sess *httpsessio
 	if !ok {
 		return nil, "查询失败"
 	}
-	openid := qu.ObjToString(sess.Get("s_m_openid"))
-	nickname := qu.ObjToString(sess.Get("s_nickname"))
 	//生成订单号
 	orderCode := pay.GetOrderCode(userId)
-	log.Println(price, productSign, ip, openid, pay_way)
-	tradeno, prepayid, payParam, payErr := pay.CreateOrderPay(price, productSign, ip, openid, pay_way)
-	if payErr != nil {
-		log.Println("er:payErr", payErr)
-		return nil, "预支付失败"
-	}
 	now := time.Now()
 	detail := map[string]interface{}{
 		"_id":          _id,
@@ -1321,8 +1330,6 @@ func courseOnlineOrder(m map[string]interface{}, userId string, sess *httpsessio
 		OrderMoney:    price,
 		OrderStatus:   0,
 		ServiceStatus: 0,
-		UserNickname:  nickname,
-		UserOpenid:    openid,
 		UserPhone:     order_phone,
 		OrderCode:     orderCode,
 		ProductType:   "中标必听课",
@@ -1331,11 +1338,17 @@ func courseOnlineOrder(m map[string]interface{}, userId string, sess *httpsessio
 		Filter:        string(filterStr),
 		UserId:        userId,
 		DisWord:       disWord,
-		OutTradeNo:    tradeno,
 		PayWay:        pay_way,
-		PrepayId:      prepayid,
-		CodeUrl:       payParam,
 		PrepayTime:    qu.FormatDate(&now, qu.Date_Full_Layout),
 		FilterId:      _id,
 	}, ""
 }
+
+func discountPrice(discount float64, money int) (orderMoney, discountPrice int) {
+	disCount_int := int(math.Ceil(discount * 1000))                //折扣
+	DiscountPrice := (float64)(money*(10000-disCount_int)) / 10000 //优惠金额
+	DiscountPrice_float, _ := decimal.NewFromFloat(DiscountPrice / 100).Round(2).Float64()
+	discountPrice = int(decimal.NewFromFloat(DiscountPrice_float * 100).Round(2).IntPart()) //算出价格
+	orderMoney = money - discountPrice
+	return orderMoney, discountPrice
+}

+ 17 - 0
src/jfw/modules/subscribepay/src/entity/payCalbackStrust.go

@@ -16,6 +16,23 @@ type CallBackParam struct {
 	OrderCode     string //线下支付使用
 }
 
+func (param *CallBackParam) GetPaySuccessOrderQuery(q ...map[string]interface{}) map[string]interface{} {
+	query := map[string]interface{}{}
+
+	for _, m := range q {
+		for k, v := range m {
+			query[k] = v
+		}
+	}
+
+	if param.OrderCode != "" { //线下支付或根据缓存orderCode定位支付订单
+		query["order_code"] = param.OrderCode
+	} else { //支付宝微信回调
+		query["out_trade_no"] = param.OutTradeno
+	}
+	return query
+}
+
 func (param *CallBackParam) SaveWxPayRecord() (insert bool) {
 	pay_count := util.Mysql.Count("weixin_pay", map[string]interface{}{
 		"transaction_id": param.TransactionId,

+ 7 - 7
src/jfw/modules/subscribepay/src/entity/resourcePackStruct.go

@@ -21,7 +21,7 @@ const (
 	BUYERPORTRAIT = "采购单位画像包"
 )
 
-//资源包
+// 资源包
 type resoucePackStruct struct {
 }
 
@@ -29,10 +29,8 @@ var JyresoucePack resoucePackStruct
 
 // PayCallBack 支付完成回调
 func (this *resoucePackStruct) PayCallBack(param *CallBackParam) bool {
-	orderData := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
-		"out_trade_no": param.OutTradeno,
-		//"product_type": ATTACHMENT,
-	}, "id,order_status,order_code,filter,user_id,d_relation_id,dis_word,order_money,vip_starttime,vip_endtime,product_type", "")
+	orderData := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(),
+		"id,order_status,order_code,filter,user_id,d_relation_id,dis_word,order_money,vip_starttime,vip_endtime,product_type", "")
 	if orderData != nil {
 		userId := qu.ObjToString((*orderData)["user_id"])
 		productType := qu.ObjToString((*orderData)["product_type"])
@@ -56,6 +54,8 @@ func (this *resoucePackStruct) PayCallBack(param *CallBackParam) bool {
 				"pay_money":    param.CashFee,
 				"pay_time":     qu.FormatDate(&now, qu.Date_Full_Layout),
 				"order_status": 1,
+				//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+				"out_trade_no": param.OutTradeno,
 			}); !update {
 				log.Printf("用户%s已购买%s订单状态出错:%v", userId, productType, (*orderData)["order_code"])
 				return false
@@ -203,7 +203,7 @@ func (this *resoucePackStruct) Filter(product, userid, lotteryId, discountId str
 	i_discountId, _ := strconv.Atoi(discountId)
 	//赠品相关
 	if i_discountId > 0 {
-		if timeNum, timeType, _ := util.GiveInfo(userid, i_product, i_discountId, 0); timeNum > 0 {
+		if _, timeNum, timeType, _, _, _, _, _ := util.GiveInfo(userid, i_product, i_discountId, 0); timeNum > 0 {
 			filter["giveCycle"] = timeNum
 			filter["giveType"] = timeType
 		}
@@ -212,7 +212,7 @@ func (this *resoucePackStruct) Filter(product, userid, lotteryId, discountId str
 	return rs, msg
 }
 
-//获取当月最后一天
+// 获取当月最后一天
 func (this *resoucePackStruct) LastDate(now time.Time) time.Time {
 	now = now.AddDate(0, 0, -now.Day()+1)
 	return time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location()).AddDate(0, 1, -1)

+ 62 - 53
src/jfw/modules/subscribepay/src/entity/subscribeVip.go

@@ -28,7 +28,7 @@ func init() {
 	qutil.ReadConfig("./subvip_price.json", &SubVipPrice)
 }
 
-//价格表
+// 价格表
 type subVipPrice struct {
 	Old struct {
 		Month struct {
@@ -75,26 +75,28 @@ type subVipPrice struct {
 	Discount float64 `json:"discount"` //折扣(测试使用)
 }
 
-//订单简单信息
+// 订单简单信息
 type VipSimpleMsg struct {
-	Area             *map[string]interface{}  `json:"area"`                     //选择地区
-	Industry         []string                 `json:"industry"`                 //选择行业
-	Cyclecount       int                      `json:"cyclecount"`               //日期数量(订单详情展示使用)
-	Cycleunit        int                      `json:"cycleunit"`                //日期单位(订单详情展示使用)
-	OldBuyset        *SubvipBuySet            `json:"buyset"`                   //旧购买详情
-	NewBuyset        *SubvipBuySet            `json:"newBuyset"`                //新购买详情
-	UpgradeSubtotail []map[string]interface{} `json:"upgradeSubtotail"`         //升级清单(订单详情计价清单展示使用)
-	OrderType        int                      `json:"ordertype"`                //1,3,5   类型 1:订单 2:续费 3:立即升级 4:下月升级 5:即将到期(可升降级续费)6:升级订单未生效再次升级
-	DisWord          string                   `json:"disWord"`                  //分销系统 口令
-	GiveCycle        int                      `json:"give_cycle,omitempty"`     //赠送周期
-	OriginalPrice    int                      `json:"original_price,omitempty"` //双十一活动原价价格
-	GiveType         int                      `json:"give_type,omitempty"`      //赠送周期 类型 1天 2月
-	DisCountId       int                      `json:"discountId,omitempty"`     //赠送的id
-	Badge            string                   `json:"badge,omitempty"`          //活动标识
-	Remark           string                   `json:"remark"`                   //备注
+	Area             *map[string]interface{}  `json:"area"`                        //选择地区
+	Industry         []string                 `json:"industry"`                    //选择行业
+	Cyclecount       int                      `json:"cyclecount"`                  //日期数量(订单详情展示使用)
+	Cycleunit        int                      `json:"cycleunit"`                   //日期单位(订单详情展示使用)
+	OldBuyset        *SubvipBuySet            `json:"buyset"`                      //旧购买详情
+	NewBuyset        *SubvipBuySet            `json:"newBuyset"`                   //新购买详情
+	UpgradeSubtotail []map[string]interface{} `json:"upgradeSubtotail"`            //升级清单(订单详情计价清单展示使用)
+	OrderType        int                      `json:"ordertype"`                   //1,3,5   类型 1:订单 2:续费 3:立即升级 4:下月升级 5:即将到期(可升降级续费)6:升级订单未生效再次升级
+	DisWord          string                   `json:"disWord"`                     //分销系统 口令
+	OriginalPrice    int                      `json:"original_price,omitempty"`    //双十一活动原价价格
+	GiveCycle        int                      `json:"give_cycle,omitempty"`        //赠送周期
+	GiveType         int                      `json:"give_type,omitempty"`         //赠送周期 类型 1天 2月
+	SellerGiveCycle  int                      `json:"seller_give_cycle,omitempty"` //赠送周期(销售创建订单赠送)
+	SellerGiveType   int                      `json:"seller_give_type,omitempty"`  //赠送周期 类型 1天 2月(销售创建订单赠送)
+	DisCountId       int                      `json:"discountId,omitempty"`        //赠送的id
+	Badge            string                   `json:"badge,omitempty"`             //活动标识
+	Remark           string                   `json:"remark"`                      //备注
 }
 
-//购买内容
+// 购买内容
 type SubvipBuySet struct {
 	Upgrade         int   `json:"upgrade"`         //是否是升级版;1是 其他不是
 	AreaCount       int   `json:"areacount"`       //-1 全国  >0 省份数量
@@ -102,16 +104,10 @@ type SubvipBuySet struct {
 	BuyerclassCount int   `json:"buyerclasscount"` //行业数
 }
 
-//支付完成回调
+// 支付完成回调
 func (this *vipSubscribeStruct) PayCallBack(param *CallBackParam) bool {
 	now := time.Now()
-	query := map[string]interface{}{}
-	if param.OrderCode != "" { //线下支付
-		query["order_code"] = param.OrderCode
-	} else { //支付宝微信回调
-		query["out_trade_no"] = param.OutTradeno
-	}
-	orderdata := util.Mysql.FindOne("dataexport_order", query, "id,filter,order_money,order_code,order_status,user_id,vip_starttime,vip_endtime,vip_type,prepay_time,dis_word,user_id,create_time,d_relation_id", "")
+	orderdata := util.Mysql.FindOne("dataexport_order", param.GetPaySuccessOrderQuery(), "id,filter,order_money,order_code,order_status,user_id,vip_starttime,vip_endtime,vip_type,prepay_time,dis_word,user_id,create_time,d_relation_id,order_channel", "")
 	pay_time := qutil.FormatDate(&now, qutil.Date_Full_Layout)
 	if orderdata == nil {
 		log.Println("未找到订单")
@@ -148,6 +144,8 @@ func (this *vipSubscribeStruct) PayCallBack(param *CallBackParam) bool {
 		"pay_money":    param.CashFee,
 		"pay_time":     pay_time,
 		"order_status": 1,
+		//支付成功后更新成支付成功的out_trade_no 避免多人支付重复刷新字段
+		"out_trade_no": param.OutTradeno,
 	}
 	var startTime time.Time
 	var endTime time.Time
@@ -162,6 +160,13 @@ func (this *vipSubscribeStruct) PayCallBack(param *CallBackParam) bool {
 		} else if vmsg.GiveType == 2 {
 			endTime = endTime.AddDate(0, vmsg.GiveCycle, 0)
 		}
+
+		if vmsg.SellerGiveType == 1 {
+			endTime = endTime.AddDate(0, 0, vmsg.SellerGiveCycle)
+		} else if vmsg.SellerGiveType == 2 {
+			endTime = endTime.AddDate(0, vmsg.SellerGiveCycle, 0)
+		}
+
 		updateMap["vip_starttime"] = qutil.FormatDate(&startTime, qutil.Date_Full_Layout)
 		updateMap["vip_endtime"] = qutil.FormatDate(&endTime, qutil.Date_Full_Layout)
 	} else if vmsg.OrderType == 2 || vmsg.OrderType == 3 || vmsg.OrderType == 5 {
@@ -184,6 +189,10 @@ func (this *vipSubscribeStruct) PayCallBack(param *CallBackParam) bool {
 			}
 		}
 	}
+	// 销售待用户下单 更新销售时间
+	if qutil.ObjToString((*orderdata)["order_channel"]) == "xdqd04" {
+		updateMap["sale_time"] = pay_time
+	}
 
 	update := util.Mysql.Update("dataexport_order", map[string]interface{}{
 		"id": (*orderdata)["id"],
@@ -249,7 +258,7 @@ func (this *vipSubscribeStruct) PayCallBack(param *CallBackParam) bool {
 	return flag
 }
 
-//获取用户最后一笔支付数据
+// 获取用户最后一笔支付数据
 func (this *vipSubscribeStruct) GetUserLastOrderDetaul(userid string) (VipSimpleMsg, error) {
 	vmsg := VipSimpleMsg{}
 	orderData := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
@@ -267,7 +276,7 @@ func (this *vipSubscribeStruct) GetUserLastOrderDetaul(userid string) (VipSimple
 	return vmsg, nil
 }
 
-//设置开始使用vip订阅
+// 设置开始使用vip订阅
 func (this *vipSubscribeStruct) StartSubVip(userId string, vmsg VipSimpleMsg, startTime, endTime time.Time, isTrial bool) bool {
 	set := map[string]interface{}{
 		"o_vipjy.i_trial":  -1,                      //已激活试用
@@ -297,7 +306,7 @@ func (this *vipSubscribeStruct) StartSubVip(userId string, vmsg VipSimpleMsg, st
 	return true
 }
 
-//仅续费
+// 仅续费
 func (this *vipSubscribeStruct) RenewSubVip(userId string, end string) bool {
 	endTime, err := time.ParseInLocation(qutil.Date_Full_Layout, end, time.Local)
 	if err != nil {
@@ -317,7 +326,7 @@ func (this *vipSubscribeStruct) RenewSubVip(userId string, end string) bool {
 	return true
 }
 
-//即将到期续费
+// 即将到期续费
 func (this *vipSubscribeStruct) WillNew(userId string, vmsg VipSimpleMsg, start, end string) bool {
 	startTime, err := time.ParseInLocation(qutil.Date_Full_Layout, start, time.Local)
 	endTime, err2 := time.ParseInLocation(qutil.Date_Full_Layout, end, time.Local)
@@ -357,7 +366,7 @@ func (this *vipSubscribeStruct) WillNew(userId string, vmsg VipSimpleMsg, start,
 	}
 }
 
-//升级
+// 升级
 func (this *vipSubscribeStruct) UpgradeSubVip(userId string, vmsg VipSimpleMsg, end string) bool {
 	endTime, err := time.ParseInLocation(qutil.Date_Full_Layout, end, time.Local)
 	if err != nil {
@@ -398,7 +407,7 @@ func (this *vipSubscribeStruct) UpgradeSubVip(userId string, vmsg VipSimpleMsg,
 	}
 }
 
-//超级订阅获取购买项
+// 超级订阅获取购买项
 func (this *vipSubscribeStruct) NewBuySet(area *map[string]interface{}, industry []string, isUpgrade bool) *SubvipBuySet {
 	pCount := -1
 	citys := []int{}
@@ -453,7 +462,7 @@ func (this *vipSubscribeStruct) NewBuySet(area *map[string]interface{}, industry
 	return &buyset
 }
 
-//查询是否有试用权限
+// 查询是否有试用权限
 func (this *vipSubscribeStruct) CanTrial(userId string) bool {
 	m, ok := util.MQFW.FindById("user", userId, `{"o_vipjy":1,"i_vip_status":1}`)
 	if m == nil || len(*m) == 0 || !ok {
@@ -470,7 +479,7 @@ func (this *vipSubscribeStruct) CanTrial(userId string) bool {
 	return true
 }
 
-//订阅修改
+// 订阅修改
 func (this *vipSubscribeStruct) SubChange(userId string, oldVip, areaNew *map[string]interface{}, industryNew []string) bool {
 	updateOk := util.MQFW.UpdateById("user", userId,
 		bson.M{"$set": bson.M{
@@ -495,8 +504,8 @@ func (this *vipSubscribeStruct) SubChange(userId string, oldVip, areaNew *map[st
 	return true
 }
 
-//获取省份,城市,行业购买内容
-//[省份,城市,行业]
+// 获取省份,城市,行业购买内容
+// [省份,城市,行业]
 func (this *vipSubscribeStruct) GetVipDetail(userId string) (*map[string]interface{}, *SubvipBuySet, bool) {
 	mData, ok := util.MQFW.FindById("user", userId, `{"o_vipjy":1,"i_vip_status":1,"l_vip_endtime":1,"l_vip_starttime":1,"isread":1}`)
 	if !ok || len(*mData) == 0 || mData == nil {
@@ -526,7 +535,7 @@ func (this *vipSubscribeStruct) GetMergeNewBuyset(o_buyset map[string]interface{
 
 }
 
-//保存筛选日志
+// 保存筛选日志
 func (this *vipSubscribeStruct) SaveSelectLog(userId, openId string, msg *VipSimpleMsg) string {
 	return util.MQFW.Save("subvip_select", map[string]interface{}{
 		"o_area":       msg.Area,     //地区(对象)
@@ -540,16 +549,16 @@ func (this *vipSubscribeStruct) SaveSelectLog(userId, openId string, msg *VipSim
 
 }
 
-//计算价格
+// 计算价格
 func (this *vipSubscribeStruct) GetSubVipPrice(buyset *SubvipBuySet, count, unit int) int {
 	return this.GetSubVipPriceByBuySet(buyset, count, unit, true)
 }
 
-//cityCountMap 选择城市数量
-//pCount 选择省份数量  pCount:-1 (全国)
-//industryNum 选择行业数量
-//count 时间长度  unit 时间单位
-//isDiscount 测试环境是否打折
+// cityCountMap 选择城市数量
+// pCount 选择省份数量  pCount:-1 (全国)
+// industryNum 选择行业数量
+// count 时间长度  unit 时间单位
+// isDiscount 测试环境是否打折
 func (this *vipSubscribeStruct) GetSubVipPriceByBuySet(buySet *SubvipBuySet, count, unit int, isDiscount bool) int {
 	log.Println("时间长度:", count)
 	log.Println("时间单位:", unit)
@@ -737,7 +746,7 @@ func getSetMealPrice(p, u int) int {
 	return 0
 }
 
-//支付成功后,将该订单以外的所有订单状态改为已取消状态 已取消:-2  先关闭订单再改状态  --entname 企业商机管理订单会用到该参数 其他取消订单不需要
+// 支付成功后,将该订单以外的所有订单状态改为已取消状态 已取消:-2  先关闭订单再改状态  --entname 企业商机管理订单会用到该参数 其他取消订单不需要
 func PayCancel(userId, product_type, entname string) bool {
 	queryMap := map[string]interface{}{
 		"user_id":      userId,
@@ -795,7 +804,7 @@ func PayCancel(userId, product_type, entname string) bool {
 	return len(errOrderOrder) == 0 //更改成功次数是否等于需要更改次数
 }
 
-//双十一活动 判断用户是否已经获得赠送周期资格
+// 双十一活动 判断用户是否已经获得赠送周期资格
 func (this *vipSubscribeStruct) IsHaveCycle(userId string) bool {
 	data, ok := util.MQFW.FindById("user", userId, `{"i_member_give":1}`)
 	if ok {
@@ -806,7 +815,7 @@ func (this *vipSubscribeStruct) IsHaveCycle(userId string) bool {
 	return false
 }
 
-//是否在活动期间
+// 是否在活动期间
 func (this *vipSubscribeStruct) IsActiving() bool {
 	now := time.Now()
 	if active.ActiveConfig.DoubleEleven.Active_Start < now.Unix() && active.ActiveConfig.DoubleEleven.Active_End > now.Unix() {
@@ -817,7 +826,7 @@ func (this *vipSubscribeStruct) IsActiving() bool {
 	return false
 }
 
-//是否已经设置过订阅设置 true 已设置  fasle未设置
+// 是否已经设置过订阅设置 true 已设置  fasle未设置
 func BuyerClassStatus(userid string) bool {
 	mData, ok := util.MQFW.FindById("user", userid, `{"o_vipjy":1}`)
 	if !ok || len(*mData) == 0 || mData == nil {
@@ -832,7 +841,7 @@ func BuyerClassStatus(userid string) bool {
 	return false
 }
 
-//修改附件下载包到期时间
+// 修改附件下载包到期时间
 func FilepackEndtime(userid string) bool {
 	now := time.Now()
 	lastdata := JyresoucePack.LastDate(now)
@@ -868,9 +877,9 @@ func FilepackEndtime(userid string) bool {
 	return true
 }
 
-//超级订阅 计算周期
-//cycleunit(1:年 2:月 3:天 4:季)
-//cyclecount 数字长度
+// 超级订阅 计算周期
+// cycleunit(1:年 2:月 3:天 4:季)
+// cyclecount 数字长度
 func (this *vipSubscribeStruct) CheckReqDate(dateStr string) (cyclecount, cycleunit int, err error) {
 	if strings.HasSuffix(dateStr, "年") {
 		cycleunit = 1
@@ -900,7 +909,7 @@ func (this *vipSubscribeStruct) CheckReqDate(dateStr string) (cyclecount, cycleu
 	return -1, -1, errors.New(fmt.Sprintf("日期%s格式化出错", dateStr))
 }
 
-//获取升级小计价格
+// 获取升级小计价格
 func (this *vipSubscribeStruct) GetSubtotalPrice(oldBuyset, newBuyset *SubvipBuySet, startTime, endtime int64) int {
 	if !func() bool { //不能降级
 		if oldBuyset.Upgrade == 1 {
@@ -928,7 +937,7 @@ func (this *vipSubscribeStruct) GetSubtotalPrice(oldBuyset, newBuyset *SubvipBuy
 	return newPrice - beforePrice
 }
 
-//获取新版超级订阅升级价格、清单
+// 获取新版超级订阅升级价格、清单
 func (this *vipSubscribeStruct) GetNewUpgradeDetail(userId string, newBuySet, oldBuySet *SubvipBuySet, oldEndtime int64, count, unit int) (totalPrice int, subtotals []map[string]interface{}) {
 	rResult, ok := util.MQFW.Find("vip_upgrade", &bson.M{"s_userid": userId, "i_isvalid": 0}, `{"l_validtime":1}`, `{"o_buyset":1,"l_validtime":1}`, false, -1, -1)
 	if !ok {

+ 1 - 0
src/jfw/modules/subscribepay/src/filter/sessionfilter.go

@@ -22,6 +22,7 @@ func (l *sessionfilter) Do() bool {
 		strings.HasPrefix(rqu, "/subscribepay/index/getIndexMessage") ||
 		strings.HasPrefix(rqu, "/res/dataexport") ||
 		strings.HasPrefix(rqu, "/jyactive") ||
+		strings.HasPrefix(rqu, "/jypay/free/") || //销售代创建订单
 		rqu == "/jypay/wx/getwxSdkSign" ||
 		rqu == "/jypay/user/company/association" { //微信js调用参数
 		return true

+ 24 - 1
src/jfw/modules/subscribepay/src/pay/util.go

@@ -14,6 +14,7 @@ import (
 	"hash"
 	"log"
 	qutil "qfw/util"
+	"qfw/util/redis"
 	"strings"
 	"sync"
 	"time"
@@ -233,8 +234,10 @@ productSign 产品种类标识
 ip 用户ip(仅微信支付需要)
 openid 用户openid(仅微信支付需要)
 payWay 支付方式
+
+⚠️ 需缓存tradeno
 */
-func CreateOrderPay(price int, productSign, ip, openid, payWay string) (tradeno, prepayid, payParam string, err error) {
+func CreateOrderPay(price int, productSign, ip, openid, payWay, orderCode string) (tradeno, prepayid, payParam string, err error) {
 	switch payWay {
 	case "wx_js", "wx_app", "wx_pc": //微信公众号支付,微信app支付,微信扫码支付
 		var ret *map[string]string
@@ -269,9 +272,29 @@ func CreateOrderPay(price int, productSign, ip, openid, payWay string) (tradeno,
 			return
 		}
 	}
+
+	if orderCode != "" && tradeno != "" {
+		CacheTradeNo(tradeno, orderCode)
+	}
+
 	return
 }
 
+const (
+	CacheOrderTradeNo = "jypay_cacheTradeNo_%s"
+	CacheTime         = 60 * 60 * 24 * 3
+)
+
+// CacheTradeNo 缓存订单唯一表示标识
+// 防止支付完成后刷新订单支付回调找不到订单
+func CacheTradeNo(tradeNo, orderCode string) {
+	redis.Put("other", fmt.Sprintf(CacheOrderTradeNo, tradeNo), orderCode, CacheTime)
+}
+
+func GetCacheOrderCode(tradeNo string) (orderCode string) {
+	return redis.GetStr("other", fmt.Sprintf(CacheOrderTradeNo, tradeNo))
+}
+
 //关闭订单
 func CloseOrderByOrderCode(ordercode string) error {
 	res := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": ordercode}, "out_trade_no,pay_way", "")

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

@@ -67,7 +67,7 @@ func (this *AreaPack) CreateOrder() {
 		discountId, _ := this.GetInteger("discountId")
 		if discountId > 0 {
 			isgive = true
-			timeNum, timeType, _ := util.GiveInfo(userId, useProduct, 0, discountId) //获取满赠时长
+			_, timeNum, timeType, _, _, _, _, _ := util.GiveInfo(userId, useProduct, 0, discountId) //获取满赠时长
 			filter.GiveCycle = timeNum
 			filter.GiveType = timeType
 			filter.DisCountId = discountId

+ 43 - 27
src/jfw/modules/subscribepay/src/service/commonAction.go

@@ -38,7 +38,7 @@ type CommonAction struct {
 	deleteOrder          xweb.Mapper `xweb:"/deleteOrder"`                 //删除订单
 	applyInvoice         xweb.Mapper `xweb:"/applyInvoice"`                //申请发票
 	sendMailNote         xweb.Mapper `xweb:"/sendMailNote/(.*)"`           //发送附件邮件通知
-	createorder          xweb.Mapper `xweb:"/common/createorder"`
+	createorder          xweb.Mapper `xweb:"/common/createorder"`          //创建订单公共方法
 }
 
 var pdfNameReg = regexp.MustCompilePOSIX(`[^//]*\.pdf`)
@@ -378,7 +378,7 @@ func (this *CommonAction) GetCommonPayParam() {
 		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)
+		tradeno, prepayid, payParam, err := pay.CreateOrderPay(totalfee, productFlag, this.IP(), qutil.ObjToString(this.GetSession("s_m_openid")), payway_req, orderCode)
 		if err != nil {
 			return &entity.FuncResult{false, errors.New(fmt.Sprintf("创建支付失败[%v]", err)), nil}
 		}
@@ -493,7 +493,7 @@ func (this *CommonAction) Createorder() {
 		}
 		body := xweb.FilterXSS(string(this.Body()))
 		//接收参数
-		json.Unmarshal([]byte(body), &infoMap)
+		_ = json.Unmarshal([]byte(body), &infoMap)
 		if len(infoMap) == 0 {
 			return nil, fmt.Errorf("无效参数")
 		}
@@ -510,43 +510,56 @@ func (this *CommonAction) Createorder() {
 			return nil, fmt.Errorf("无效参数")
 		}
 		log.Println(infoMap)
-		now := time.Now()
+
+		//校验
+		if err := entity.JyCommonOrderStruct.RequestCheck(product, data, this.Session()); err != "" {
+			return nil, fmt.Errorf(err)
+		}
+
 		//获取卡券相关
 		lotteryId := qutil.ObjToString(data["lotteryId"]) //卡卷信息的id
 		i_discountId := qutil.IntAll(data["discountId"])  //赠品相关
 		discountId := strconv.Itoa(i_discountId)
-		inserMap, msg := entity.JyCommonOrderStruct.InserMap(product, productId, userid, lotteryId, discountId, data, this.Session())
+
+		inserMap, msg := entity.JyCommonOrderStruct.InserMap(product, productId, userid, lotteryId, discountId, data)
 		//错误信息
 		if msg != "" {
 			return nil, fmt.Errorf(msg)
 		}
+		now := time.Now()
 		distributionChannel, orderChannel := util.GetJyOrderChannel(inserMap.DisWord, this.Header("User-Agent"))
 		insertM := map[string]interface{}{
-			"order_money":        inserMap.OrderMoney,
-			"order_status":       inserMap.OrderStatus,
-			"service_status":     inserMap.ServiceStatus,
-			"user_nickname":      inserMap.UserNickname,
-			"user_openid":        inserMap.UserOpenid,
-			"user_phone":         inserMap.UserPhone,
-			"order_code":         inserMap.OrderCode,
-			"product_type":       product,
-			"create_time":        qutil.FormatDate(&now, qutil.Date_Full_Layout),
-			"original_price":     inserMap.OriginalPrice,
-			"user_id":            userid,
-			"filter":             inserMap.Filter,
-			"discount_price":     inserMap.DiscountPrice,
-			"d_relation_id":      inserMap.DrelationId,
-			"data_spec":          inserMap.DataSpec,
-			"user_mail":          inserMap.UserMail,
-			"data_count":         inserMap.DataCount,
-			"filter_publishtime": inserMap.FilterPublishtime,
-			"filter_keys":        inserMap.FilterKeys,
-			"download_url":       inserMap.DownloadUrl,
-			// "vip_type":             inserMap.VipType,
+			"order_money":          inserMap.OrderMoney,
+			"order_status":         inserMap.OrderStatus,
+			"service_status":       inserMap.ServiceStatus,
+			"user_phone":           inserMap.UserPhone,
+			"order_code":           inserMap.OrderCode,
+			"product_type":         product,
+			"create_time":          qutil.FormatDate(&now, qutil.Date_Full_Layout),
+			"original_price":       inserMap.OriginalPrice,
+			"user_id":              userid,
+			"filter":               inserMap.Filter,
+			"discount_price":       inserMap.DiscountPrice,
+			"d_relation_id":        inserMap.DrelationId,
+			"data_spec":            inserMap.DataSpec,
+			"user_mail":            inserMap.UserMail,
+			"data_count":           inserMap.DataCount,
+			"filter_publishtime":   inserMap.FilterPublishtime,
+			"filter_keys":          inserMap.FilterKeys,
+			"download_url":         inserMap.DownloadUrl,
 			"dis_word":             inserMap.DisWord,
 			"distribution_channel": distributionChannel, //销售渠道
 			"order_channel":        orderChannel,        //下单渠道
 		}
+
+		if openId := qutil.ObjToString(this.GetSession("s_m_openid")); openId != "" {
+			insertM["user_openid"] = openId
+		}
+
+		if nickname := qutil.ObjToString(this.GetSession("s_nickname")); nickname != "" {
+			insertM["user_nickname"] = nickname
+		}
+
 		if inserMap.VipStartTime != "" && inserMap.VipEndTime != "" {
 			insertM["vip_starttime"] = inserMap.VipStartTime
 			insertM["vip_endtime"] = inserMap.VipEndTime
@@ -572,12 +585,15 @@ func (this *CommonAction) Createorder() {
 		if inserMap.VipType != 0 {
 			insertM["vip_type"] = inserMap.VipType
 		}
+		if inserMap.ExpirationTime != "" {
+			insertM["expiration_time"] = inserMap.ExpirationTime
+		}
 		orderid := util.Mysql.Insert("dataexport_order", insertM)
 		if orderid <= 0 {
 			return nil, fmt.Errorf("创建订单异常")
 		}
 		if i_discountId > 0 {
-			go util.FindUserLotteryId(userid, orderid, i_discountId)
+			util.FindUserLotteryId(userid, orderid, i_discountId)
 		}
 		rdata := map[string]interface{}{"order_code": inserMap.OrderCode, "needPay": !inserMap.UnNeedPay}
 		return rdata, nil

+ 2 - 0
src/jfw/modules/subscribepay/src/service/dataexportPack.go

@@ -46,6 +46,8 @@ func (this *DataExportPack) PackGoodsList() {
 		res, err := http.Get(getUrl)
 		if err != nil {
 			log.Println(err.Error())
+			this.ServeJson(packList)
+			return
 		}
 		defer res.Body.Close()
 		bs, _ := ioutil.ReadAll(res.Body)

+ 10 - 10
src/jfw/modules/subscribepay/src/service/invoice.go

@@ -41,7 +41,7 @@ type InvoiceInfo struct {
 	data map[string]interface{} `json:"data"`
 }
 
-//红票信息
+// 红票信息
 type RedMsg struct {
 	InvoiceCode      string `json:"invoice_code"`
 	InvoiceNumber    string `json:"invoice_number"`
@@ -187,9 +187,10 @@ func (this *Invoice) Addinvoice() error {
 		pos := qutil.IntAllDef(last, 0)
 		locks[pos].Lock()
 		defer locks[pos].Unlock()
-		u := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": order_code, "user_id": userId, "applyBill_status": map[string]interface{}{"ne": 2}}, "order_money,product_type,pay_way,pay_money,is_backstage_order,billingMode", "")
+		u := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": order_code, "user_id": userId, "applyBill_status": map[string]interface{}{"ne": 2}}, "order_money,product_type,order_channel,pay_way,pay_money,is_backstage_order,billingMode", "")
 		if u != nil {
-			if qutil.IntAll((*u)["billingMode"]) == 1 && qutil.IntAll((*u)["is_backstage_order"]) != 1 {
+			//后端代用户下单支持开票 order_channel = xdqd04
+			if qutil.IntAll((*u)["billingMode"]) == 1 && (qutil.IntAll((*u)["is_backstage_order"]) != 1 || qutil.InterfaceToStr((*u)["order_channel"]) == "xdqd04") {
 				var prices float64
 				//公对公转账 账单金额可以修改 开发票应取实付金额 pay_money
 				//微信支付宝支付 pay_money为订单金额减去微信or支付包红包
@@ -302,7 +303,6 @@ func (this *Invoice) Addinvoice() error {
 							}
 						}
 						defer response.Body.Close()
-
 						resData := (*resMap)["data"].(map[string]interface{})
 						update_status := util.Mysql.Update(dbname, map[string]interface{}{"order_code": order_code}, map[string]interface{}{
 							"invoice_serialnum": resData["swno"],
@@ -318,7 +318,7 @@ func (this *Invoice) Addinvoice() error {
 				}
 			}
 		} else {
-			if !updata_status || invoice_status != 1 {
+			if invoice_status != 1 {
 				log.Println("invoice err:", "updata_status:", updata_status, "order_code:", order_code, "invoice_status:", invoice_status, userId)
 			}
 		}
@@ -328,7 +328,7 @@ func (this *Invoice) Addinvoice() error {
 	return nil
 }
 
-//查看发票
+// 查看发票
 func (this *Invoice) Showinvoice() {
 	order_code := this.GetString("order_code")
 	data := make(map[string]interface{})
@@ -375,7 +375,7 @@ func (this *Invoice) Showinvoice() {
 
 }
 
-//开发票回调
+// 开发票回调
 func (this *Invoice) Callbackinvoice() {
 	isRed, _ := this.GetBool("isRed")
 	resType := this.GetString("resType") //红票回调-->"changed":换票 "refund":退票
@@ -586,7 +586,7 @@ func (this *Invoice) Callbackinvoice() {
 	}
 }
 
-//换票
+// 换票
 func (this *Invoice) Replaceinvoice() {
 	userId := qutil.ObjToString(this.GetSession("userId"))
 	order_code := this.GetString("order_code")
@@ -849,7 +849,7 @@ func (this *Invoice) Replaceinvoice() {
 
 }
 
-//退票
+// 退票
 func (this *Invoice) Refundinvoice() {
 	var refund_flag = -1
 	userid := this.GetSession("userId")
@@ -971,7 +971,7 @@ func (this *Invoice) Available() {
 	})
 }
 
-//删除有问题的换开发票并记录
+// 删除有问题的换开发票并记录
 func delReplaceInvoice(query map[string]interface{}) bool {
 	data := util.Mysql.FindOne(dbname, query, "", "")
 	if data != nil && len(*data) > 0 {

+ 57 - 39
src/jfw/modules/subscribepay/src/service/orderListDetails.go

@@ -39,6 +39,8 @@ type OrderListDetails struct {
 	getMemberDetail     xweb.Mapper `xweb:"/orderListDetails/getMemberDetail"`  //大会员订单详情页
 	getBidfileDetail    xweb.Mapper `xweb:"/orderListDetails/getBidileDetail"`  //剑鱼币订单详情页
 	jyPoint             xweb.Mapper `xweb:"/order/jyPoint"`                     //剑鱼币
+
+	replaceOrderInfo xweb.Mapper `xweb:"/orderListDetails/replaceOrderInfo"` //代付订单详情页
 }
 
 var (
@@ -50,10 +52,11 @@ var (
 	tableName_order      = "dataexport_order" //订单表
 )
 
-//订单数据展示(订单详情页面)
+// 订单数据展示(订单详情页面)
 func (this *OrderListDetails) GetOrderPayAllMsg() {
-	fields := "id,order_code,prepay_time,create_time,pay_time,pay_way,original_price,order_money,pay_money,applybill_status,out_trade_no,filter,product_type,order_status,applybill_type,applybill_taxnum,applybill_company,vip_starttime,vip_endtime,vip_type,discount_price,d_relation_id,billingMode,return_status,is_backstage_order,vip_starttime,vip_endtime"
-	data, t, transaction_id := this.CommonDetail(4, fields)
+	userId := qutil.ObjToString(this.GetSession("userId"))
+	fields := "id,order_code,order_channel,prepay_time,del_status,create_time,pay_time,pay_way,original_price,order_money,pay_money,applybill_status,out_trade_no,filter,product_type,order_status,applybill_type,applybill_taxnum,applybill_company,vip_starttime,vip_endtime,vip_type,discount_price,d_relation_id,billingMode,return_status,is_backstage_order,vip_starttime,vip_endtime,expiration_time"
+	data, t, transaction_id := CommonDetail(4, fields, userId, this.GetString("orderCode"))
 	r := &entity.FuncResult{true, nil, map[string]interface{}{
 		"order":          data,
 		"time":           t,
@@ -62,7 +65,7 @@ func (this *OrderListDetails) GetOrderPayAllMsg() {
 	this.ServeJson(r.Format())
 }
 
-//订单列表首页
+// 订单列表首页
 func (o *OrderListDetails) MyOrder() {
 	//每页显示数
 	userId := o.Session().Get("userId")
@@ -118,7 +121,7 @@ func TypSta(typ string) (queryM interface{}) {
 	return
 }
 
-//删除或取消订单
+// 删除或取消订单
 func (o *OrderListDetails) DeleteOrder() error {
 	if userId := o.GetSession("userId"); userId != nil {
 		queryMap := map[string]interface{}{
@@ -151,6 +154,7 @@ func (o *OrderListDetails) DeleteOrder() error {
 				nextPage = true
 			}
 			if res != nil {
+				log.Println(res)
 				o.SetRes(res, queryM)
 			}
 		}
@@ -205,7 +209,7 @@ func (o *OrderListDetails) DeleteOrder() error {
 	return nil
 }
 
-//设置邮箱-发送验证码
+// 设置邮箱-发送验证码
 func (o *OrderListDetails) SetEmail() {
 	email := o.GetString("email")
 	userId := qutil.ObjToString(o.GetSession("userId"))
@@ -270,7 +274,7 @@ func (o *OrderListDetails) SetEmail() {
 	o.ServeJson(&o.T)
 }
 
-//验证邮箱-验证码
+// 验证邮箱-验证码
 func (o *OrderListDetails) CheckMailCodeVerify() {
 	email := o.GetString("email")
 	emailVerity := o.GetString("emailVerity")
@@ -287,7 +291,7 @@ func (o *OrderListDetails) CheckMailCodeVerify() {
 	o.ServeJson(&o.T)
 }
 
-//邮箱操作:绑定,解绑,更换,查看
+// 邮箱操作:绑定,解绑,更换,查看
 func (o *OrderListDetails) EmailOperation() {
 	operation := o.GetString("operation")
 	email := o.GetString("email")
@@ -318,7 +322,7 @@ func (o *OrderListDetails) EmailOperation() {
 	o.ServeJson(&o.T)
 }
 
-//计价清单
+// 计价清单
 func (o *OrderListDetails) GetValuationList() error {
 	userId := o.GetSession("userId")
 	order_code := o.GetString("order_code")
@@ -348,7 +352,7 @@ func (o *OrderListDetails) GetValuationList() error {
 	return nil
 }
 
-//会员状态
+// 会员状态
 func (o *OrderListDetails) IsVip() {
 	var isV, flagBger = false, 0
 	res, err := util.MQFW.FindOne("user", bson.M{"_id": StringTOBsonId(qutil.ObjToString(o.GetSession("userId")))})
@@ -364,7 +368,7 @@ func (o *OrderListDetails) IsVip() {
 	})
 }
 
-//获取购买订阅相关信息
+// 获取购买订阅相关信息
 func (o *OrderListDetails) GetVipOrderInfo() {
 	userId := qutil.ObjToString(o.GetSession("userId"))
 	order_code := o.GetString("orderCode")
@@ -420,10 +424,11 @@ func (o *OrderListDetails) GetVipOrderInfo() {
 	})
 }
 
-//企业商机管理详情页
+// 企业商机管理详情页
 func (o *OrderListDetails) GetEntnicheDetails() {
+	userId := qutil.ObjToString(o.GetSession("userId"))
 	fields := "id,order_code,order_status,create_time,pay_time,pay_way,out_trade_no,prepay_id,product_type,pay_money,order_money,filter,applybill_type,applybill_taxnum,applybill_company,applybill_status"
-	data, _, _ := o.CommonDetail(3, fields)
+	data, _, _ := CommonDetail(3, fields, userId, o.GetString("order_code"))
 	o.ServeJson(map[string]interface{}{
 		"data": data,
 	})
@@ -447,11 +452,11 @@ func (o *OrderListDetails) EntIsCanBuy() {
 	return
 }
 
-//获取最后一次购买的订单 product_type : 参数
+// 获取最后一次购买的订单 product_type : 参数
 func LastOrder(product_type, userid string) map[string]string {
 	m := map[string]string{}
 	args := []interface{}{}
-	sql := `select product_type,order_code from dataexport_order where del_status=0 
+	sql := `select product_type,order_code from dataexport_order where del_status=0
 and order_status=1 and  product_type in(`
 	for k, v := range strings.Split(product_type, ",") {
 		m[v] = ""
@@ -577,9 +582,9 @@ func (o *OrderListDetails) SetRes(res []map[string]interface{}, queryM map[strin
 	}
 }
 
-//查询数据
+// 查询数据
 func (o *OrderListDetails) Datas(queryM map[string]interface{}, pageNum, pagesize_max int) (haveNextPage bool, result []map[string]interface{}, err error) {
-	res := *util.Mysql.Find(tableName_order, queryM, "id,order_code,filter_publishtime,create_time,data_spec,filter_id,filter_keys,order_money,pay_money,data_count,order_status,pay_way,product_type,filter,pay_time,vip_starttime,vip_endtime,applybill_status,applybill_type,applybill_taxnum,applybill_company,vip_type,course_status,discount_price,d_relation_id,billingMode,is_backstage_order,return_status", "create_time desc", -1, 0)
+	res := *util.Mysql.Find(tableName_order, queryM, "id,order_code,order_channel,filter_publishtime,create_time,data_spec,filter_id,filter_keys,order_money,pay_money,data_count,order_status,pay_way,product_type,filter,pay_time,vip_starttime,vip_endtime,applybill_status,applybill_type,applybill_taxnum,applybill_company,vip_type,course_status,discount_price,d_relation_id,billingMode,is_backstage_order,return_status,expiration_time", "create_time desc", -1, 0)
 	if len(res) > 0 {
 		start := (pageNum - 1) * pagesize_max
 		end := pageNum * pagesize_max
@@ -650,8 +655,15 @@ func (o *OrderListDetails) Datas(queryM map[string]interface{}, pageNum, pagesiz
 				i_countdown := qutil.IntAll(order_countdown)
 				create_time_stamp = create_time.AddDate(0, 0, i_countdown).Unix()
 			}
+			expirationBl := false
+			if result[i]["expiration_time"] != nil {
+				expiration_time, _ := time.ParseInLocation(qutil.Date_Full_Layout, qutil.ObjToString(result[i]["expiration_time"]), time.Local)
+				if expiration_time.Unix() < time.Now().Unix() {
+					expirationBl = true
+				}
+			}
 			is_backstage_order := qutil.IntAllDef(result[i]["is_backstage_order"], 0)
-			if create_time_stamp < time.Now().Unix() && qutil.IntAll(result[i]["order_status"]) == 0 && is_backstage_order == 0 {
+			if (create_time_stamp < time.Now().Unix() || expirationBl) && qutil.IntAll(result[i]["order_status"]) == 0 && is_backstage_order == 0 {
 				result[i]["order_status"] = orderStatus_cancel
 				go FortyEightHoursCancel(qutil.ObjToString(result[i]["order_code"]), create_time_stamp, time.Now().Unix())
 			}
@@ -661,13 +673,13 @@ func (o *OrderListDetails) Datas(queryM map[string]interface{}, pageNum, pagesiz
 	return
 }
 
-//邮箱正则验证
+// 邮箱正则验证
 func isEmail(value string) bool {
 	var emailPattern = regexp.MustCompile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")
 	return emailPattern.MatchString(value)
 }
 
-//获取支付单号
+// 获取支付单号
 func getPayTransactionId(payWay, tradeNo string) (transaction_id string) {
 	if payWay == "" || tradeNo == "" {
 		return
@@ -690,7 +702,7 @@ func getPayTransactionId(payWay, tradeNo string) (transaction_id string) {
 	return
 }
 
-//检查vip订单是否到期,如果到期 订单取消
+// 检查vip订单是否到期,如果到期 订单取消
 func FortyEightHoursCancel(order string, create_time_stamp, now_time_stamp int64) {
 	//查询vip订单条件
 	queryM := map[string]interface{}{
@@ -698,15 +710,25 @@ func FortyEightHoursCancel(order string, create_time_stamp, now_time_stamp int64
 		"order_status":       0,
 		"is_backstage_order": 0,
 	}
-	res := util.Mysql.FindOne(tableName_order, queryM, "id,order_code,create_time,pay_way,out_trade_no,prepay_time,order_status,discount_price,d_relation_id,user_id,filter,product_type", "")
+	res := util.Mysql.FindOne(tableName_order, queryM, "id,order_code,create_time,pay_way,out_trade_no,prepay_time,order_status,discount_price,d_relation_id,user_id,filter,product_type,expiration_time", "")
 	if res != nil {
 		id := qutil.Int64All((*res)["id"])
 		queryMap := map[string]interface{}{
 			"id":      id,
 			"user_id": qutil.ObjToString((*res)["user_id"]),
 		}
+		expiration_bl := false
+		//判断活动到期时间
+		if (*res)["expiration_time"] != nil { //该字段只有限时活动订单才有
+			expiration_time, _ := time.ParseInLocation(qutil.Date_Full_Layout, qutil.ObjToString((*res)["expiration_time"]), time.Local)
+
+			if expiration_time.Unix() < now_time_stamp {
+				expiration_bl = true
+			}
+		}
+
 		//如果超过48小时 取消订单  创建48小时后的时间戳<当前时间戳
-		if create_time_stamp < now_time_stamp {
+		if create_time_stamp < now_time_stamp || expiration_bl {
 			flag := false
 			if qutil.IntAll((*res)["order_status"]) == 0 && qutil.ObjToString((*res)["pay_way"]) != "transferAccounts" { //未支付状态下 删除订单需要先关闭订单
 				flag = pay.CloseDataExportOrder(qutil.ObjToString((*res)["pay_way"]), qutil.ObjToString((*res)["out_trade_no"]), qutil.ObjToString((*res)["prepay_time"]))
@@ -741,7 +763,7 @@ func FortyEightHoursCancel(order string, create_time_stamp, now_time_stamp int64
 	}
 }
 
-//判断用户购买的企业商机管理是否显示续费按钮	--返回值第一个参数 是判断是否显示续费按钮 第二个参数 是判断是否显示再次购买按钮
+// 判断用户购买的企业商机管理是否显示续费按钮	--返回值第一个参数 是判断是否显示续费按钮 第二个参数 是判断是否显示再次购买按钮
 func isEntExpire(userid, order_code string) (bool, bool) {
 	list := util.Mysql.FindOne("dataexport_order", bson.M{"order_code": order_code}, "filter_id", "")
 	if list != nil {
@@ -790,12 +812,12 @@ func (o *OrderListDetails) IsOver() {
 	ischanged, _ := o.GetBool("ischanged")
 	t := time.Now().AddDate(0, 0, -90).Format(qutil.Date_Full_Layout)
 	if !ischanged {
-		if util.Mysql.CountBySql(`select count(1) as count from dataexport_order 
+		if util.Mysql.CountBySql(`select count(1) as count from dataexport_order
 								where user_id = ? and pay_time > ? and order_code = ? and applybill_status = ? `, userid, t, order_code, 0) > 0 {
 			status = 1
 		}
 	} else {
-		if util.Mysql.CountBySql(`select count(1) as count from dataexport_order 
+		if util.Mysql.CountBySql(`select count(1) as count from dataexport_order
 								where user_id = ? and pay_time > ? and order_code = ?`, userid, t, order_code) > 0 {
 			status = 1
 		}
@@ -807,34 +829,30 @@ func (o *OrderListDetails) IsOver() {
 	return
 }
 
-//大会员详情订单(AI中标预测包订单详情也查询此接口)
+// 大会员详情订单(AI中标预测包订单详情也查询此接口)
 func (o *OrderListDetails) GetMemberDetail() {
+	userId := qutil.ObjToString(o.GetSession("userId"))
 	fields := "id,order_code,order_status,create_time,pay_time,pay_way,out_trade_no,prepay_id,product_type,pay_money,order_money,filter,applybill_type,applybill_taxnum,applybill_company,applybill_status,vip_starttime,vip_endtime,course_status,is_backstage_order,return_status,billingMode,discount_price"
-	data, _, _ := o.CommonDetail(0, fields)
+	data, _, _ := CommonDetail(0, fields, userId, o.GetString("order_code"))
 	o.ServeJson(map[string]interface{}{
 		"data": data,
 	})
 }
 
 func (o *OrderListDetails) GetBidfileDetail() {
+	userId := qutil.ObjToString(o.GetSession("userId"))
 	fields := "id,order_code,order_status,create_time,pay_time,pay_way,out_trade_no,prepay_id,product_type,pay_money,order_money,filter,applybill_type,applybill_taxnum,applybill_company,applybill_status,vip_starttime,vip_endtime,course_status,discount_price,d_relation_id"
-	data, _, _ := o.CommonDetail(1, fields)
+	data, _, _ := CommonDetail(1, fields, userId, o.GetString("order_code"))
 	o.ServeJson(map[string]interface{}{
 		"data": data,
 	})
 }
 
 //bigm:0大会员订单详情页 1剑鱼币订单 3企业商机管理详情页 4订单数据展示(订单详情页面)
-func (o *OrderListDetails) CommonDetail(bigm int, fields string) (data, time map[string]interface{}, transaction_id string) {
-	userId := qutil.ObjToString(o.GetSession("userId"))
+func CommonDetail(bigm int, fields, userId, order_code string) (data, time map[string]interface{}, transaction_id string) {
+	//userId := qutil.ObjToString(o.GetSession("userId"))
 	data = map[string]interface{}{}
 	if userId != "" {
-		var order_code string
-		if bigm == 4 {
-			order_code = o.GetString("orderCode")
-		} else {
-			order_code = o.GetString("order_code")
-		}
 		if order_code != "" {
 			info := map[string]interface{}{}
 			info["order_code"] = order_code
@@ -981,7 +999,7 @@ func GetEntOrdercode(query map[string]interface{}, entid []int) []string {
 	return entordercode
 }
 
-//判断数组是否包含
+// 判断数组是否包含
 func IsContain(slice []string, s string) bool {
 	for _, qq := range slice {
 		if qq == s {
@@ -991,7 +1009,7 @@ func IsContain(slice []string, s string) bool {
 	return false
 }
 
-//去重
+// 去重
 func deleteRepeat(slice []int) []int {
 	m := make(map[int]int)
 	slice_repeat := []int{}

+ 2 - 2
src/jfw/modules/subscribepay/src/service/payCallback.go

@@ -174,7 +174,7 @@ func (a *PayCallBackAction) AliPayCallback() {
 			qutil.ObjToString(checkSign.Get("gmt_payment")),
 			qutil.ObjToString(checkSign.Get("trade_no")),
 			"",
-			"",
+			pay.GetCacheOrderCode(qutil.ObjToString(checkSign.Get("out_trade_no"))),
 		}
 		outTradeno := thisParam.OutTradeno
 		if devTradenoSign := qutil.ObjToString(config.PayConf["devTradenoSign"]); devTradenoSign != "" {
@@ -273,7 +273,7 @@ func (p *PayCallBackAction) WxPayCallback() {
 		qutil.ObjToString(ret["time_end"]),
 		qutil.ObjToString(ret["transaction_id"]),
 		qutil.ObjToString(ret["openid"]),
-		"",
+		pay.GetCacheOrderCode(qutil.ObjToString(ret["out_trade_no"])),
 	}
 	outTradeno := thisParam.OutTradeno
 	if devTradenoSign := qutil.ObjToString(config.PayConf["devTradenoSign"]); devTradenoSign != "" {

+ 575 - 0
src/jfw/modules/subscribepay/src/service/salesCreateOrder.go

@@ -0,0 +1,575 @@
+package service
+
+import (
+	. "api"
+	"config"
+	"encoding/base64"
+	"encoding/json"
+	"entity"
+	"errors"
+	"fmt"
+	"github.com/SKatiyar/qr"
+	"github.com/go-xweb/xweb"
+	"go.mongodb.org/mongo-driver/bson"
+	"log"
+	"net/url"
+	"pay"
+	qutil "qfw/util"
+	"qfw/util/jy"
+	"qfw/util/redis"
+	"strconv"
+	"time"
+	"util"
+)
+
+type SalesCreateOrder struct {
+	*xweb.Action
+	createBySeller    xweb.Mapper `xweb:"/free/seller/createOrder"`           //销售代用户下单-创建订单
+	wxPaymentPage     xweb.Mapper `xweb:"/free/seller/wxPaymentPage"`         //销售代用户下单-无身份微信订单页面
+	getOrderPayAllMsg xweb.Mapper `xweb:"/free/seller/getOrderPayAllMsg"`     //销售代用户下单-获取订单详情
+	getCommonPayParam xweb.Mapper `xweb:"/free/seller/getCommonPayParam"`     //销售代用户下单-获取支付参数
+	isPaySuccess      xweb.Mapper `xweb:"/free/seller/isPaySuccess"`          //销售代用户下单-是否支付成功
+	getSubBuyMsg      xweb.Mapper `xweb:"/free/seller/svip/getSubBuyMsg"`     //超级订阅-获取已购买信息
+	getPrice          xweb.Mapper `xweb:"/free/seller/svip/getPrice"`         //超级订阅-获取超级订阅价格
+	getSelectPrice    xweb.Mapper `xweb:"/free/seller/svip/getSelectPrice"`   //超级订阅-获取选择价格
+	getValuationList  xweb.Mapper `xweb:"/free/seller/svip/getValuationList"` //超级订阅-计价清单
+
+	//tokenShow xweb.Mapper `xweb:"/free/seller/tokenShow"` //超级订阅-获取选择价格
+}
+
+func (this *SalesCreateOrder) TokenShow() {
+	vmap := map[string]interface{}{}
+	for key := range this.Request.Form {
+		value := this.Request.Form.Get(key)
+		if key != "token" {
+			vmap[key] = value
+		} else {
+			userid, sellPName, sellPid, sellData, err := util.SellerTokenDecrypt(value)
+			if err != nil {
+				vmap[key] = err.Error()
+				continue
+			}
+			vmap[key] = map[string]interface{}{
+				"userid":    userid,
+				"sellPName": sellPName,
+				"sellPid":   sellPid,
+				"sellData":  sellData,
+			}
+		}
+	}
+	this.ServeJson(vmap)
+}
+
+// CreateBySeller 销售为用户创建订单
+// 逻辑和Createorder 一致
+// 无用户身份,额外赠送
+func (this *SalesCreateOrder) CreateBySeller() {
+	var userid string
+	rData, errMsg := func() (interface{}, error) {
+		//参数接收
+		infoMap := map[string]interface{}{}
+		body := xweb.FilterXSS(string(this.Body()))
+		//接收参数
+		_ = json.Unmarshal([]byte(body), &infoMap)
+		if len(infoMap) == 0 {
+			return nil, fmt.Errorf("无效参数")
+		}
+		//解密请求参数
+		userid, sellPName, sellPid, sellData, err := util.SellerTokenDecrypt(qutil.ObjToString(infoMap["token"]))
+		if err != nil {
+			return nil, err
+		}
+		//产品类型
+		product, _ := infoMap["product"].(string)
+		if product != "VIP订阅" { //目前仅超级订阅
+			return nil, fmt.Errorf("请求产品类型有误")
+		}
+		productId := strconv.Itoa(qutil.IntAll(infoMap["productId"]))
+
+		//
+		data, _ := infoMap["data"].(map[string]interface{})
+		if len(data) <= 0 {
+			return nil, fmt.Errorf("无效参数")
+		}
+
+		//获取卡券相关
+		lotteryId := qutil.ObjToString(data["lotteryId"]) //卡卷信息的id
+		i_discountId := qutil.IntAll(data["discountId"])  //赠品相关
+		discountId := strconv.Itoa(i_discountId)
+		inserMap, msg := entity.JyCommonOrderStruct.InserMap(product, productId, userid, lotteryId, discountId, data)
+		//错误信息
+		if msg != "" {
+			return nil, fmt.Errorf(msg)
+		}
+		//销售额外赠送
+		if product == "VIP订阅" && len(sellData) > 0 {
+			tt := qutil.IntAll(sellData["tt"])
+			tn := qutil.IntAll(sellData["tn"])
+			if inserMap.VipEndTime != "" {
+				endTime, _ := time.ParseInLocation(qutil.Date_Full_Layout, inserMap.VipEndTime, time.Local)
+				if tt == 1 {
+					endTime = endTime.AddDate(0, 0, tn)
+				} else if tt == 2 {
+					endTime = endTime.AddDate(0, tn, 0)
+				}
+				inserMap.VipEndTime = endTime.Format(qutil.Date_Full_Layout)
+			}
+
+			filterMap := map[string]interface{}{}
+			if err := json.Unmarshal([]byte(inserMap.Filter), &filterMap); err != nil {
+				return nil, fmt.Errorf("创建订单异常Unmarshal")
+			}
+
+			if inserMap.VipType != 2 {
+				filterMap["seller_give_type"] = tt
+				filterMap["seller_give_cycle"] = tn
+			}
+
+			bb, err := json.Marshal(filterMap)
+			if err != nil {
+				return nil, fmt.Errorf("创建订单异常-Marshal")
+			}
+			inserMap.Filter = string(bb)
+		}
+
+		now := time.Now()
+		insertM := map[string]interface{}{
+			"order_money":          inserMap.OrderMoney,
+			"order_status":         inserMap.OrderStatus,
+			"service_status":       inserMap.ServiceStatus,
+			"user_phone":           inserMap.UserPhone,
+			"order_code":           inserMap.OrderCode,
+			"product_type":         product,
+			"create_time":          qutil.FormatDate(&now, qutil.Date_Full_Layout),
+			"original_price":       inserMap.OriginalPrice,
+			"user_id":              userid,
+			"filter":               inserMap.Filter,
+			"discount_price":       inserMap.DiscountPrice,
+			"d_relation_id":        inserMap.DrelationId,
+			"data_spec":            inserMap.DataSpec,
+			"user_mail":            inserMap.UserMail,
+			"data_count":           inserMap.DataCount,
+			"filter_publishtime":   inserMap.FilterPublishtime,
+			"is_backstage_order":   1,
+			"filter_keys":          inserMap.FilterKeys,
+			"download_url":         inserMap.DownloadUrl,
+			"dis_word":             inserMap.DisWord,
+			"distribution_channel": "x020",
+			"order_channel":        "xdqd04",  //下单渠道-启明星后台销售创建
+			"salesperson":          sellPName, //销售人员
+			"salesperson_id":       sellPid,   //销售人员id
+		}
+
+		if inserMap.VipStartTime != "" && inserMap.VipEndTime != "" {
+			insertM["vip_starttime"] = inserMap.VipStartTime
+			insertM["vip_endtime"] = inserMap.VipEndTime
+		}
+		if inserMap.PrepayTime != "" {
+			insertM["prepay_time"] = inserMap.PrepayTime
+		}
+		if inserMap.PayWay != "" {
+			insertM["pay_way"] = inserMap.PayWay
+		}
+		if inserMap.PrepayId != "" {
+			insertM["prepay_id"] = inserMap.PrepayId
+		}
+		if inserMap.FilterId != "" {
+			insertM["filter_id"] = inserMap.FilterId
+		}
+		if inserMap.VipType != 0 {
+			insertM["vip_type"] = inserMap.VipType
+		}
+
+		orderid := util.Mysql.Insert("dataexport_order", insertM)
+		if orderid <= 0 {
+			return nil, fmt.Errorf("创建订单异常")
+		}
+		//发送站内信
+		pcUrl := fmt.Sprintf(config.Config.WebSiteParameter.Link, inserMap.OrderCode)
+		appUrl := fmt.Sprintf(config.Config.WebSiteParameter.AndroidUrl, inserMap.OrderCode)
+		wxUrl := fmt.Sprintf(config.Config.WebSiteParameter.WeChatUrl, inserMap.OrderCode)
+		go util.SendStationMessages(config.Config.WebSiteParameter.Addr, userid, config.Config.WebSiteParameter.Action,
+			"1", config.Config.WebSiteParameter.Title, config.Config.WebSiteParameter.Content,
+			pcUrl, appUrl, appUrl, wxUrl, qutil.InterfaceToStr(orderid))
+
+		if i_discountId > 0 {
+			go util.FindUserLotteryId(userid, orderid, i_discountId)
+		}
+		rdata := map[string]interface{}{"order_code": inserMap.OrderCode, "needPay": !inserMap.UnNeedPay}
+		return rdata, nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s CreateBySeller 异常:%s\n", userid, errMsg.Error())
+	}
+	//创建完订单后更新卡券信息
+	this.ServeJson(NewResult(rData, errMsg))
+}
+
+// WxPaymentPage
+// 微信支付将openid添加至token
+// 并重定向至指定url
+func (this *SalesCreateOrder) WxPaymentPage() error {
+	stateKey := this.GetString("state")
+	if (this.GetString("href") == "" || this.GetString("token") == "") &&
+		stateKey == "" {
+		return this.WriteBytes([]byte("请求异常"))
+	}
+	param := this.Request.Form
+	if stateKey == "" { //公众号回调
+		stateKey = func() string {
+			return fmt.Sprintf("%s_%s", time.Now().Format("20060102150405"), qutil.GetLetterRandom(5))
+		}()
+		redis.Put("other", stateKey, param, 60*5) //存储信息
+		return this.Redirect(fmt.Sprintf(config.Wxoauth, url.QueryEscape(this.Site()+this.Url()), stateKey), 302)
+	}
+	//获取wx跳转前参数
+	if redisValue := redis.Get("other", stateKey); redisValue != nil {
+		if t, ok := redisValue.(url.Values); ok {
+			param = t
+		}
+	}
+	//获取用户openid
+	openid := util.Getopenid(this.GetString("code"))
+	if openid == "" {
+		return this.WriteBytes([]byte("获取用户身份异常"))
+	}
+	userid, sellPName, sellPid, sellData, err := util.SellerTokenDecrypt(param.Get("token"))
+	if err != nil {
+		return this.WriteBytes([]byte(err.Error()))
+	}
+	sellData["openid"] = openid
+	toHref := param.Get("href")
+	param.Set("token", util.GetSellerToken(userid, sellPName, sellPid, sellData)) //更新token
+	for _, key := range []string{"state", "code", "href"} {
+		param.Del(key)
+	}
+	return this.Redirect(toHref+"?"+param.Encode(), 302)
+}
+
+// GetCommonPayParam 销售为用户创建订单
+// 逻辑和commonAction.go GetCommonPayParam 一致
+func (this *SalesCreateOrder) GetCommonPayParam() {
+	orderCode := this.GetString("orderCode")
+	//userId := qutil.ObjToString(this.GetSession("userId"))
+	payway_req := this.GetString("payway")
+	var userId string
+	r := func() *entity.FuncResult {
+		//解密请求参数
+		userId, _, _, desc, err := util.SellerTokenDecrypt(this.GetString("token"))
+		if err != nil {
+			return &entity.FuncResult{false, err, nil}
+		}
+		query := map[string]interface{}{
+			"user_id":       userId,
+			"order_code":    orderCode,
+			"order_channel": "xdqd04", //仅查询销售创建订单
+			"order_status":  0,
+		}
+		oData := util.Mysql.FindOne("dataexport_order", query, "id,code_url,prepay_time,pay_way,order_money,product_type,out_trade_no,course_status", "")
+		if oData == nil || len(*oData) == 0 {
+			return &entity.FuncResult{false, errors.New("未知订单"), nil}
+		}
+		//对公转账审核中
+		if qutil.IntAll((*oData)["course_status"]) == 2 || qutil.IntAll((*oData)["course_status"]) == 4 {
+			return &entity.FuncResult{false, errors.New("转账审核中,请勿重复支付"), nil}
+		}
+		payParam := qutil.ObjToString((*oData)["code_url"])
+		payway := qutil.ObjToString((*oData)["pay_way"])
+		totalfee := qutil.IntAll((*oData)["order_money"])
+		//上次订单支付串是否可用
+		if prepayTime, err := time.ParseInLocation(qutil.Date_Full_Layout, qutil.ObjToString((*oData)["prepay_time"]), time.Local); err == nil && payParam != "" && payway != "wx_js" { //微信公众号支付需要openid,不通账户支付不能通用
+			if time.Now().Before(prepayTime.Add(time.Hour * 2)) { //支付串未过期
+				if payway == payway_req {
+					if payParam != "" {
+						return &entity.FuncResult{true, nil, map[string]interface{}{
+							"orderCode": orderCode,
+							"res":       payParam,
+							"price":     totalfee,
+							"timeout":   prepayTime.Unix() + 2*60*60 - time.Now().Unix(),
+							"payWay":    payway}}
+					}
+				} else {
+					//关闭之前支付串(防止重复支付)
+					if !pay.CloseOrder(qutil.ObjToString((*oData)["out_trade_no"]), payway) {
+						log.Printf("SalesCreateOrder GetCommonPayParam 关闭订单%s出错\n", orderCode)
+						return &entity.FuncResult{false, errors.New("支付方式切换异常"), nil}
+					}
+				}
+			}
+		}
+		openid := ""
+		if payway_req == "wx_js" {
+			if openid, _ = desc["openid"].(string); openid == "" {
+				return &entity.FuncResult{false, fmt.Errorf("微信支付缺少参数"), nil}
+			}
+		} //重新生成支付串
+		productFlag, ok := pay.PayWayAndSign[qutil.ObjToString((*oData)["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(), openid, payway_req, orderCode)
+		if err != nil {
+			return &entity.FuncResult{false, errors.New(fmt.Sprintf("创建支付失败[%v]", err)), nil}
+		}
+		//更新订单表
+		now := time.Now()
+		ok = util.Mysql.Update("dataexport_order", query, map[string]interface{}{
+			"code_url":     payParam,
+			"prepay_time":  qutil.FormatDate(&now, qutil.Date_Full_Layout),
+			"out_trade_no": tradeno,
+			"prepay_id":    prepayid,
+			"pay_way":      payway_req,
+		})
+		if !ok {
+			return &entity.FuncResult{false, errors.New("数据库操作异常"), nil}
+		}
+		return &entity.FuncResult{true, nil, map[string]interface{}{
+			"orderCode": orderCode,
+			"res":       payParam,
+			"price":     totalfee,
+			"timeout":   2 * 60 * 60,
+			"payWay":    payway_req}}
+	}()
+	if r.Err != nil {
+		log.Printf("%s SalesCreateOrder GetCommonPayParam err:%v\n", userId, r.Err.Error())
+	}
+	if payway_req == "wx_pc" && r.Data["res"] != nil {
+		rEncode, _ := qr.Encode(qutil.ObjToString(r.Data["res"]), qr.M)
+		pngdat := rEncode.PNG()
+		r.Data["res"] = base64.StdEncoding.EncodeToString(pngdat)
+	}
+	this.ServeJson(r.Format())
+}
+
+func (this *SalesCreateOrder) IsPaySuccess() {
+	defer qutil.Catch()
+	var userId string
+	rMap, err := func() (rData map[string]interface{}, err error) {
+		code := this.GetString("code")
+		userId, _, _, _, err = util.SellerTokenDecrypt(this.GetString("token"))
+		if err != nil {
+			return nil, err
+		}
+		if code != "" && userId != "" {
+			data := util.Mysql.FindOne("dataexport_order", map[string]interface{}{
+				"order_code":    code,
+				"user_id":       userId,
+				"order_channel": "xdqd04",
+			}, "order_status,pay_time,user_mail,pay_way,pay_money,filter", "")
+			if data != nil && qutil.IntAll((*data)["order_status"]) == 1 {
+				t, _ := time.ParseInLocation(qutil.Date_Full_Layout, qutil.ObjToString((*data)["pay_time"]), time.Local)
+				return map[string]interface{}{
+					"success":   true,
+					"email":     qutil.ObjToString((*data)["user_mail"]),
+					"payTime":   t.Unix(),
+					"pay_way":   (*data)["pay_way"],
+					"price":     (*data)["pay_money"],
+					"filter":    (*data)["filter"],
+					"orderCode": code,
+				}, nil
+			}
+		}
+		rData["success"] = false
+		return
+	}()
+	if err != nil {
+		log.Printf("%s SalesCreateOrder IsPaySuccess err:%v\n", userId, err.Error())
+	}
+	this.ServeJson(rMap)
+}
+
+// GetSubBuyMsg 获取购买订阅相关信息
+// 逻辑和vipSubscribeChange.go getSubBuyMsg 一致
+func (this *SalesCreateOrder) GetSubBuyMsg() {
+	var userId string
+	r := func() *entity.FuncResult {
+		userId, _, _, _, err := util.SellerTokenDecrypt(this.GetString("token"))
+		if err != nil {
+			return &entity.FuncResult{false, err, nil}
+		}
+		rData, buyset, vip := entity.JyVipSubStruct.GetVipDetail(userId)
+		if rData == nil || len(*rData) == 0 {
+			return &entity.FuncResult{false, errors.New("获取信息失败"), nil}
+		}
+		var isread = false
+		if (*rData)["isread"] != nil {
+			isread = (*rData)["isread"].(bool)
+		}
+		o_vipjy := qutil.ObjToMap((*rData)["o_vipjy"])
+		vipStatus := qutil.IntAll((*rData)["i_vip_status"])
+		var renewList *[]map[string]interface{}
+		if vipStatus == 2 { //查询是否有未执行的续费订单
+			renewList, _ = util.MQFW.Find("vip_upgrade", &bson.M{"s_userid": userId, "i_isvalid": 0}, `{"l_validtime":1}`, `{"o_buyset":1,"l_validtime":1}`, false, -1, -1)
+			for i := 0; i < len(*renewList); i++ {
+				delete((*renewList)[i], "_id")
+			}
+		}
+		bigPower := jy.GetBigVipUserBaseMsg(userId, util.Mysql, util.MQFW)
+		return &entity.FuncResult{true, nil, map[string]interface{}{
+			"isTrial":         vipStatus == 1,
+			"area":            (*o_vipjy)["o_area"],
+			"industry":        (*o_vipjy)["a_buyerclass"],
+			"buyset":          buyset,
+			"renewList":       renewList,
+			"infotype":        (*o_vipjy)["a_infotype"],
+			"items":           (*o_vipjy)["a_items"],
+			"projectmatch":    (*o_vipjy)["i_projectmatch"],
+			"ratemode":        (*o_vipjy)["i_ratemode"],
+			"matchway":        (*o_vipjy)["i_matchway"],
+			"startTime":       (*rData)["l_vip_starttime"],
+			"endTime":         (*rData)["l_vip_endtime"],
+			"otherbuyerclass": (*o_vipjy)["i_matchbuyerclass_other"],
+			"isread":          isread,
+			"isvip":           vip,
+			"isnew":           NewUserByVIP(userId), //免费订阅区分新老用户
+			"isUpgrade":       bigPower.IsUpgrade,
+		}}
+	}()
+	if r.Err != nil {
+		log.Printf("%s SalesCreateOrder  GetSubBuyMsg err:%v\n", userId, r.Err.Error())
+	}
+	this.ServeJson(r.Format())
+}
+
+// GetSelectPrice 计算价格
+// 复制 vipSubscribePay.go getSelectPrice
+func (this *SalesCreateOrder) GetSelectPrice() {
+	var userId string
+	r := func() *entity.FuncResult {
+		userId, _, _, _, err := util.SellerTokenDecrypt(this.GetString("token"))
+		if err != nil {
+			return &entity.FuncResult{false, err, nil}
+		}
+		area := qutil.ObjToMap(this.GetString("area")) //地区
+		timeRenew := this.GetString("time")            //周期
+		orderType, _ := this.GetInteger("orderType")   //1 购买;2 续费;3 升级
+		//卡卷信息的id
+		lotteryId := this.GetString("lotteryId")
+		useProduct, _ := this.GetInteger("useProduct")
+		return CommonBilling(area, timeRenew, userId, lotteryId, orderType, useProduct)
+	}()
+	if r.Err != nil {
+		log.Printf("%s 价格计算 err:%v\n", userId, r.Err.Error())
+	}
+	this.ServeJson(r.Format())
+}
+
+// GetValuationList 订单详情-计价清单
+// 逻辑与 orderListDetails.go GetValuationList保持一致
+func (this *SalesCreateOrder) GetValuationList() {
+	var userId string
+	r, err := func() (map[string]interface{}, error) {
+		userId, _, _, _, err := util.SellerTokenDecrypt(this.GetString("token"))
+		if err != nil {
+			return nil, err
+		}
+		order_code := this.GetString("order_code")
+		upgradeSubtotail := []map[string]interface{}{}
+		queryMap := map[string]interface{}{
+			"order_code": order_code,
+			"user_Id":    userId,
+		}
+		filter := util.Mysql.FindOne(tableName_order, queryMap, "filter,order_money", "")
+		if filter == nil {
+			return nil, fmt.Errorf("未知订单")
+		}
+		res := qutil.ObjToMap((*filter)["filter"])
+		upgradeSubtotail = qutil.ObjArrToMapArr((*res)["upgradeSubtotail"].([]interface{}))
+		if len(upgradeSubtotail) > 0 {
+			for _, v := range upgradeSubtotail {
+				//续费 没有oldBuyset
+				if v["oldBuyset"] == nil {
+					v["oldBuyset"] = (*res)["newBuyset"]
+				}
+			}
+		}
+		return map[string]interface{}{
+			"list":        upgradeSubtotail,
+			"order_money": (*filter)["order_money"],
+		}, nil
+	}()
+	if err != nil {
+		log.Printf("%s 价格计算 err:%v\n", userId, r)
+	}
+	this.ServeJson(r)
+}
+
+// GetPrice 销售代下单 支付价格
+// 逻辑和vipSubscribeChange.go GetPrice 一致
+func (this *SalesCreateOrder) GetPrice() {
+	res := map[string]interface{}{
+		"isActiving": true,
+		"isWritten":  0,
+	}
+	j, _ := json.Marshal(&entity.SubVipPrice)
+	_ = json.Unmarshal(j, &res)
+	userId, _, _, _, _ := util.SellerTokenDecrypt(this.GetString("token"))
+	if userId != "" {
+		data, ok := util.MQFW.FindById("user", userId, nil)
+		if ok && data != nil && *data != nil {
+			//已录入信息 已激活大会员赠送
+			if (*data)["i_member_give"] != nil {
+				res["isWritten"] = qutil.IntAll((*data)["i_member_give"])
+			}
+		}
+	}
+	this.ServeJson(res)
+}
+
+// GetOrderPayAllMsg 代付订单详情页
+func (o *SalesCreateOrder) GetOrderPayAllMsg() {
+	order_code := o.GetString("orderCode")
+	token := o.GetString("token")
+
+	data := map[string]interface{}{}
+	var (
+		r             entity.FuncResult
+		transactionId string
+	)
+	t := make(map[string]interface{})
+	if order_code != "" && token != "" {
+		fields := "order_code,user_id"
+		info := map[string]interface{}{}
+		userId, _, _, _, err := util.SellerTokenDecrypt(token)
+		if err != nil {
+			r.Err = errors.New("获取订单信息失败")
+			goto env
+		}
+		info["order_code"] = order_code
+		info["user_id"] = userId
+		info["order_channel"] = "xdqd04"
+		dataMap := util.Mysql.FindOne(tableName_order, info, fields, "")
+		if dataMap != nil && len(*dataMap) > 0 {
+			data = *dataMap
+			//查询userid
+			//userId := qutil.InterfaceToStr(data["user_id"])
+			//if userId == "" {
+			//	r.Err = errors.New("获取订单信息失败")
+			//	goto env
+			//}
+			field := "id,order_code,del_status,prepay_time,create_time,pay_time,pay_way,user_phone,original_price,order_money,pay_money,applybill_status,out_trade_no,filter,product_type,order_status,applybill_type,applybill_taxnum,applybill_company,vip_starttime,vip_endtime,vip_type,discount_price,d_relation_id,billingMode,return_status,is_backstage_order,vip_starttime,vip_endtime"
+			data, t, transactionId = CommonDetail(4, field, userId, order_code)
+			//如果手机号号为空查找通过userid查找手机号
+			//if qutil.InterfaceToStr(data["user_phone"]) == "" {
+			dataPhone, _ := util.MQFW.FindById("user", userId, "s_phone,s_m_phone")
+			sPhone := qutil.InterfaceToStr((*dataPhone)["s_phone"])
+			data["user_phone"] = qutil.If(sPhone == "", qutil.InterfaceToStr((*dataPhone)["s_m_phone"]), sPhone)
+			dataMapSta := make(map[string]interface{})
+			if qutil.IntAll(data["del_status"]) == 1 || qutil.IntAll(data["order_status"]) == -1 {
+				dataMapSta["del_status"] = qutil.IntAll(data["del_status"])
+				dataMapSta["order_status"] = qutil.IntAll(data["order_status"])
+			} else {
+				dataMapSta = data
+			}
+			//}
+			r.Success = true
+			r.Data = map[string]interface{}{
+				"order":          dataMapSta,
+				"time":           t,
+				"transaction_id": transactionId,
+			}
+		}
+	}
+env:
+	o.ServeJson(r.Format())
+}

+ 8 - 7
src/jfw/modules/subscribepay/src/service/userAccountInfo.go

@@ -68,17 +68,18 @@ func (this *UserAccount) GetSimpleData() {
 	if headImage == "" {
 		headImage = this.GetSession("s_headimageurl")
 	}
-	nickname, _ := this.GetSession("phone").(string)
-	if nickname == "" {
-		nickname, _ = qutil.If(this.GetSession("s_nickname") != nil, this.GetSession("s_nickname"), this.GetSession("app_name")).(string)
-	} else {
-		if jy.IsPhone(nickname) {
-			nickname = string(nickname[0:3]) + "****" + string(nickname[(len(nickname)-4):])
+	phone, _ := this.GetSession("phone").(string)
+	name, _ := qutil.If(this.GetSession("s_nickname") != nil, this.GetSession("s_nickname"), this.GetSession("app_name")).(string)
+	if phone != "" {
+		if jy.IsPhone(phone) {
+			phone = string(phone[0:3]) + "****" + string(phone[(len(phone)-4):])
 		}
 	}
 	this.ServeJson(map[string]interface{}{
 		"userId":    qutil.EncodeArticleId(qutil.ObjToString(this.GetSession("userId"))),
-		"nickName":  nickname,
+		"nickName":  qutil.If(phone != "", phone, name).(string),
+		"phone":     phone,
+		"name":      name,
 		"headImage": headImage,
 	})
 }

+ 2 - 0
src/jfw/modules/subscribepay/src/service/vipSubscribeChange.go

@@ -54,6 +54,7 @@ func (this *SubscribeChange) GetSubBuyMsg() {
 				delete((*renewList)[i], "_id")
 			}
 		}
+		bigPower := jy.GetBigVipUserBaseMsg(userId, util.Mysql, util.MQFW)
 		return &entity.FuncResult{true, nil, map[string]interface{}{
 			"isTrial":         vipStatus == 1,
 			"area":            (*o_vipjy)["o_area"],
@@ -72,6 +73,7 @@ func (this *SubscribeChange) GetSubBuyMsg() {
 			"isvip":           vip,
 			"isnew":           NewUserByVIP(userId), //免费订阅区分新老用户
 			"key_max_length":  qutil.If(vip, config.Config.VipKeyMaxLength, 10),
+			"isUpgrade":       bigPower.IsUpgrade,
 		}}
 	}()
 	if r.Err != nil {

+ 74 - 66
src/jfw/modules/subscribepay/src/service/vipSubscribePay.go

@@ -40,80 +40,88 @@ func (this *SubVipPayOrder) GetSelectPrice() {
 		area := qutil.ObjToMap(this.GetString("area")) //地区
 		timeRenew := this.GetString("time")            //周期
 		orderType, _ := this.GetInteger("orderType")   //1 购买;2 续费;3 升级
-		// 原价;订单价
-		original_price, order_price := 0, 0
-		userMsg := jy.GetBigVipUserBaseMsg(userId, util.Mysql, util.MQFW)
-		if (userMsg.VipStatus > 0 && orderType == 1) || (userMsg.VipStatus <= 0 && (orderType == 3 || orderType == 2)) {
-			return &entity.FuncResult{false, errors.New("参数异常"), nil}
-		} else if userMsg.VipStatus <= 0 && orderType == 1 { //购买价格
+		//卡卷信息的id
+		lotteryId := this.GetString("lotteryId")
+		useProduct, _ := this.GetInteger("useProduct")
+		return CommonBilling(area, timeRenew, userId, lotteryId, orderType, useProduct)
+	}()
+	if r.Err != nil {
+		log.Printf("%s 价格计算 err:%v\n", userId, r.Err.Error())
+	}
+	this.ServeJson(r.Format())
+}
+func CommonBilling(area *map[string]interface{}, timeRenew, userId, lotteryId string, orderType, useProduct int) *entity.FuncResult {
+	//area := qutil.ObjToMap(this.GetString("area")) //地区
+	//timeRenew := this.GetString("time")            //周期
+	//orderType, _ := this.GetInteger("orderType")   //1 购买;2 续费;3 升级
+	// 原价;订单价
+	original_price, order_price := 0, 0
+	userMsg := jy.GetBigVipUserBaseMsg(userId, util.Mysql, util.MQFW)
+	if (userMsg.VipStatus > 0 && orderType == 1) || (userMsg.VipStatus <= 0 && (orderType == 3 || orderType == 2)) {
+		return &entity.FuncResult{false, errors.New("参数异常"), nil}
+	} else if userMsg.VipStatus <= 0 && orderType == 1 { //购买价格
+		date_count, date_unit, err := entity.JyVipSubStruct.CheckReqDate(timeRenew)
+		if err != nil {
+			return &entity.FuncResult{false, err, nil}
+		}
+		buyset := entity.JyVipSubStruct.NewBuySet(area, nil, true) //改版后只能购买升级版超级订阅
+		//计算价格
+		original_price = entity.JyVipSubStruct.GetSubVipPrice(buyset, date_count, date_unit)
+	} else if userMsg.VipStatus > 0 { //2:续费价格(只延长时间);3:升级价格(升级只升级地区)
+		rData, oldBuyset, _ := entity.JyVipSubStruct.GetVipDetail(userId)
+		switch orderType {
+		case 2:
+			now := time.Now()
 			date_count, date_unit, err := entity.JyVipSubStruct.CheckReqDate(timeRenew)
 			if err != nil {
 				return &entity.FuncResult{false, err, nil}
 			}
-			buyset := entity.JyVipSubStruct.NewBuySet(area, nil, true) //改版后只能购买升级版超级订阅
-			//计算价格
-			original_price = entity.JyVipSubStruct.GetSubVipPrice(buyset, date_count, date_unit)
-		} else if userMsg.VipStatus > 0 { //2:续费价格(只延长时间);3:升级价格(升级只升级地区)
-			rData, oldBuyset, _ := entity.JyVipSubStruct.GetVipDetail(userId)
-			switch orderType {
-			case 2:
-				now := time.Now()
-				date_count, date_unit, err := entity.JyVipSubStruct.CheckReqDate(timeRenew)
-				if err != nil {
-					return &entity.FuncResult{false, err, nil}
-				}
-				endUnix := qutil.Int64All((*rData)["l_vip_endtime"])
-				isTrail := qutil.IntAll((*rData)["i_vip_status"]) == 1
-				if time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 59, now.Location()).
-					AddDate(3, 0, 0).Before(util.GetDATE(date_unit, date_count, endUnix)) && !isTrail {
-					return &entity.FuncResult{false, errors.New("订阅周期超过三年"), nil}
-				}
-				original_price = entity.JyVipSubStruct.GetSubVipPriceByBuySet(oldBuyset, date_count, date_unit, false)
-			case 3:
-				endUnix := qutil.Int64All((*rData)["l_vip_endtime"])
-				newBuyset := entity.JyVipSubStruct.NewBuySet(area, nil, true) //改版后只能购买升级版超级订阅
-				//升级校验
-				original_price, _ = getNewUpgradeDetail(userId, newBuyset, oldBuyset, endUnix, 0, 0)
-				if original_price < 0 {
-					if original_price == -1 {
-						return &entity.FuncResult{false, errors.New("不能升级此状态"), nil}
-					} else {
-						return &entity.FuncResult{false, errors.New("查询续费订单出错"), nil}
-					}
-				}
-			}
-		}
-		order_price = original_price
-		//卡卷信息的id
-		lotteryId := this.GetString("lotteryId")
-		useProduct, _ := this.GetInteger("useProduct")
-		if lotteryId != "" {
-			products := config.CouponConfig.Products["超级订阅"]
-			if useProduct > 0 {
-				products = strconv.Itoa(useProduct)
+			endUnix := qutil.Int64All((*rData)["l_vip_endtime"])
+			isTrail := qutil.IntAll((*rData)["i_vip_status"]) == 1
+			if time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 59, now.Location()).
+				AddDate(3, 0, 0).Before(util.GetDATE(date_unit, date_count, endUnix)) && !isTrail {
+				return &entity.FuncResult{false, errors.New("订阅周期超过三年"), nil}
 			}
-			full_price, reduce_price := 0, 0
-			var discount float64
-			full_price, reduce_price, discount, _ = util.GetCouponInfo(userId, lotteryId, products)
-			if full_price <= original_price {
-				if discount == 100 { //满减
-					order_price = original_price - reduce_price
-				} else { //满折
-					disCount_int := int(math.Ceil(discount * 100))
-					order_price = original_price * disCount_int / 1000
+			original_price = entity.JyVipSubStruct.GetSubVipPriceByBuySet(oldBuyset, date_count, date_unit, false)
+		case 3:
+			endUnix := qutil.Int64All((*rData)["l_vip_endtime"])
+			newBuyset := entity.JyVipSubStruct.NewBuySet(area, nil, true) //改版后只能购买升级版超级订阅
+			//升级校验
+			original_price, _ = getNewUpgradeDetail(userId, newBuyset, oldBuyset, endUnix, 0, 0)
+			if original_price < 0 {
+				if original_price == -1 {
+					return &entity.FuncResult{false, errors.New("不能升级此状态"), nil}
+				} else {
+					return &entity.FuncResult{false, errors.New("查询续费订单出错"), nil}
 				}
 			}
 		}
-		return &entity.FuncResult{true, nil, map[string]interface{}{
-			"original_price": original_price,
-			"order_price":    order_price,
-		},
+	}
+	order_price = original_price
+	//卡卷信息的id
+	if lotteryId != "" {
+		products := config.CouponConfig.Products["超级订阅"]
+		if useProduct > 0 {
+			products = strconv.Itoa(useProduct)
+		}
+		full_price, reduce_price := 0, 0
+		var discount float64
+		full_price, reduce_price, discount, _ = util.GetCouponInfo(userId, lotteryId, products)
+		if full_price <= original_price {
+			if discount == 100 { //满减
+				order_price = original_price - reduce_price
+			} else { //满折
+				disCount_int := int(math.Ceil(discount * 100))
+				order_price = original_price * disCount_int / 1000
+			}
 		}
-	}()
-	if r.Err != nil {
-		log.Printf("%s 价格计算 err:%v\n", userId, r.Err.Error())
 	}
-	this.ServeJson(r.Format())
+	return &entity.FuncResult{true, nil, map[string]interface{}{
+		"original_price": original_price,
+		"order_price":    order_price,
+	},
+	}
+
 }
 
 //支付价格
@@ -278,7 +286,7 @@ func (this *SubVipPayOrder) CreateOrder() {
 		discountId, _ := this.GetInteger("discountId")
 		if discountId > 0 {
 			isgive = true
-			timeNum, timeType, activityName := util.GiveInfo(userId, useProduct, 0, discountId) //获取满赠时长
+			_, timeNum, timeType, _, _, _, activityName, _ := util.GiveInfo(userId, useProduct, 0, discountId) //获取满赠时长
 			filter.GiveCycle = timeNum
 			filter.GiveType = timeType
 			filter.DisCountId = discountId
@@ -434,7 +442,7 @@ func (this *SubVipPayOrder) Renew() {
 		discountId, _ := this.GetInteger("discountId")
 		useProduct, _ := this.GetInteger("useProduct")
 		if discountId > 0 && useProduct > 0 {
-			timeNum, timeType, activityName := util.GiveInfo(userId, useProduct, 0, discountId) //获取满赠时长
+			_, timeNum, timeType, _, _, _, activityName, _ := util.GiveInfo(userId, useProduct, 0, discountId) //获取满赠时长
 			filter.GiveCycle = timeNum
 			filter.GiveType = timeType
 			filter.DisCountId = discountId

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

@@ -17,5 +17,6 @@
 	"memberServiceIsExpire":"15:28",
 	"DataExportSendMailDuringMinute":1,
 	"updateDEStatus":"1h",
-	"provinceExpire":"00:00"
+	"provinceExpire":"00:00",
+	"updateTimeLimitActivityOrderStatus":"15s"
 }

+ 107 - 24
src/jfw/modules/subscribepay/src/timetask/timetask.go

@@ -1,12 +1,13 @@
 package timetask
 
 import (
+	"config"
 	. "config"
 	"encoding/hex"
 	"fmt"
 	"log"
 	. "mongodb"
-	"p"
+	p "p"
 	"pay"
 	qutil "qfw/util"
 	"qfw/util/jy"
@@ -34,7 +35,8 @@ func Run() {
 		go SendDataExportMailForPayed()
 		go updateDataExportStatus()
 		go bigMemberExpireRemind()
-		go updateProvincePackageStatus() //省份流量包
+		go updateProvincePackageStatus()        //省份流量包
+		go updateTimeLimitActitityOrderStatus() //修改限时活动的订单状态
 	}
 }
 
@@ -261,19 +263,17 @@ func checkIsExpire() {
 			time.Sleep(time.Minute)
 			sess = util.MQFW.GetMgoConn()
 		}
-		delSess := util.Mgo_log.GetMgoConn()
-		delSessErrCount := 0
-		for {
-			if delSessErrCount == 10 {
-				break
-			} else if delSess != nil {
-				defer util.Mgo_log.DestoryMongoConn(delSess)
-				break
-			}
-			delSessErrCount++
-			time.Sleep(5 * time.Second)
-			delSess = util.Mgo_log.GetMgoConn()
-		}
+		count, err := sess.DB("qfw").C("user").Find(map[string]interface{}{
+			"i_appid": 2,
+			"i_vip_status": map[string]interface{}{
+				"$gt": 0,
+			},
+			"l_vip_endtime": map[string]interface{}{
+				"$lte": now_unix + threeday,
+			},
+		}).Count()
+		log.Println("当前时间:", qutil.FormatDateByInt64(&now_unix, qutil.Date_Full_Layout), "数据总量:", count, "--err:", err)
+		var i int64 = 0
 		it := sess.DB("qfw").C("user").Find(map[string]interface{}{
 			"i_appid": 2,
 			"i_vip_status": map[string]interface{}{
@@ -284,12 +284,13 @@ func checkIsExpire() {
 			},
 		}).Select(map[string]interface{}{"i_vip_status": 1, "l_vip_endtime": 1, "i_vip_expire_tip": 1}).Iter()
 		for m := make(map[string]interface{}); it.Next(&m); {
+			i++
 			_id := BsonIdToSId(m["_id"])
 			l_vip_endtime := qutil.Int64All(m["l_vip_endtime"])
 			i_vip_status := qutil.IntAll(m["i_vip_status"])
 			i_vip_expire_tip := qutil.IntAll(m["i_vip_expire_tip"])
 			if l_vip_endtime <= now_unix {
-				util.MQFW.UpdateById("user", _id, map[string]interface{}{
+				ok := util.MQFW.UpdateById("user", _id, map[string]interface{}{
 					"$set": map[string]interface{}{
 						"i_vip_status":     -i_vip_status,
 						"i_vip_expire_tip": 2,
@@ -300,16 +301,34 @@ func checkIsExpire() {
 						"i_vip_expire_tip_retry": "",
 					},
 				})
-				if delSess != nil {
-					for _, pushColl := range []string{"pushspace", "pushspace_temp", "pushspace_vip", "pushspace_project"} {
-						_, err := delSess.DB("push").C(pushColl).RemoveAll(map[string]interface{}{"userid": _id})
-						if err != nil {
-							log.Println("用户", _id, "已到期删除", pushColl, "表数据出错", err)
-						} else {
-							log.Println("用户", _id, "已到期删除", pushColl, "表数据")
+				if !ok {
+					log.Println("用户:", _id, " 更新vip状态异常")
+				}
+				go func(_id string) {
+					delSess := util.Mgo_log.GetMgoConn()
+					delSessErrCount := 0
+					for {
+						if delSessErrCount == 10 {
+							break
+						} else if delSess != nil {
+							break
 						}
+						delSessErrCount++
+						time.Sleep(5 * time.Second)
+						delSess = util.Mgo_log.GetMgoConn()
 					}
-				}
+					if delSess != nil {
+						defer util.Mgo_log.DestoryMongoConn(delSess)
+						for _, pushColl := range []string{"pushspace", "pushspace_temp", "pushspace_vip", "pushspace_project"} {
+							_, err := delSess.DB("push").C(pushColl).RemoveAll(map[string]interface{}{"userid": _id})
+							if err != nil {
+								log.Println("用户", _id, "已到期删除", pushColl, "表数据出错", err)
+							} else {
+								log.Println("用户", _id, "已到期删除", pushColl, "表数据")
+							}
+						}
+					}
+				}(_id)
 				go jy.ClearBigVipUserPower(_id)
 				log.Println("用户", _id, i_vip_status, l_vip_endtime, "修改已到期状态")
 				redis.Del("other", "p1_indexMessage_"+_id) //清除redis中vip状态
@@ -330,6 +349,10 @@ func checkIsExpire() {
 			}
 			m = make(map[string]interface{})
 		}
+		if i != count {
+			log.Println("更新vip状态有异常,已处理:", i, "总量:", count)
+		}
+		log.Println("已处理:", i, "总量:", count)
 		log.Println("定时任务,更新vip状态结束")
 	})
 }
@@ -889,6 +912,62 @@ func checkMemberServiceIsExpire() {
 	})
 }
 
+func updateTimeLimitActitityOrderStatus() { //修改限时活动的订单状态
+	crontabByTicker(true, TimeTaskConfig.UpdateTimeLimitActivityOrderStatus, func() {
+		defer qutil.Catch()
+		log.Println("定时任务,更新限时活动订单状态开始")
+		now := time.Now().Add(-time.Duration(config.Config.ActivityOrderCountdown) * time.Minute)
+		//获取倒计时时间
+		starttime := now.Format(qutil.Date_Full_Layout)
+		limitTime := 20 //默认二十秒
+		if strings.Contains(TimeTaskConfig.UpdateTimeLimitActivityOrderStatus, "s") {
+			cStr := strings.Split(TimeTaskConfig.UpdateTimeLimitActivityOrderStatus, "s")[0]
+			limitTime, _ = strconv.Atoi(cStr)
+		}
+		endtime := now.Add(-time.Duration(limitTime) * time.Second).Format(qutil.Date_Full_Layout)
+		data := util.Mysql.SelectBySql(`select * from dataexport_order where order_status =0 and  expiration_time>=? and expiration_time<? and is_backstage_order = 0`, starttime, endtime)
+		log.Println(fmt.Sprintf(`select * from dataexport_order where order_status =0 and  expiration_time<%s and expiration_time>=%s`, starttime, endtime))
+		if data != nil && len(*data) > 0 {
+			for _, v := range *data {
+				//订单编号
+				order_code, _ := v["order_code"].(string)
+				productType := 0 //取消卡券的时候 需要这个参数  商品类型0普通的1线上课程
+				if product_type, _ := v["product_type"].(string); product_type != "中标必听课" {
+					productType = 1
+				}
+				flag := false
+				if qutil.IntAll(v["order_status"]) == 0 && qutil.IntAll(v["is_backstage_order"]) == 0 && qutil.ObjToString(v["pay_way"]) != "transferAccounts" { //未支付状态下 删除订单需要先关闭订单
+					flag = pay.CloseDataExportOrder(qutil.ObjToString(v["pay_way"]), qutil.ObjToString(v["out_trade_no"]), qutil.ObjToString(v["prepay_time"]))
+				}
+				if flag || (!(qutil.IntAll(v["course_status"]) == 2 || qutil.IntAll(v["course_status"]) == 4)) && qutil.ObjToString(v["pay_way"]) == "transferAccounts" && qutil.IntAll(v["is_backstage_order"]) == 0 { //对公转账非审核中 和 转账成功 状态下超时取消订单
+					queryMap := map[string]interface{}{
+						"order_code": order_code,
+					}
+					flag = util.Mysql.Update("dataexport_order", queryMap, map[string]interface{}{"order_status": -2})
+				}
+
+				if !flag {
+					log.Println("mysql 订单更新失败", order_code)
+				} else {
+					//解除卡卷绑定
+					//用户领取卡卷的记录id
+					userLotteryId, _ := v["d_relation_id"].(string)
+					if userLotteryId != "" {
+						//用户id
+						userId, _ := v["user_id"].(string)
+						go func(userId, userLotteryId, order_code string) {
+							if !util.UpdateCouponState(userId, userLotteryId, "", "", order_code, qutil.ObjToString(v["product_type"]), "0", 0, productType) {
+								log.Println(fmt.Sprintf("单号%s-解绑失败-卡卷%s", order_code, userLotteryId))
+							}
+						}(userId, userLotteryId, order_code)
+					}
+				}
+			}
+		}
+		log.Println("定时任务,更新限时活动订单结束")
+	})
+}
+
 //
 func clearBigVipUserPower(userId string) {
 	if userId != "" {
@@ -943,6 +1022,10 @@ func crontabByTicker(flag bool, c string, f func()) {
 		cStr := strings.Split(c, "h")[0]
 		countdown, _ = strconv.Atoi(cStr)
 		countdown = countdown * 60 * 60
+	} else if strings.Contains(c, "s") {
+		cStr := strings.Split(c, "s")[0]
+		countdown, _ = strconv.Atoi(cStr)
+		countdown = countdown
 	} else {
 		countdown, _ = strconv.Atoi(c)
 		countdown = countdown * 60

+ 37 - 6
src/jfw/modules/subscribepay/src/util/coupon.go

@@ -58,13 +58,13 @@ func GetCouponInfo(userId, lotteryId, pCode string) (full, reduce int, discount
 			//开始时间
 			lotteryBeginDate := qutil.ObjToString((*info)["LotteryBeginDate"])
 			var beginDate = time.Now().Unix()
-			if thisTime, err := time.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%s 00:00:00", lotteryBeginDate), time.Local); err == nil {
+			if thisTime, err := time.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%s", lotteryBeginDate), time.Local); err == nil {
 				beginDate = thisTime.Unix()
 			}
 			//结束时间
 			lotteryEndDate := qutil.ObjToString((*info)["LotteryendDate"])
 			var endDate = time.Now().Unix()
-			if thisTime, err := time.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%s 23:59:59", lotteryEndDate), time.Local); err == nil {
+			if thisTime, err := time.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%s", lotteryEndDate), time.Local); err == nil {
 				endDate = thisTime.Unix()
 			}
 			//未开始 已结束 则不可用
@@ -97,6 +97,7 @@ func UpdateCouponState(userId, userLotteryId, nickName, phone, orderCode, usePro
 		"useProduct":     []string{useProduct},
 		"discountId":     []string{discountId},
 	}
+	log.Println("------>", data)
 	//
 	res, err := http.PostForm(config.CouponConfig.CouponUpdate, data)
 	if err != nil {
@@ -105,6 +106,7 @@ func UpdateCouponState(userId, userLotteryId, nickName, phone, orderCode, usePro
 	}
 	defer res.Body.Close()
 	bs, _ := ioutil.ReadAll(res.Body)
+	log.Println("==>", string(bs))
 	resMap := map[string]interface{}{}
 	err = json.Unmarshal([]byte(bs), &resMap)
 	if err != nil {
@@ -125,11 +127,16 @@ return:
 	timeNum:赠送数量
 	timeType:时间类型:1/天、2/月
 	activityName:活动名称
+	promotionalPrice:促销价
+	discount:折扣
+	reduce:减免
+	activityType:活动类型
 	查看赠品天数接口
 */
-func GiveInfo(userid string, useProduct, useProductType, discountId int) (timeNum, timeType int, activityName string) {
+func GiveInfo(userid string, useProduct, useProductType, discountId int) (activityType, timeNum, timeType, promotionalPrice, reduce int, discount float64, activityName string, isUsed bool) {
 	getUrl := fmt.Sprintf("%s?useProduct=%s&appId=%s&useProductType=%v&userId=%s", config.CouponConfig.Giveinfo, strconv.Itoa(useProduct), config.CouponConfig.AppId, useProductType, userid)
 	res, err := http.Get(getUrl)
+	log.Println(discountId, getUrl)
 	if err != nil {
 		log.Println(err.Error())
 	}
@@ -144,11 +151,35 @@ func GiveInfo(userid string, useProduct, useProductType, discountId int) (timeNu
 		if qutil.IntAll(resMap["Code"]) == 1 {
 			if data, _ := resMap["Data"].([]interface{}); len(data) > 0 && data != nil {
 				m := qutil.ObjArrToMapArr(data)
+				//遍历参与活动的产品
 				for _, v := range m {
 					if qutil.IntAll(v["DiscountId"]) == discountId {
-						timeNum = qutil.IntAll(v["Time"])
-						timeType = qutil.IntAll(v["TimeType"])
-						activityName = qutil.ObjToString(v["ActivityName"])
+						//判断活动类型 类型:0满减、1折扣券、2满赠、3促销、4限时折扣、5限时减免
+						activityType = qutil.IntAll(v["ActivityType"])
+
+						isReceive, _ := v["IsReceive"].(bool)        //是否可用
+						stockNum := qutil.Int64All(v["StockNumber"]) //库存数
+						begintime, endtime := qutil.Int64All(v["BeginDate"]), qutil.Int64All(v["EndDate"])
+						now := time.Now().Unix()
+						if !isReceive || stockNum == 0 || !(now >= begintime && now < endtime) {
+							log.Println(userid, "活动暂不可用", isReceive, stockNum)
+							return
+						}
+						switch activityType {
+						case 2:
+							timeNum = qutil.IntAll(v["Time"])
+							timeType = qutil.IntAll(v["TimeType"])
+							activityName = qutil.ObjToString(v["ActivityName"])
+						case 3:
+							promotionalPrice = qutil.IntAll(v["PromotionalPrice"])
+						case 4:
+							discount = qutil.Float64All(v["Discount"])
+
+						case 5:
+							reduce = qutil.IntAll(v["Reduce"])
+						}
+						//可用
+						isUsed = true
 					}
 				}
 			}

+ 1 - 1
src/jfw/modules/subscribepay/src/util/db.go

@@ -3,7 +3,7 @@ package util
 import (
 	. "config"
 	mg "mongodb"
-	"p"
+	p "p"
 	qutil "qfw/util"
 	"qfw/util/elastic"
 	"qfw/util/mysql"

Некоторые файлы не были показаны из-за большого количества измененных файлов