Przeglądaj źródła

Merge branch 'master' into feature/v1.1.14

lianbingjie 2 lat temu
rodzic
commit
aa30ec120f

+ 39 - 8
jyBXBuyer/api/bxbuyer.api

@@ -12,20 +12,18 @@ type (
 		Province       []string `json:"province,optional"`       //省份
 		City           []string `json:"city,optional"`           //城市
 		BuyerClass     []string `json:"buyerClass,optional"`     //客户类型(采购单位行业)
-		Industry       []string `json:"industry,optional"`       //行业分类(信息行业)
 		BusinessScope  string   `json:"businessScope,optional"`  //业务范围(关键词 附加词 排除词)
 		BuyerName      string   `json:"buyerName,optional"`      //采购单位名称
 		AppId          string   `header:"appId"`                 //剑鱼10000
 		UserType       string   `path:"userType"`                //用户标签
 		IsCheckFollow  bool     `json:"isCheckFollow,optional"`  //是否查询关注信息(商机管理用户)
 		IsCheckReceive bool     `json:"isCheckReceive,optional"` //是否查询已领取(商机管理用户)
-		UserId         string   `header:"userId"`                //用户id
-		EntId          string   `header:"entId"`                 //企业id
-		EntUserId      string   `header:"entUserId"`             //商机管理企业用户id
-		Customer       []string `json:"customer,optional"`       //历史客户
-		//SortRule       int64    `json:"sortRule"`       //排序规则
-		//PageNum        int64    `json:"pageNum"`        //当前页码
-		//PageSize       int64    `json:"pageSize"`       //每页数据量
+		UserId         string   `header:"userId,optional"`       //用户id
+		EntId          string   `header:"entId,optional"`        //企业id
+		EntUserId      string   `header:"entUserId,optional"`    //商机管理企业用户id
+		IsContact      int64    `json:"isContact,optional"`      // 是否有联系人 0 不筛选 1-有联系人 2-无联系人
+		PageNum        int64    `json:"pageNum"`                 //当前页码
+		PageSize       int64    `json:"pageSize"`                //每页数据量
 	}
 	//
 	commonResp {
@@ -33,8 +31,41 @@ type (
 		Err_msg  string      `json:"error_msg"`
 		Data     interface{} `json:"data"`
 	}
+	//用户基本信息
+	baseParam {
+		EntId        int64  `header:"entId,optional"`        // 企业id
+		EntUserId    int64  `header:"entUserId,optional"`    // 企业下用户id
+		PositionType int64  `header:"positionType,optional"` // 职位类型 0个人 1企业
+		PositionId   int64  `header:"positionId,optional"`   //职位id
+		AccountId    int64  `header:"accountId,optional"`    //账户id
+		MgoUserId    string `header:"mgoUserId,optional"`    //原userId
+		AppId        string `header:"appId,optional"`        //剑鱼10000
+		UserId       string `header:"userId,optional"`       //用户id
+		NewUserId    int64  `header:"newUserId,optional"`    //base_user_id
+		EntAccountId int64  `header:"entAccountId,optional"` //企业账户id
+		Phone        string `header:"phone,optional"`
+	}
+	//采购单位关联信息
+	relatesInformationReq {
+		baseParam
+		BiddingCount int    `json:"biddingCount,optional"` //关联招标信息数量---根据采购单位
+		BuyerCount   int    `json:"buyerCount,optional"`   //关联采购单位信息---根据地区
+		Buyer        string `json:"buyer,optional"`        //采购单位
+		Area         string `json:"area,optional"`         //地区
+		City         string `json:"city,optional"`         //城市
+	}
+	// 采购单位补充信息请求参数
+	BuyerSupplyInfoReq {
+		baseParam
+		Buyer []string `json:"buyer,optional"` //采购单位
+
+	}
 )
 service bxbuyer-api {
 	@handler buyerSearchList
 	post /jybx/buyer/:userType/buyerList(buyerListReq) returns (commonResp)
+	@handler relatesInformation
+	post /jybx/buyer/relates/information(relatesInformationReq) returns (commonResp)
+	@handler buyerSupplyInfo
+	post /jybx/buyer/supply/info(BuyerSupplyInfoReq) returns (commonResp)
 }

+ 2 - 2
jyBXBuyer/api/etc/bxbuyer-api.yaml

@@ -1,7 +1,7 @@
 Name: bxbuyer-api
 Host: 0.0.0.0
 Port: 8007
-Timeout: 8000
+Timeout: 30000
 Webrpcport: 8017
 Gateway:
   ServerCode: jybxbuyer
@@ -12,7 +12,7 @@ Buyer:
     Hosts:
       - 127.0.0.1:2379
     Key: bxbuyer.rpc
-  Timeout: 8000
+  Timeout: 30000
 AppId: 10000
 MgoLogsName: jybxbuyer_logs
 MgoLogsCount: 500

+ 28 - 0
jyBXBuyer/api/internal/handler/buyerSupplyInfoHandler.go

@@ -0,0 +1,28 @@
+package handler
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+	"jyBXBuyer/api/internal/logic"
+	"jyBXBuyer/api/internal/svc"
+	"jyBXBuyer/api/internal/types"
+)
+
+func buyerSupplyInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.BuyerSupplyInfoReq
+		if err := httpx.Parse(r, &req); err != nil {
+			httpx.Error(w, err)
+			return
+		}
+
+		l := logic.NewBuyerSupplyInfoLogic(r.Context(), svcCtx)
+		resp, err := l.BuyerSupplyInfo(&req)
+		if err != nil {
+			httpx.Error(w, err)
+		} else {
+			httpx.OkJson(w, resp)
+		}
+	}
+}

+ 28 - 0
jyBXBuyer/api/internal/handler/relatesInformationHandler.go

@@ -0,0 +1,28 @@
+package handler
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+	"jyBXBuyer/api/internal/logic"
+	"jyBXBuyer/api/internal/svc"
+	"jyBXBuyer/api/internal/types"
+)
+
+func relatesInformationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.RelatesInformationReq
+		if err := httpx.Parse(r, &req); err != nil {
+			httpx.Error(w, err)
+			return
+		}
+
+		l := logic.NewRelatesInformationLogic(r.Context(), svcCtx, r)
+		resp, err := l.RelatesInformation(&req)
+		if err != nil {
+			httpx.Error(w, err)
+		} else {
+			httpx.OkJson(w, resp)
+		}
+	}
+}

+ 10 - 0
jyBXBuyer/api/internal/handler/routes.go

@@ -17,6 +17,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/jybx/buyer/:userType/buyerList",
 				Handler: buyerSearchListHandler(serverCtx),
 			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/jybx/buyer/relates/information",
+				Handler: relatesInformationHandler(serverCtx),
+			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/jybx/buyer/supply/info",
+				Handler: buyerSupplyInfoHandler(serverCtx),
+			},
 		},
 	)
 }

+ 3 - 4
jyBXBuyer/api/internal/logic/buyerSearchListLogic.go

@@ -39,8 +39,6 @@ func (l *BuyerSearchListLogic) BuyerSearchList(req *types.BuyerListReq) (resp *t
 		BuyerName:      req.BuyerName,
 		Province:       req.Province,
 		City:           req.City,
-		BusinessScope:  req.BusinessScope,
-		Industry:       req.Industry,
 		BuyerClass:     req.BuyerClass,
 		IsCheckFollow:  req.IsCheckFollow,
 		IsCheckReceive: req.IsCheckReceive,
@@ -48,7 +46,9 @@ func (l *BuyerSearchListLogic) BuyerSearchList(req *types.BuyerListReq) (resp *t
 		UserId:         l.r.Header.Get("userId"),
 		EntId:          req.EntId,
 		EntUserId:      req.EntUserId,
-		Customer:       req.Customer,
+		PageSize:       req.PageSize,
+		PageNum:        req.PageNum,
+		IsContact:      req.IsContact,
 	})
 	if err0 != nil {
 		return &types.CommonResp{
@@ -62,5 +62,4 @@ func (l *BuyerSearchListLogic) BuyerSearchList(req *types.BuyerListReq) (resp *t
 		Err_msg:  res.ErrMsg,
 		Data:     res.Data,
 	}, nil
-	return
 }

+ 52 - 0
jyBXBuyer/api/internal/logic/buyerSupplyInfoLogic.go

@@ -0,0 +1,52 @@
+package logic
+
+import (
+	"context"
+	"jyBXBuyer/rpc/type/bxbuyer"
+
+	"jyBXBuyer/api/internal/svc"
+	"jyBXBuyer/api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type BuyerSupplyInfoLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewBuyerSupplyInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BuyerSupplyInfoLogic {
+	return &BuyerSupplyInfoLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *BuyerSupplyInfoLogic) BuyerSupplyInfo(req *types.BuyerSupplyInfoReq) (resp *types.CommonResp, err error) {
+	return &types.CommonResp{
+		Err_code: 0,
+		Err_msg:  "",
+		Data:     "",
+	}, nil
+
+	res, err0 := l.svcCtx.Buyer.BuyerSupplyInfo(l.ctx, &bxbuyer.BuyerSupplyInfoReq{
+		Buyers:       req.Buyer,
+		PositionId:   req.PositionId,
+		PositionType: req.PositionType,
+		Phone:        req.Phone,
+	})
+	if err0 != nil {
+		return &types.CommonResp{
+			Err_code: -1,
+			Err_msg:  "错误",
+			Data:     nil,
+		}, nil
+	}
+	return &types.CommonResp{
+		Err_code: res.ErrCode,
+		Err_msg:  res.ErrMsg,
+		Data:     res.Data,
+	}, nil
+}

+ 53 - 0
jyBXBuyer/api/internal/logic/relatesInformationLogic.go

@@ -0,0 +1,53 @@
+package logic
+
+import (
+	"context"
+	"jyBXBuyer/rpc/type/bxbuyer"
+	"net/http"
+
+	"jyBXBuyer/api/internal/svc"
+	"jyBXBuyer/api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type RelatesInformationLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	r      *http.Request
+}
+
+func NewRelatesInformationLogic(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request) *RelatesInformationLogic {
+	return &RelatesInformationLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		r:      r,
+	}
+}
+
+func (l *RelatesInformationLogic) RelatesInformation(req *types.RelatesInformationReq) (resp *types.CommonResp, err error) {
+	res, err0 := l.svcCtx.Buyer.RelatesInfo(l.ctx, &bxbuyer.RelatesInformationReq{
+		Area:         req.Area,
+		City:         req.City,
+		BiddingCount: int64(req.BiddingCount),
+		BuyerCount:   int64(req.BuyerCount),
+		Buyer:        req.Buyer,
+		PositionId:   req.PositionId,
+		PositionType: req.PositionType,
+		Phone:        req.Phone,
+	})
+	if err0 != nil {
+		return &types.CommonResp{
+			Err_code: -1,
+			Err_msg:  "错误",
+			Data:     nil,
+		}, nil
+	}
+	return &types.CommonResp{
+		Err_code: res.ErrCode,
+		Err_msg:  res.ErrMsg,
+		Data:     res.Data,
+	}, nil
+}

+ 34 - 5
jyBXBuyer/api/internal/types/types.go

@@ -5,17 +5,18 @@ type BuyerListReq struct {
 	Province       []string `json:"province,optional"`       //省份
 	City           []string `json:"city,optional"`           //城市
 	BuyerClass     []string `json:"buyerClass,optional"`     //客户类型(采购单位行业)
-	Industry       []string `json:"industry,optional"`       //行业分类(信息行业)
 	BusinessScope  string   `json:"businessScope,optional"`  //业务范围(关键词 附加词 排除词)
 	BuyerName      string   `json:"buyerName,optional"`      //采购单位名称
 	AppId          string   `header:"appId"`                 //剑鱼10000
 	UserType       string   `path:"userType"`                //用户标签
 	IsCheckFollow  bool     `json:"isCheckFollow,optional"`  //是否查询关注信息(商机管理用户)
 	IsCheckReceive bool     `json:"isCheckReceive,optional"` //是否查询已领取(商机管理用户)
-	UserId         string   `header:"userId"`                //用户id
-	EntId          string   `header:"entId"`                 //企业id
-	EntUserId      string   `header:"entUserId"`             //商机管理企业用户id
-	Customer       []string `json:"customer,optional"`       //历史客户
+	UserId         string   `header:"userId,optional"`       //用户id
+	EntId          string   `header:"entId,optional"`        //企业id
+	EntUserId      string   `header:"entUserId,optional"`    //商机管理企业用户id
+	IsContact      int64    `json:"isContact,optional"`      // 是否有联系人 0 不筛选 1-有联系人 2-无联系人
+	PageNum        int64    `json:"pageNum"`                 //当前页码
+	PageSize       int64    `json:"pageSize"`                //每页数据量
 }
 
 type CommonResp struct {
@@ -23,3 +24,31 @@ type CommonResp struct {
 	Err_msg  string      `json:"error_msg"`
 	Data     interface{} `json:"data"`
 }
+
+type BaseParam struct {
+	EntId        int64  `header:"entId,optional"`        // 企业id
+	EntUserId    int64  `header:"entUserId,optional"`    // 企业下用户id
+	PositionType int64  `header:"positionType,optional"` // 职位类型 0个人 1企业
+	PositionId   int64  `header:"positionId,optional"`   //职位id
+	AccountId    int64  `header:"accountId,optional"`    //账户id
+	MgoUserId    string `header:"mgoUserId,optional"`    //原userId
+	AppId        string `header:"appId,optional"`        //剑鱼10000
+	UserId       string `header:"userId,optional"`       //用户id
+	NewUserId    int64  `header:"newUserId,optional"`    //base_user_id
+	EntAccountId int64  `header:"entAccountId,optional"` //企业账户id
+	Phone        string `header:"phone,optional"`
+}
+
+type RelatesInformationReq struct {
+	BaseParam
+	BiddingCount int    `json:"biddingCount,optional"` //关联招标信息数量---根据采购单位
+	BuyerCount   int    `json:"buyerCount,optional"`   //关联采购单位信息---根据地区
+	Buyer        string `json:"buyer,optional"`        //采购单位
+	Area         string `json:"area,optional"`         //地区
+	City         string `json:"city,optional"`         //城市
+}
+
+type BuyerSupplyInfoReq struct {
+	BaseParam
+	Buyer []string `json:"buyer,optional"` //采购单位
+}

+ 77 - 20
jyBXBuyer/rpc/bxbuyer.proto

@@ -1,7 +1,7 @@
 syntax = "proto3";
 
 package bxbuyer;
-option go_package="./bxbuyer";
+option go_package = "./bxbuyer";
 
 message BuyerListReq {
   string appId = 1;//剑鱼默认10000
@@ -10,18 +10,17 @@ message BuyerListReq {
   string  buyerName = 4;//采购单位名称
   repeated string  province = 5;//省份
   repeated string  city = 6;//城市
-  string  businessScope = 7;//关键词 附加词 排除词
-  int64  sortRule = 8;//排序规则
-  bool  isCheckFollow = 9;//是否查询关注信息(商机管理用户)
-  bool  isCheckReceive = 10;//是否查询已领取(商机管理用户)
-  repeated string  industry = 11;//行业
-  repeated string  buyerClass = 12;//采购单位类型
-  string  userId = 13;
-  string  userType = 14;//用户状态 fType:免费用户	pType:付费用户	vType:超级订阅用户	mType:大会员用户	eType:商机管理用户
-  string  platform = 15;//请求平台
-  string entId = 16;//企业id
-  string entUserId = 17;//商机管理用户id
-  repeated string  customer = 18;//历史客户
+  int64  sortRule = 7;//排序规则
+  bool  isCheckFollow = 8;//是否查询关注信息(商机管理用户)
+  bool  isCheckReceive = 9;//是否查询已领取(商机管理用户)
+  repeated string  buyerClass = 10;//采购单位类型
+  string  userId = 11;
+  string  userType = 12;//用户状态 fType:免费用户	pType:付费用户	vType:超级订阅用户	mType:大会员用户	eType:商机管理用户
+  string  platform = 13;//请求平台
+  string entId = 14;//企业id
+  string entUserId = 15;//商机管理用户id
+  string pageSource = 16;// 来源   search-搜索  index-首页
+  int64  isContact = 17;// 是否有联系人:0-全部; 1-有 ;2-无
 }
 
 message BuyerListResp {
@@ -36,16 +35,74 @@ message BuyerData {
 
 message  BuyerList {
   string  buyer = 1;//采购单位名称
-  double  budget = 2;//预算
-  string  province = 3;//省份
-  string  city = 4;//城市
-  int64  pCount = 5;//项目数量
-  bool  isFollowed = 6;//是否关注
-  bool  isReceived = 7;//是否已领取
-  string  recId = 8;//领取id
+  string  province = 2;//省份
+  string  city = 3;//城市
+  bool  isFollowed = 4;//是否关注
+  bool  isReceived = 5;//是否已领取
+  string  recId = 6;//领取id
+  string buyerClass = 7;// 采购单位类型
+  int64 biddingCount = 8;// 招标动态数量
+  int64 contactCount = 9;// 历史联系人数量
+  int64 projectCount = 10;// 采购项目数量
+  float bidAmountCount = 11;// 采购规模
 }
 
+message relatesInformationReq {
+  int64  biddingCount = 1;
+  int64  buyerCount=2;
+  string buyer = 3;
+  string area = 4;
+  string city = 5;
+  int64  positionId = 6; // 职位id
+  int64  positionType =7;// 职位类型 0个人 1企业
+  string phone = 8 ;// 手机号
+}
+//
+message relatesInformationResp{
+  int64 err_code = 1;
+  string err_msg = 2;
+  relatesInformation data = 3;
+}
+message relatesInformation {
+  repeated infoList buyerList =1;//采购单位信息
+  repeated infoList biddingList = 2;//类似采购单位招标信息
+}
+//
+message infoList {
+  string name =1;//采购单位名称||信息标题
+  string id = 2;//信息类型id
+  string publishTime = 3;
+}
+// 采购单位搜索获取补充信息
+message BuyerSupplyInfoReq{
+  string appId = 1;//剑鱼默认10000
+  int64  positionId = 2; // 职位id
+  int64  positionType =3;// 职位类型 0个人 1企业
+  string phone = 4 ;// 手机号
+  repeated string buyers = 5;// 采购单位名称
+}
+message BuyerSupplyResp {
+  int64 err_code = 1;
+  string err_msg = 2;
+  repeated  SupplyData data = 3;
+}
+
+message SupplyData {
+  int64 biddingCount = 1;// 招标动态数量
+  int64 contactCount = 2;// 历史联系人数量
+  int64 projectCount = 3;// 采购项目数量
+  float bidAmountCount = 4;// 采购规模
+  string buyer = 5;//采购单位名词
+}
+
+
+
+
 service Bxbuyer {
   //采购单位搜索
   rpc BuyerList(BuyerListReq) returns(BuyerListResp);
+  // 采购单位搜索补充信息 招标动态数量 、历史联系人数量、项目数量、采购规模
+  rpc BuyerSupplyInfo(BuyerSupplyInfoReq) returns(BuyerSupplyResp);
+  //采购单位画像 关联信息
+  rpc RelatesInfo(relatesInformationReq) returns(relatesInformationResp);
 }

+ 27 - 4
jyBXBuyer/rpc/bxbuyer/bxbuyer.go

@@ -13,14 +13,25 @@ import (
 )
 
 type (
-	BuyerData     = bxbuyer.BuyerData
-	BuyerList     = bxbuyer.BuyerList
-	BuyerListReq  = bxbuyer.BuyerListReq
-	BuyerListResp = bxbuyer.BuyerListResp
+	BuyerData              = bxbuyer.BuyerData
+	BuyerList              = bxbuyer.BuyerList
+	BuyerListReq           = bxbuyer.BuyerListReq
+	BuyerListResp          = bxbuyer.BuyerListResp
+	BuyerSupplyInfoReq     = bxbuyer.BuyerSupplyInfoReq
+	BuyerSupplyResp        = bxbuyer.BuyerSupplyResp
+	InfoList               = bxbuyer.InfoList
+	RelatesInformation     = bxbuyer.RelatesInformation
+	RelatesInformationReq  = bxbuyer.RelatesInformationReq
+	RelatesInformationResp = bxbuyer.RelatesInformationResp
+	SupplyData             = bxbuyer.SupplyData
 
 	Bxbuyer interface {
 		// 采购单位搜索
 		BuyerList(ctx context.Context, in *BuyerListReq, opts ...grpc.CallOption) (*BuyerListResp, error)
+		//  采购单位搜索补充信息 招标动态数量 、历史联系人数量、项目数量、采购规模
+		BuyerSupplyInfo(ctx context.Context, in *BuyerSupplyInfoReq, opts ...grpc.CallOption) (*BuyerSupplyResp, error)
+		// 采购单位画像 关联信息
+		RelatesInfo(ctx context.Context, in *RelatesInformationReq, opts ...grpc.CallOption) (*RelatesInformationResp, error)
 	}
 
 	defaultBxbuyer struct {
@@ -39,3 +50,15 @@ func (m *defaultBxbuyer) BuyerList(ctx context.Context, in *BuyerListReq, opts .
 	client := bxbuyer.NewBxbuyerClient(m.cli.Conn())
 	return client.BuyerList(ctx, in, opts...)
 }
+
+//  采购单位搜索补充信息 招标动态数量 、历史联系人数量、项目数量、采购规模
+func (m *defaultBxbuyer) BuyerSupplyInfo(ctx context.Context, in *BuyerSupplyInfoReq, opts ...grpc.CallOption) (*BuyerSupplyResp, error) {
+	client := bxbuyer.NewBxbuyerClient(m.cli.Conn())
+	return client.BuyerSupplyInfo(ctx, in, opts...)
+}
+
+// 采购单位画像 关联信息
+func (m *defaultBxbuyer) RelatesInfo(ctx context.Context, in *RelatesInformationReq, opts ...grpc.CallOption) (*RelatesInformationResp, error) {
+	client := bxbuyer.NewBxbuyerClient(m.cli.Conn())
+	return client.RelatesInfo(ctx, in, opts...)
+}

+ 24 - 23
jyBXBuyer/rpc/etc/bxbuyer.yaml

@@ -2,30 +2,31 @@ Name: bxbuyer.rpc
 ListenOn: 127.0.0.1:8008
 Etcd:
   Hosts:
-  - 127.0.0.1:2379
+    - 127.0.0.1:2379
   Key: bxbuyer.rpc
-Timeout: 8000
+Timeout: 30000
 Webrpcport: 8018
 BuyerCount: 500
 DefaultBuyerNames:
-    - "吉林省农村信用社联合社"
-    - "包头职业技术学院"
-    - "中国民生银行股份有限公司"
-    - "广东烟草梅州市有限公司"
-    - "宁波市自然资源和规划局"
-    - "正数网络技术有限公司"
-    - "浙江创联信息技术股份有限公司"
-    - "甘肃省农村信用社联合社"
-    - "广西壮族自治区自然资源厅"
-    - "华数传媒网络有限公司"
-    - "无锡地铁集团有限公司"
-    - "天津银行股份有限公司"
-    - "广州信息投资有限公司"
-    - "国联证券股份有限公司"
-    - "北京航空航天大学宁波创新研究院"
-    - "湖北省卫生健康委员会"
-    - "上海浦东发展银行股份有限公司信用卡中心"
-    - "上海市房屋管理局"
-    - "长三角金融科技有限公司"
-    - "华能信息技术有限公司"
-    - "浙江华数广电网络股份有限公司"
+  - "吉林省农村信用社联合社"
+  - "包头职业技术学院"
+  - "中国民生银行股份有限公司"
+  - "广东烟草梅州市有限公司"
+  - "宁波市自然资源和规划局"
+  - "正数网络技术有限公司"
+  - "浙江创联信息技术股份有限公司"
+  - "甘肃省农村信用社联合社"
+  - "广西壮族自治区自然资源厅"
+  - "华数传媒网络有限公司"
+  - "无锡地铁集团有限公司"
+  - "天津银行股份有限公司"
+  - "广州信息投资有限公司"
+  - "国联证券股份有限公司"
+  - "北京航空航天大学宁波创新研究院"
+  - "湖北省卫生健康委员会"
+  - "上海浦东发展银行股份有限公司信用卡中心"
+  - "上海市房屋管理局"
+  - "长三角金融科技有限公司"
+  - "华能信息技术有限公司"
+  - "浙江华数广电网络股份有限公司"
+BuyerSearchLimit: 100  # 采购单位搜索数量限制

+ 3 - 3
jyBXBuyer/rpc/etc/db.yaml

@@ -1,16 +1,16 @@
 mysql:
     main:
         dbName: jianyu
-        address: 192.168.3.11:3366
+        address: 192.168.3.149:3306
         userName: root
         password: Topnet123
         maxOpenConns: 5
         maxIdleConns: 5
 redis:
     addr:
-        - other=192.168.3.206:1712
+        - other=192.168.3.149:1713
 es:
-    addr: http://192.168.3.206:9800
+    addr: http://192.168.3.241:9205
     size: 30
     version: v7
     userName: ""

+ 1 - 0
jyBXBuyer/rpc/internal/config/config.go

@@ -10,6 +10,7 @@ type Config struct {
 	Webrpcport        int64
 	BuyerCount        int64
 	DefaultBuyerNames []string
+	BuyerSearchLimit  int64
 }
 
 type Db struct {

+ 61 - 19
jyBXBuyer/rpc/internal/logic/buyerlistlogic.go

@@ -4,7 +4,9 @@ import (
 	"app.yhyue.com/moapp/jybase/redis"
 	"context"
 	"encoding/json"
+	"fmt"
 	"github.com/zeromicro/go-zero/core/logx"
+	IC "jyBXBuyer/rpc/init"
 	"jyBXBuyer/rpc/internal/svc"
 	"jyBXBuyer/rpc/model"
 	"jyBXBuyer/rpc/type/bxbuyer"
@@ -27,37 +29,77 @@ func NewBuyerListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BuyerLi
 // 采购单位搜索
 func (l *BuyerListLogic) BuyerList(in *bxbuyer.BuyerListReq) (*bxbuyer.BuyerListResp, error) {
 	logx.Info("----:", model.CheckEmpty(in))
-	query := ""
-	resp := &bxbuyer.BuyerListResp{}
+	resp := &bxbuyer.BuyerListResp{
+		Data: &bxbuyer.BuyerData{},
+	}
+	if in.PageNum < 1 {
+		in.PageNum = 1
+	}
+	if in.PageSize > 100 || in.PageSize < 1 {
+		in.PageSize = 10
+	}
+	if in.PageSize > IC.C.BuyerSearchLimit {
+		in.PageSize = IC.C.BuyerSearchLimit
+	}
+	// 判断数量
+	// 采购单位搜索过来的 最多查BuyerSearchLimit条
+	if in.PageNum*in.PageSize > IC.C.BuyerSearchLimit && (in.PageNum-1)*in.PageSize >= IC.C.BuyerSearchLimit {
+		in.PageNum = IC.C.BuyerSearchLimit / in.PageSize
+	}
+
+	query, CountQuery := "", ""
+	buyerNames := []string{}
 	if model.CheckEmpty(in) {
-		//获取缓存数据
 		var isBool = true
-		bs, err := redis.GetBytes("other", model.P_redis_key)
+		list := []*bxbuyer.BuyerList{} //100条数据
+		bs, err := redis.GetBytes("other", fmt.Sprintf(model.P_redis_key))
 		if err == nil && bs != nil && len(*bs) > 0 {
 			isBool = false
-			if err := json.Unmarshal(*bs, &resp.Data); err != nil {
+			if err := json.Unmarshal(*bs, &list); err != nil {
 				isBool = true
 				logx.Info("获取redis缓存,序列化异常")
+			} else {
+				if len(list) > 0 {
+					// 根据页码返回数据
+					start := in.PageSize * (in.PageNum - 1)
+					end := in.PageSize * in.PageNum
+					count := len(list)
+					resp.Data.Count = int64(count)
+					if end > int64(len(list)) {
+						end = int64(len(list))
+					}
+					resp.Data.List = list[start:end]
+					for i := 0; i < len(resp.Data.List); i++ {
+						buyerNames = append(buyerNames, resp.Data.List[i].Buyer)
+					}
+				} else {
+					isBool = true
+				}
 			}
 		}
 		if isBool {
 			query = model.BuyerListRedisCacheQuery()
-			resp = model.GetBuyerList(query, in, true)
-			b, err := json.Marshal(resp.Data)
-			if err == nil {
-				redis.PutBytes("other", model.P_redis_key, &b, model.P_redis_time)
-			} else {
-				logx.Info("缓存数据 序列化异常")
-			}
+			buyerNames, resp = model.BuyerListRedisCache(query, in)
+
 		}
 	} else {
-		query = model.BuyerListQuery(in)
+		query, CountQuery = model.BuyerListQuery(in)
 		logx.Info("query:", query)
-		resp = model.GetBuyerList(query, in, false)
+		buyerNames, resp = model.GetBuyerList(query, CountQuery, false) // 查询数据
+	}
+	if len(resp.Data.List) > 0 && (in.UserId != "" || in.EntUserId != "") {
+		model.SupplyFollowInfo(in, buyerNames, resp)
+	}
+	if len(resp.Data.List) > 0 {
+		if in.PageNum*in.PageSize > IC.C.BuyerSearchLimit && (in.PageNum-1)*in.PageSize < IC.C.BuyerSearchLimit {
+			end := IC.C.BuyerSearchLimit - (in.PageNum-1)*in.PageSize
+			if len(resp.Data.List) > int(end) {
+				resp.Data.List = resp.Data.List[:end]
+			}
+		}
+	}
+	if resp.Data.Count > IC.C.BuyerSearchLimit {
+		resp.Data.Count = IC.C.BuyerSearchLimit
 	}
-	return &bxbuyer.BuyerListResp{
-		Data:    resp.Data,
-		ErrMsg:  resp.ErrMsg,
-		ErrCode: resp.ErrCode,
-	}, nil
+	return resp, nil
 }

+ 36 - 0
jyBXBuyer/rpc/internal/logic/buyersupplyinfologic.go

@@ -0,0 +1,36 @@
+package logic
+
+import (
+	"context"
+	IC "jyBXBuyer/rpc/init"
+	"jyBXBuyer/rpc/internal/svc"
+	"jyBXBuyer/rpc/model"
+	"jyBXBuyer/rpc/type/bxbuyer"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type BuyerSupplyInfoLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewBuyerSupplyInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BuyerSupplyInfoLogic {
+	return &BuyerSupplyInfoLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+// 采购单位搜索补充信息 招标动态数量 、历史联系人数量、项目数量、采购规模
+func (l *BuyerSupplyInfoLogic) BuyerSupplyInfo(in *bxbuyer.BuyerSupplyInfoReq) (*bxbuyer.BuyerSupplyResp, error) {
+	resp := &bxbuyer.BuyerSupplyResp{}
+	if len(in.Buyers) == 0 || len(in.Buyers) > int(IC.C.BuyerSearchLimit) {
+		return resp, nil
+	}
+	resp = model.BuyerSupplyInfo(in.Buyers)
+
+	return resp, nil
+}

+ 28 - 0
jyBXBuyer/rpc/internal/logic/relatesinfologic.go

@@ -0,0 +1,28 @@
+package logic
+
+import (
+	"context"
+	"github.com/zeromicro/go-zero/core/logx"
+	"jyBXBuyer/rpc/internal/svc"
+	"jyBXBuyer/rpc/service"
+	"jyBXBuyer/rpc/type/bxbuyer"
+)
+
+type RelatesInfoLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewRelatesInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RelatesInfoLogic {
+	return &RelatesInfoLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+// 采购单位画像 关联信息
+func (l *RelatesInfoLogic) RelatesInfo(in *bxbuyer.RelatesInformationReq) (*bxbuyer.RelatesInformationResp, error) {
+	return service.GetRelatesInfo(in), nil
+}

+ 12 - 0
jyBXBuyer/rpc/internal/server/bxbuyerserver.go

@@ -27,3 +27,15 @@ func (s *BxbuyerServer) BuyerList(ctx context.Context, in *bxbuyer.BuyerListReq)
 	l := logic.NewBuyerListLogic(ctx, s.svcCtx)
 	return l.BuyerList(in)
 }
+
+//  采购单位搜索补充信息 招标动态数量 、历史联系人数量、项目数量、采购规模
+func (s *BxbuyerServer) BuyerSupplyInfo(ctx context.Context, in *bxbuyer.BuyerSupplyInfoReq) (*bxbuyer.BuyerSupplyResp, error) {
+	l := logic.NewBuyerSupplyInfoLogic(ctx, s.svcCtx)
+	return l.BuyerSupplyInfo(in)
+}
+
+// 采购单位画像 关联信息
+func (s *BxbuyerServer) RelatesInfo(ctx context.Context, in *bxbuyer.RelatesInformationReq) (*bxbuyer.RelatesInformationResp, error) {
+	l := logic.NewRelatesInfoLogic(ctx, s.svcCtx)
+	return l.RelatesInfo(in)
+}

+ 626 - 180
jyBXBuyer/rpc/model/buyerListBYEs.go

@@ -1,10 +1,12 @@
 package model
 
 import (
+	"app.yhyue.com/moapp/jybase/redis"
 	"encoding/json"
 	"fmt"
 	IC "jyBXBuyer/rpc/init"
 	"jyBXBuyer/rpc/type/bxbuyer"
+	"log"
 	"strconv"
 	"strings"
 	"sync"
@@ -16,29 +18,35 @@ import (
 	"github.com/zeromicro/go-zero/core/logx"
 )
 
+const (
+	HasContact = 1 // 采购单位是否有联系方式筛选项 1-有联系方式
+	NoContact  = 2 //  无联系方式
+)
+
 type BScope struct {
 	Keyword         []string `json:"keyword"`
 	AdditionalWords []string `json:"additionalWords"`
 	ExcludedWords   []string `json:"excludedWords"`
 }
+type supplyDataStruct struct {
+	ProjectCount   int64
+	BidCount       int64
+	BidAmountCount float32
+	ContactCount   int64
+}
 
-//获取采购单位查询query
-func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string) {
-	query_bool_must_and := `{"bool": {"must": [%s]%s}}`
-	multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
-	query := `{"size": 0,"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer": ""}}],"should":[%s],"minimum_should_match": %d}},%s}`
+// 获取采购单位查询query
+func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string, CountQstr string) {
+	query := `{%s "query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}],"should":[%s],"minimum_should_match": %d}} %s}`
 	//21.1.20  为和画像保持一致  数据组要求 budget 改成 bidamount
-	query_aggs := `"aggs": {"group_field": {"terms": {"field": %s,"size": %d%s},"aggs": {"count": {"sum": {"field": "bidamount"}}}}}`
-	query_sort := `,"order": {"count": "desc"}`
-	query_bool_must := `{"terms":{"%s":[%s]}}`
 	query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
-
+	sort := ""
 	bools := []string{}
 	musts := []string{}
 	musts_should := []string{}
 	//省份
 	if len(in.Province) > 0 {
-		musts_should = append(musts_should, fmt.Sprintf(`{"terms":{"area":["%s"]}}`, strings.Join(in.Province, "\",\"")))
+		musts_should = append(musts_should, fmt.Sprintf(`{"terms":{"province":["%s"]}}`, strings.Join(in.Province, "\",\"")))
 	}
 	//城市
 	if len(in.City) > 0 {
@@ -48,9 +56,12 @@ func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string) {
 		musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(musts_should, ",")))
 	}
 	//采购单位名称
-	if len(in.BuyerName) > 0 {
-		entNameQuery := `{"match_phrase":{"buyer.mbuyer":"` + in.BuyerName + `"}}`
+	if in.BuyerName != "" {
+		entNameQuery := fmt.Sprintf(`{"multi_match": {"query": "%s","type": "phrase", "fields": ["name"]}}`, in.BuyerName)
 		musts = append(musts, entNameQuery)
+	} else {
+		sort = `,"sort":[{"updatetime":"desc"}]` // 仅无关键词时再
+
 	}
 	//采购单位类型
 	buyerclass := in.BuyerClass
@@ -65,169 +76,622 @@ func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string) {
 		Buyerclass += `]}}`
 		musts = append(musts, Buyerclass)
 	}
-	//行业
-	industry := in.Industry
-	if len(industry) > 0 {
-		musts = append(musts, fmt.Sprintf(query_bool_must, "subscopeclass", `"`+strings.Join(industry, `","`)+`"`))
+	// 采购单位联系方式  0-不限 1-有联系人 2-无联系人
+	if in.IsContact != 0 {
+		isContact := MC.If(in.IsContact == int64(HasContact), true, false)
+		isContactStr := `{"term":{"is_contact":` + fmt.Sprint(isContact) + `}}`
+		musts = append(musts, isContactStr)
 	}
-	if len(in.Customer) > 0 {
-		entcustomerClass := `{"terms":{"buyer":[`
-		for k, v := range in.Customer {
-			if k > 0 {
-				entcustomerClass += `,`
-			}
-			entcustomerClass += `"` + v + `"`
+	boolsNum := 0
+	qstr = fmt.Sprintf(query, fmt.Sprintf(`"from":%d,"size": %d,`, (in.PageNum-1)*in.PageSize, in.PageSize), strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, sort)
+	CountQstr = fmt.Sprintf(query, "", strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, "")
+	return
+}
+
+// 采购单位补充采购规模、项目数量、招标动态数量
+func SupplyDataQuery(buyerList []string) (query string) {
+	// 查近两年的数据   因为bigmember  BuyerMiniPortrait 查的默认是两年
+	q := `{"size":0,"query": { "bool": { "must": [ {"terms": { "buyer": ["` + strings.Join(buyerList, "\",\"") + `"] }},{"range": {"jgtime": {"gte": %d,"lt": %d} }} ]}}, "aggs": { "buyerBuckets": {"terms": {"field": "buyer"
+ },"aggs": {"bidAmountCount": {"sum": {"field": "bidamount"}}}}}}`
+	start, end := getTimeRange()
+	return fmt.Sprintf(q, start.Unix(), end.Unix())
+}
+func getTimeRange() (st, et time.Time) {
+	now := time.Now()
+	eYear := now.Year()
+	sYear := now.Year() - 2
+	//返回默认时间
+	sTimeStamp := time.Date(sYear, 1, 1, 0, 0, 0, 0, time.Local)
+	eTimeStamp := time.Date(eYear, now.Month(), now.Day(), now.Hour(), now.Minute(), 0, 0, time.Local)
+
+	return sTimeStamp, eTimeStamp
+
+}
+
+const (
+	P_INDEX                   = "projectset"
+	P_TYPE                    = "projectset"
+	P_redis_time              = 7 * 24 * 60 * 60 //redis存7天
+	P_redis_key               = "buyerListCache" // 存缓存 100条数据
+	BuyerIndex                = "buyer"          // 采购单位index
+	BuyerType                 = "buyer"
+	biddingIndex              = "bidding"
+	biddingType               = "bidding"
+	BuyerSupplyInfoRedisKey   = "BuyerSupplyInfo_%s"  // 采购单位补充信息缓存
+	BuyerSupplyInfoRedisTime  = 2 * 60 * 60           // 采购单位补充信息缓存时间 一个小时
+	BuyerProjectInfoRedisKey  = "BuyerProjectInfo_%s" // 采购单位补充项目信息缓存Key  (项目数量采购规模)
+	BuyerProjectInfoRedisTime = 24 * 60 * 60          // 采购单位补充项目信息缓存时间
+)
+
+// GetBuyerList 查询采购单位列表
+func GetBuyerList(qstr string, CountQuery string, isCache bool) (buyerNames []string, resp *bxbuyer.BuyerListResp) {
+	t1 := time.Now()
+	total := elastic.Count(BuyerIndex, BuyerType, CountQuery) // 总数
+	logx.Info("耗时1:", time.Since(t1))
+	resp = &bxbuyer.BuyerListResp{
+		Data: &bxbuyer.BuyerData{
+			Count: total,
+			List:  []*bxbuyer.BuyerList{},
+		},
+	}
+	if total == 0 {
+		return
+	}
+	start := time.Now()
+	rs := elastic.Get(BuyerIndex, BuyerType, qstr) // 采购单位列表
+	logx.Info("采购单位列表 es get查询耗时", time.Since(start))
+	if rs == nil || len(*rs) == 0 {
+		return
+	}
+	for i := 0; i < len(*rs); i++ {
+		tmp := &bxbuyer.BuyerList{
+			Buyer:      MC.ObjToString((*rs)[i]["name"]),
+			Province:   MC.ObjToString((*rs)[i]["province"]),
+			City:       MC.ObjToString((*rs)[i]["city"]),
+			BuyerClass: MC.ObjToString((*rs)[i]["buyerclass"]),
 		}
-		entcustomerClass += `]}}`
-		musts = append(musts, entcustomerClass)
+		buyerNames = append(buyerNames, tmp.Buyer)
+		resp.Data.List = append(resp.Data.List, tmp)
 	}
-	//业务范围
-	boolsNum := 0
-	if in.BusinessScope != "" {
-		var BScopes = []BScope{}
-		json.Unmarshal([]byte(in.BusinessScope), &BScopes)
-		boolsNum = 1
-		findfields := `"projectname.pname","purchasing"`
-		multi_match = fmt.Sprintf(multi_match, "%s", findfields)
-		for _, v := range BScopes {
-			shoulds := []string{}
-			must_not := []string{}
-			//关键词
-			if len(v.Keyword) > 0 {
-				for _, kv := range v.Keyword {
-					shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+kv+"\""))
-				}
+	logx.Info("耗时;", time.Since(t1).Seconds(), "秒--", time.Since(t1).Microseconds())
+	return
+}
+
+// BuyerListRedisCache 空搜索 1.查询项目数量最多的前200个 2.然后 再查buyer里确认数据有效 100个 3.项目数量和采购规模单独存缓存 1天
+//
+//	func BuyerListRedisCache(query string, in *bxbuyer.BuyerListReq) (buyerNames []string, resp *bxbuyer.BuyerListResp) {
+//		//获取缓存数据
+//		resp = &bxbuyer.BuyerListResp{
+//			Data: &bxbuyer.BuyerData{
+//				List: []*bxbuyer.BuyerList{},
+//			},
+//		}
+//		t1 := time.Now()
+//		logx.Info("耗时1:", time.Since(t1))
+//		aggs := GetAggs(P_INDEX, P_TYPE, query)
+//		logx.Info("查询语句:", query)
+//		logx.Info("BuyerListRedisCache:", time.Since(t1))
+//		type BuyerAggStruct struct {
+//			Buckets []struct {
+//				Key            string `json:"key,omitempty"`
+//				Doc_count      int64  `json:"doc_count,omitempty"`
+//				BidAmountCount struct {
+//					Value float32 `json:"value,omitempty"`
+//				} `json:"bidAmountCount"`
+//			} `json:"buckets"`
+//		}
+//		var buyerBuckets = BuyerAggStruct{}
+//		saveBuyerList := []*bxbuyer.BuyerList{} //100条数据 最后存起来
+//		// 处理成map 用于后面格式化数据
+//		if aggs == nil || aggs["buyerBuckets"] == nil {
+//			return
+//		}
+//		bs, err := aggs["buyerBuckets"].MarshalJSON()
+//		if err != nil {
+//			resp.ErrCode = -1
+//			resp.ErrMsg = "获取数据异常"
+//			return
+//		}
+//		if len(bs) == 0 {
+//			resp.ErrMsg = "暂无数据"
+//			return
+//		}
+//		err = json.Unmarshal(bs, &buyerBuckets)
+//		if err != nil || len(buyerBuckets.Buckets) == 0 {
+//			resp.ErrMsg = "暂无数据"
+//			return
+//		}
+//		for i := 0; i < len(buyerBuckets.Buckets); i++ {
+//			if len(saveBuyerList) == int(IC.C.BuyerSearchLimit) {
+//				break
+//			}
+//			// 查buyer  确认数据存在 补充 buyerclass 省份 城市信息
+//			rs := GetBuyer(buyerBuckets.Buckets[i].Key)
+//			if rs != nil && len(*rs) > 0 { // 存在 则追加
+//				tmpBuyerInfo := (*rs)[0]
+//				buyerInfo := &bxbuyer.BuyerList{
+//					Buyer:      buyerBuckets.Buckets[i].Key,
+//					Province:   MC.ObjToString(tmpBuyerInfo["province"]),
+//					City:       MC.ObjToString(tmpBuyerInfo["city"]),
+//					BuyerClass: MC.ObjToString(tmpBuyerInfo["buyerclass"]),
+//				}
+//				saveBuyerList = append(saveBuyerList, buyerInfo)
+//				buyerNames = append(buyerNames, buyerInfo.Buyer)
+//				// 项目数量和采购规模存缓存 1天
+//				projectCacheData := supplyDataStruct{
+//					ProjectCount:   buyerBuckets.Buckets[i].Doc_count,
+//					BidAmountCount: buyerBuckets.Buckets[i].BidAmountCount.Value,
+//				}
+//				go func(buyer string, data supplyDataStruct) {
+//					b, err := json.Marshal(data)
+//					if err == nil {
+//						redis.PutBytes("other", fmt.Sprintf(BuyerProjectInfoRedisKey, buyer), &b, BuyerProjectInfoRedisTime+GetRand(60))
+//					}
+//				}(buyerBuckets.Buckets[i].Key, projectCacheData)
+//
+//			}
+//		}
+//		if len(saveBuyerList) > 0 {
+//			//  100 列表存redis 7天
+//			go func(data []*bxbuyer.BuyerList) {
+//				b, err := json.Marshal(data)
+//				if err == nil {
+//					redis.PutBytes("other", fmt.Sprintf(P_redis_key), &b, P_redis_time)
+//				}
+//			}(saveBuyerList)
+//		} else {
+//			return
+//		}
+//
+//		// 根据页码返回数据
+//		start := in.PageSize * (in.PageNum - 1)
+//		end := in.PageSize * in.PageNum
+//		resp.Data.Count = int64(len(saveBuyerList))
+//		if end > int64(len(saveBuyerList)-1) {
+//			end = int64(len(saveBuyerList) - 1)
+//		}
+//		resp.Data.List = saveBuyerList[start:end]
+//		return
+//	}
+func BuyerListRedisCache(query string, in *bxbuyer.BuyerListReq) (buyerNames []string, resp *bxbuyer.BuyerListResp) {
+	//获取缓存数据
+	resp = &bxbuyer.BuyerListResp{
+		Data: &bxbuyer.BuyerData{
+			List: []*bxbuyer.BuyerList{},
+		},
+	}
+	t1 := time.Now()
+	rs := elastic.Get(BuyerIndex, BuyerType, query) // 采购单位列表
+	logx.Info("空搜索采购单位列表 es get查询耗时", time.Since(t1))
+	if rs == nil || len(*rs) == 0 {
+		return
+	}
+	saveBuyerList := []*bxbuyer.BuyerList{} //最后缓存起来
+	for i := 0; i < len(*rs); i++ {
+		tmp := &bxbuyer.BuyerList{
+			Buyer:      MC.ObjToString((*rs)[i]["name"]),
+			Province:   MC.ObjToString((*rs)[i]["province"]),
+			City:       MC.ObjToString((*rs)[i]["city"]),
+			BuyerClass: MC.ObjToString((*rs)[i]["buyerclass"]),
+		}
+		buyerNames = append(buyerNames, tmp.Buyer)
+		saveBuyerList = append(saveBuyerList, tmp)
+	}
+	if len(saveBuyerList) > 0 {
+		//  100 列表存redis 7天
+		go func(data []*bxbuyer.BuyerList) {
+			b, err := json.Marshal(data)
+			if err == nil {
+				redis.PutBytes("other", fmt.Sprintf(P_redis_key), &b, P_redis_time)
 			}
-			//附加词
-			if len(v.AdditionalWords) > 0 {
-				for _, av := range v.AdditionalWords {
-					shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+av+"\""))
-				}
+		}(saveBuyerList)
+	} else {
+		return
+	}
+	// 根据页码返回数据
+	start := in.PageSize * (in.PageNum - 1)
+	end := in.PageSize * in.PageNum
+	resp.Data.Count = int64(len(saveBuyerList))
+	if end > int64(len(saveBuyerList)) {
+		end = int64(len(saveBuyerList))
+	}
+	resp.Data.List = saveBuyerList[start:end]
+	logx.Info("空搜索整体耗时;", time.Since(t1).Seconds(), "秒--", time.Since(t1).Microseconds())
+	return
+}
+
+// GetBuyer 查采购单位表 确认采购单位存在
+func GetBuyer(buyerName string) *[]map[string]interface{} {
+	q := `{"size":1,"_source":["buyerclass","province","city"],"query":{"bool":{"must":[{"term":{"buyer_name":"%s"}}]}}}`
+	rs := elastic.Get(BuyerIndex, BuyerType, fmt.Sprintf(q, buyerName))
+	return rs
+}
+
+// SupplyFollowInfo 补充是否关注信息
+func SupplyFollowInfo(in *bxbuyer.BuyerListReq, buyerNames []string, resp *bxbuyer.BuyerListResp) *bxbuyer.BuyerListResp {
+
+	//省份和城市 是否查询已关注信息 是否查询已领取信息
+	//企业信用库qyxy_std 和es buyer库 查询省份和城市
+	//客户领取
+	t2 := time.Now()
+	isRws := map[string]string{}
+	if in.IsCheckReceive {
+		isRws = IsReceived(buyerNames, in.EntUserId)
+	}
+	logx.Info("客户领取耗时:", time.Since(t2))
+	//客户关注
+	t3 := time.Now()
+	isFws := map[string]bool{}
+	if in.IsCheckFollow {
+		isFws = IsFollowd(buyerNames, in.UserId)
+	}
+	logx.Info("采购单位关注耗时:", time.Since(t3))
+	for _, bv := range resp.Data.List {
+		if in.IsCheckReceive {
+			if isRws[bv.Buyer] != "" {
+				bv.IsReceived = true
+				bv.RecId = isRws[bv.Buyer]
 			}
-			if len(v.ExcludedWords) > 0 {
-				//排除词
-				for _, ev := range v.ExcludedWords {
-					must_not = append(must_not, fmt.Sprintf(multi_match, "\""+ev+"\""))
-				}
+		}
+		if in.IsCheckFollow {
+			if isFws[bv.Buyer] {
+				bv.IsFollowed = true
+			}
+		}
+	}
+	return resp
+}
+
+// SupplyBuyerListData 补充字段   招标动态数量 项目数量 历史联系人数量 采购单位规模
+func SupplyBuyerListData(buyerNames []string, resp *bxbuyer.BuyerListResp) *bxbuyer.BuyerListResp {
+	//buyerNames 是否存在缓存 数据
+	//如果没有 放到一个新的 []string
+	needSearchBuyer := []string{}
+	cacheMap := map[string]supplyDataStruct{}
+	for i := 0; i < len(buyerNames); i++ {
+		bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, buyerNames[i]))
+		if err == nil && bs != nil && len(*bs) > 0 {
+			tmp := supplyDataStruct{}
+			if err := json.Unmarshal(*bs, &tmp); err == nil {
+				cacheMap[buyerNames[i]] = tmp // 拿到缓存的数据
+			} else {
+				needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查
 			}
-			//添加
-			if len(shoulds) > 0 {
-				notStr := ""
-				if len(must_not) > 0 {
-					notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
+		} else {
+			needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查
+		}
+
+	}
+
+	start := time.Now()
+	t1 := time.Now()
+	buyerMap := map[string]supplyDataStruct{} // 聚合的数据
+	if len(needSearchBuyer) > 0 {
+		query := SupplyDataQuery(needSearchBuyer) // 项目数量、采购规模
+		// 聚合查
+		aggs := GetAggs(P_INDEX, P_TYPE, query)
+		logx.Info("查询语句:", query)
+		logx.Info("项目数量采购规模查询耗时:", time.Since(t1))
+		type BuyerAggStruct struct {
+			Buckets []struct {
+				Key            string `json:"key,omitempty"`
+				Doc_count      int64  `json:"doc_count,omitempty"`
+				BidAmountCount struct {
+					Value float32 `json:"value,omitempty"`
+				} `json:"bidAmountCount"`
+			} `json:"buckets"`
+		}
+		var buyerBuckets = BuyerAggStruct{}
+		// 处理成map 用于后面格式化数据
+		if aggs != nil && aggs["buyerBuckets"] != nil {
+			bs, err := aggs["buyerBuckets"].MarshalJSON()
+			if err != nil {
+				resp.ErrCode = -1
+				resp.ErrMsg = "获取数据异常"
+			} else {
+				if len(bs) == 0 {
+					resp.ErrMsg = "暂无数据"
+				} else {
+					err := json.Unmarshal(bs, &buyerBuckets)
+					logx.Info(err)
+					if len(buyerBuckets.Buckets) > 0 {
+						for _, v := range buyerBuckets.Buckets {
+							buyerMap[v.Key] = supplyDataStruct{
+								BidAmountCount: v.BidAmountCount.Value,
+								ProjectCount:   v.Doc_count,
+							}
+						}
+					}
 				}
-				bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
 			}
 		}
 	}
-	query_aggs = fmt.Sprintf(query_aggs, `"buyer"`, IC.C.BuyerCount, "%s")
-	if in.SortRule == 0 { //项目总数排序
-		query_sort = ""
+	ch := make(chan int, 10)
+	ch2 := make(chan int, 10)
+	wg := &sync.WaitGroup{}
+	for i := 0; i < len(resp.Data.List); i++ {
+		buyer := resp.Data.List[i].Buyer
+		// 先查缓存
+		if cacheData, ok := cacheMap[buyer]; ok {
+			resp.Data.List[i].BidAmountCount = cacheData.BidAmountCount
+			resp.Data.List[i].ProjectCount = cacheData.ProjectCount
+			resp.Data.List[i].BiddingCount = cacheData.BidCount
+			resp.Data.List[i].ContactCount = cacheData.ContactCount
+			continue
+		}
+		// 缓存里没有的再查数据补充
+		if supplyData, ok := buyerMap[buyer]; ok {
+			resp.Data.List[i].BidAmountCount = supplyData.BidAmountCount
+			resp.Data.List[i].ProjectCount = supplyData.ProjectCount
+		}
+		ch2 <- 1
+		wg.Add(1)
+		go func(list *bxbuyer.BuyerList, buyer string) {
+			defer func() {
+				<-ch2
+				wg.Done()
+			}()
+			list.ContactCount = GetProjectContactCount(buyer) // 补充联系人字段
+		}(resp.Data.List[i], buyer)
+		ch <- 1
+		wg.Add(1)
+		go func(list *bxbuyer.BuyerList, buyer string) {
+			defer func() {
+				<-ch
+				wg.Done()
+			}()
+			list.BiddingCount = GetNewBiddingCount(buyer)
+		}(resp.Data.List[i], buyer)
+
+	}
+	wg.Wait()
+	logx.Info("SupplyBuyerListData 整体耗时:", time.Since(start))
+
+	//得到所有数据,包括 redis里的,再存一下
+	go func(respList []*bxbuyer.BuyerList) {
+		for i := 0; i < len(respList); i++ {
+			tmp := supplyDataStruct{
+				ContactCount:   respList[i].ContactCount,
+				BidCount:       respList[i].BiddingCount,
+				ProjectCount:   respList[i].ProjectCount,
+				BidAmountCount: respList[i].BidAmountCount,
+			}
+			// 存redis
+			b, err := json.Marshal(tmp)
+			if err == nil {
+				redis.PutBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, respList[i].Buyer), &b, BuyerSupplyInfoRedisTime+GetRand(60))
+			}
+		}
+	}(resp.Data.List)
+
+	return resp
+}
+
+// 获取项目数量 采购单位规模
+func getBuyerProjectCache(buyer string) (rs *supplyDataStruct) {
+	bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerProjectInfoRedisKey, buyer))
+	if err == nil && bs != nil && len(*bs) > 0 {
+		if err := json.Unmarshal(*bs, &rs); err != nil {
+			logx.Info("获取redis缓存,序列化异常")
+		} else {
+			return rs
+		}
 	}
-	query_aggs = fmt.Sprintf(query_aggs, query_sort)
-	qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, query_aggs)
 	return
 }
 
-const (
-	P_INDEX      = "projectset"
-	P_TYPE       = "projectset"
-	P_redis_time = 15 * 24 * 60 * 60 //redis存15天
-	P_redis_key  = "buyerListCache"
-)
+// BuyerSupplyInfo 补充字段
+func BuyerSupplyInfo(buyerNames []string) (resp *bxbuyer.BuyerSupplyResp) {
+	resp = &bxbuyer.BuyerSupplyResp{}
+	start := time.Now()
+	// buyerNames
+	//buyerNames 是否存在缓存 数据
+	//如果没有 放到一个新的 []string
+	needSearchBuyer := []string{}
+	cacheMap := map[string]supplyDataStruct{}
+	buyerMap := map[string]supplyDataStruct{}
+	for i := 0; i < len(buyerNames); i++ {
+		bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, buyerNames[i]))
+		if err == nil && bs != nil && len(*bs) > 0 {
+			tmp := supplyDataStruct{}
+			if err := json.Unmarshal(*bs, &tmp); err == nil {
+				cacheMap[buyerNames[i]] = tmp // 拿到缓存的数据  采购规模 项目数量 联系人数量 招标动态数量
+			} else {
+				// 查缓存
+				cacheProject := getBuyerProjectCache(buyerNames[i])
+				if cacheProject != nil {
+					buyerMap[buyerNames[i]] = *cacheProject
+				} else {
+					needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查采购规模和项目数量
+				}
 
-//查询采购单位列表
-func GetBuyerList(qstr string, in *bxbuyer.BuyerListReq, isCache bool) (resp *bxbuyer.BuyerListResp) {
-	t1 := time.Now()
-	aggs := GetAggs(P_INDEX, P_TYPE, qstr)
-	resp = &bxbuyer.BuyerListResp{
-		Data: &bxbuyer.BuyerData{},
-	}
-	type GroupStruct struct {
-		Buckets []struct {
-			Key       string `json:"key,omitempty"`
-			Doc_count int64  `json:"doc_count,omitempty"`
-			Count     struct {
-				Value float64 `json:"value,omitempty"`
-			} `json:"count"`
-		} `json:"buckets"`
-	}
-	var group = GroupStruct{}
-	if aggs != nil && aggs["group_field"] != nil {
-		bs, err := aggs["group_field"].MarshalJSON()
-		if err != nil {
-			resp.ErrCode = -1
-			resp.ErrMsg = "获取数据异常"
+			}
 		} else {
-			if len(bs) == 0 {
-				resp.ErrMsg = "暂无数据"
+			// 查缓存
+			cacheProject := getBuyerProjectCache(buyerNames[i])
+			if cacheProject != nil {
+				buyerMap[buyerNames[i]] = *cacheProject
 			} else {
-				json.Unmarshal(bs, &group)
-				if len(group.Buckets) > 0 {
-					for _, v := range group.Buckets {
-						var list = &bxbuyer.BuyerList{}
-						list.Buyer = v.Key
-						list.Budget = v.Count.Value
-						list.PCount = v.Doc_count
-						resp.Data.List = append(resp.Data.List, list)
-					}
-				}
+				needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查采购规模和项目数量
 			}
 		}
+
 	}
-	resp.Data.Count = int64(len(resp.Data.List))
-	logx.Info("=---count---===", resp.Data.Count)
-	if len(resp.Data.List) > 0 {
-		var wg sync.WaitGroup
-		//省份和城市 是否查询已关注信息 是否查询已领取信息
-		//企业信用库qyxy_std 和es buyer库 查询省份和城市
-		var fiftyArr = []*bxbuyer.BuyerList{}
-		var buyerNames = []string{}
-		for bk, bv := range resp.Data.List {
-			fiftyArr = append(fiftyArr, bv)
-			buyerNames = append(buyerNames, bv.Buyer)
-			if (bk+1)%50 == 0 || len(resp.Data.List) == bk+1 {
-				wg.Add(1)
-				go func(wg *sync.WaitGroup, fiftyArr []*bxbuyer.BuyerList, buyerNames []string, icf, icr bool, userId, entUserId string) {
-					//省份城市 关注状态 领取状态
-					infoMap := GetBuyerInfo(buyerNames)
-					//关注状态
-					isFws := map[string]bool{}
-					if icf {
-						isFws = IsFollowd(buyerNames, userId)
-					}
-					//领取状态
-					isRws := map[string]string{}
-					if icr {
-						isRws = IsReceived(buyerNames, entUserId)
-					}
-					//log.Println("---:", isRws)
-					for _, fv := range fiftyArr {
-						fv.Province = infoMap[fv.Buyer].Province
-						fv.City = infoMap[fv.Buyer].City
-						if icf {
-							fv.IsFollowed = isFws[fv.Buyer]
-						}
-						if icr {
-							if isRws[fv.Buyer] != "" {
-								fv.RecId = isRws[fv.Buyer]
-								fv.IsReceived = true
+	if len(needSearchBuyer) > 0 {
+		t1 := time.Now()
+		query := SupplyDataQuery(buyerNames) // 项目数量、采购规模
+		// 聚合查
+		aggs := GetAggs(P_INDEX, P_TYPE, query)
+		logx.Info("查询语句:", query)
+		logx.Info("项目数量采购规模查询耗时:", time.Since(t1))
+		type BuyerAggStruct struct {
+			Buckets []struct {
+				Key            string `json:"key,omitempty"`
+				Doc_count      int64  `json:"doc_count,omitempty"`
+				BidAmountCount struct {
+					Value float32 `json:"value,omitempty"`
+				} `json:"bidAmountCount"`
+			} `json:"buckets"`
+		}
+		var buyerBuckets = BuyerAggStruct{}
+		// 处理成map 用于后面格式化数据
+		if aggs != nil && aggs["buyerBuckets"] != nil {
+			bs, err := aggs["buyerBuckets"].MarshalJSON()
+			if err != nil {
+				resp.ErrCode = -1
+				resp.ErrMsg = "获取数据异常"
+			} else {
+				if len(bs) == 0 {
+					resp.ErrMsg = "暂无数据"
+				} else {
+					err := json.Unmarshal(bs, &buyerBuckets)
+					logx.Info(err)
+					if len(buyerBuckets.Buckets) > 0 {
+						for _, v := range buyerBuckets.Buckets {
+							buyerMap[v.Key] = supplyDataStruct{
+								BidAmountCount: v.BidAmountCount.Value,
+								ProjectCount:   v.Doc_count,
 							}
 						}
 					}
-					wg.Done()
-				}(&wg, fiftyArr, buyerNames, in.IsCheckFollow, in.IsCheckReceive, in.UserId, in.EntUserId)
-				fiftyArr = []*bxbuyer.BuyerList{}
-				buyerNames = []string{}
+				}
 			}
 		}
-		wg.Wait()
 	}
-	logx.Info("耗时;", time.Since(t1).Seconds(), time.Since(t1).Microseconds())
+
+	ch := make(chan int, 10)
+	ch2 := make(chan int, 10)
+	wg := &sync.WaitGroup{}
+	for i := 0; i < len(buyerNames); i++ {
+		buyer := buyerNames[i]
+		resp.Data = append(resp.Data, &bxbuyer.SupplyData{
+			Buyer: buyer,
+		})
+		// 先查缓存
+		if cacheData, ok := cacheMap[buyer]; ok {
+			resp.Data[i].BidAmountCount = cacheData.BidAmountCount
+			resp.Data[i].ProjectCount = cacheData.ProjectCount
+			resp.Data[i].BiddingCount = cacheData.BidCount
+			resp.Data[i].ContactCount = cacheData.ContactCount
+			continue
+		}
+		// 缓存里没有的再取查数据补充
+		// 补充字段
+		if supplyData, ok := buyerMap[buyer]; ok {
+			resp.Data[i].BidAmountCount = supplyData.BidAmountCount
+			resp.Data[i].ProjectCount = supplyData.ProjectCount
+		}
+		ch2 <- 1
+		wg.Add(1)
+		go func(list *bxbuyer.SupplyData, buyer string) {
+			defer func() {
+				<-ch2
+				wg.Done()
+			}()
+			list.ContactCount = GetProjectContactCount(buyer) // 补充联系人字段
+		}(resp.Data[i], buyer)
+		ch <- 1
+		wg.Add(1)
+		go func(list *bxbuyer.SupplyData, buyer string) {
+			defer func() {
+				<-ch
+				wg.Done()
+			}()
+			list.BiddingCount = GetNewBiddingCount(buyer)
+		}(resp.Data[i], buyer)
+
+	}
+	wg.Wait()
+	logx.Info(" 整体耗时:", time.Since(start))
+	//得到所有数据,包括 redis里的,再存一下
+	go func(respList []*bxbuyer.SupplyData) {
+		for i := 0; i < len(respList); i++ {
+			tmp := supplyDataStruct{
+				ContactCount:   respList[i].ContactCount,
+				BidCount:       respList[i].BiddingCount,
+				ProjectCount:   respList[i].ProjectCount,
+				BidAmountCount: respList[i].BidAmountCount,
+			}
+			// 存redis
+			b, err := json.Marshal(tmp)
+			if err == nil {
+				redis.PutBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, respList[i].Buyer), &b, BuyerSupplyInfoRedisTime+GetRand(60))
+			}
+		}
+	}(resp.Data)
 	return
 }
 
-//聚合查询
+func GetProjectContactCount(buyerName string) int64 {
+	start := time.Now()
+	list := []string{}
+	searchSql := fmt.Sprintf(`{"query":{"bool":{"filter":[{"term":{"buyer":"%s"}}]}},"_source":["list.buyerperson","list.buyertel"],"sort":[{"zbtime":"desc"}],"size":500}`, buyerName)
+	projectList := elastic.Get(P_INDEX, P_TYPE, searchSql)
+	logx.Info("GetProjectContactCount esget 耗时", time.Since(start), searchSql)
+	if projectList == nil || len(*projectList) == 0 {
+		return 0
+	}
+	//根据联系人和联系方式展示
+	//多个项目同一个联系人;只展示最新项目
+	//一个项目多个联系人;拆分展示
+	repeatContacts := map[string]bool{}
+	for _, rowData := range *projectList {
+		mapList, ok := rowData["list"].([]interface{})
+		if !ok || len(mapList) == 0 {
+			continue
+		}
+		for i := len(mapList) - 1; i >= 0; i-- {
+			thisMsg, ok := mapList[i].(map[string]interface{})
+			if !ok || len(thisMsg) == 0 {
+				continue
+			}
+			thisPhone, thisPerson := "", ""
+			if thisPhone, _ = thisMsg["buyertel"].(string); thisPhone != "" {
+				thisPerson, _ = thisMsg["buyerperson"].(string)
+			}
+			if thisPhone == "" { //联系人为空则不展示 dev4.7.3联系人为空展示此记录
+				continue
+			}
+			//一个项目只选取一条公告联系人
+			thisAddPerson := false
+			//名字中多个联系人拆分
+			for _, name := range strings.Split(thisPerson, ",") {
+				thisName := strings.TrimSpace(name)
+				if thisName == "" && thisAddPerson { //联系人为空则不展示
+					continue
+				}
+				thisAddPerson = true
+				repeatKey := fmt.Sprintf("%s_%s", thisName, thisPhone)
+				if repeatContacts[repeatKey] {
+					continue
+				}
+				repeatContacts[repeatKey] = true
+				list = append(list, thisPhone)
+			}
+			if thisAddPerson {
+				break
+			}
+		}
+	}
+	logx.Info("GetProjectContactCount 单次耗时:", time.Since(start))
+	return int64(len(list))
+}
+func GetNewBiddingCount(buyer string) int64 {
+	start := time.Now()
+	if buyer == "" {
+		return 0
+	}
+	var mustQuery []string
+	st, et := getTimeRange()
+	mustQuery = append(mustQuery, fmt.Sprintf(`{"range":{"publishtime":{"gte":%d,"lte":%d}}}`, st.Unix(), et.Unix()))
+	mustQuery = append(mustQuery, fmt.Sprintf(`{"term": {"buyer": "%s"}}`, buyer))
+	aa := fmt.Sprintf(`{"query":{"bool":{"must":[%s]}}}`, strings.Join(mustQuery, ","))
+	count := elastic.Count(biddingIndex, biddingType, aa)
+	logx.Info("GetNewBiddingCount 单次耗时:", buyer, time.Since(start))
+	return count
+}
+
+// 聚合查询
 func GetAggs(index, itype, query string) (aggs map[string]json.RawMessage) {
 	aggs, _, _ = elastic.GetAggs(index, itype, query)
 	return
@@ -238,7 +702,7 @@ type buyerInfo struct {
 	City     string
 }
 
-//潜在客户 获取省份和城市
+// 潜在客户 获取省份和城市
 func GetBuyerInfo(buyerNames []string) (infoMap map[string]buyerInfo) {
 	var buyerInfoQuery = `{"query": {"bool": {"must": [{"terms": {"%s": [%s]}}],"must_not": [],"should": []}},"from": 0,"size": 50,"sort": []}`
 	query := fmt.Sprintf(buyerInfoQuery, "buyer_name", `"`+strings.Join(buyerNames, `","`)+`"`)
@@ -260,7 +724,7 @@ func GetBuyerInfo(buyerNames []string) (infoMap map[string]buyerInfo) {
 }
 
 var fc = "follow_customer" //关注客户表
-//采购单位是否作为客户已被关注
+// 采购单位是否作为客户已被关注
 func IsFollowd(buyerNames []string, userId string) (isFws map[string]bool) {
 	queryMap := map[string]interface{}{
 		"userId": userId,
@@ -269,17 +733,15 @@ func IsFollowd(buyerNames []string, userId string) (isFws map[string]bool) {
 		},
 	}
 	list, ok := IC.Mgo.Find(fc, queryMap, `{"_id":1}`, nil, false, -1, -1)
-	if ok && list != nil {
-		if len(*list) > 0 {
-			isFws = map[string]bool{}
-			for _, lv := range *list {
-				if MC.ObjToString(lv["name"]) != "" {
-					isFws[MC.ObjToString(lv["name"])] = true
-				}
+	if ok && len(*list) > 0 {
+		isFws = map[string]bool{}
+		for _, lv := range *list {
+			if MC.ObjToString(lv["name"]) != "" {
+				isFws[MC.ObjToString(lv["name"])] = true
 			}
 		}
 	} else {
-		logx.Info("采购单位是否已关注信息异常")
+		logx.Info("采购单位是否已关注信息异常  or  未查到数据")
 	}
 	return
 }
@@ -289,9 +751,11 @@ var (
 	Entniche_user_customer = "entniche_user_customer"
 )
 
-//领取状态
+// 领取状态
 func IsReceived(buyerNames []string, entUserId string) (isRws map[string]string) {
 	//新加领取的客户id----保证领取的唯一性
+	aa := fmt.Sprintf("SELECT ecn.id,  ecn.name  FROM %s ecn,%s  euu WHERE ecn.id = euu.customer_id AND euu.user_id =? AND ecn.`name` IN  ('%s') AND (euu.source_type =1 or euu.source_type=4)", Entniche_customer, Entniche_user_customer, strings.Join(buyerNames, "','"))
+	log.Println(aa)
 	receInfos := IC.MainMysql.SelectBySql(fmt.Sprintf("SELECT ecn.id,  ecn.name  FROM %s ecn,%s  euu WHERE ecn.id = euu.customer_id AND euu.user_id =? AND ecn.`name` IN  ('%s') AND (euu.source_type =1 or euu.source_type=4)", Entniche_customer, Entniche_user_customer, strings.Join(buyerNames, "','")), entUserId)
 	if receInfos != nil {
 		if len(*receInfos) > 0 {
@@ -308,9 +772,9 @@ func IsReceived(buyerNames []string, entUserId string) (isRws map[string]string)
 	return
 }
 
-//是否为空请求
+// 是否为空请求
 func CheckEmpty(in *bxbuyer.BuyerListReq) bool {
-	if in.BuyerName == "" && len(in.BuyerClass) == 0 && len(in.Province) == 0 && len(in.City) == 0 && len(in.Industry) == 0 && in.BusinessScope == "" && len(in.Customer) == 0 {
+	if in.BuyerName == "" && len(in.BuyerClass) == 0 && len(in.Province) == 0 && len(in.City) == 0 && in.IsContact == 0 {
 		return true
 	}
 	return false
@@ -318,26 +782,8 @@ func CheckEmpty(in *bxbuyer.BuyerListReq) bool {
 
 //缓存数据查询
 
-//获取采购单位查询query
+// 获取采购单位查询query
 func BuyerListRedisCacheQuery() (qstr string) {
-	query := `{"size": 0,"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer": ""}}],"should":[],"minimum_should_match": %d}},%s}`
-	//21.1.20  为和画像保持一致  数据组要求 budget 改成 bidamount
-	query_aggs := `"aggs": {"group_field": {"terms": {"field": %s,"size": %d%s},"aggs": {"count": {"sum": {"field": "bidamount"}}}}}`
-	query_sort := `,"order": {"count": "desc"}`
-	musts := []string{}
-	boolsNum := 0
-	entcustomerClass := `{"terms":{"buyer":[`
-	for k, v := range IC.C.DefaultBuyerNames {
-		if k > 0 {
-			entcustomerClass += `,`
-		}
-		entcustomerClass += `"` + v + `"`
-	}
-	entcustomerClass += `]}}`
-	musts = append(musts, entcustomerClass)
-	query_aggs = fmt.Sprintf(query_aggs, `"buyer"`, len(IC.C.DefaultBuyerNames), "%s")
-	query_aggs = fmt.Sprintf(query_aggs, query_sort)
-	qstr = fmt.Sprintf(query, strings.Join(musts, ","), boolsNum, query_aggs)
-	logx.Info("qstr:", qstr)
-	return
+	qstr = `{"size":%d,"query":{"bool":{"must":[],"must_not":[{"term":{"buyer_name":""}}]}},"sort":[{"updatetime":"desc"}]}`
+	return fmt.Sprintf(qstr, IC.C.BuyerSearchLimit)
 }

+ 12 - 0
jyBXBuyer/rpc/model/util.go

@@ -0,0 +1,12 @@
+package model
+
+import (
+	"math/rand"
+	"time"
+)
+
+func GetRand(n int) int {
+	randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
+	// 获取一个范围在 [0, ) 的随机整数
+	return randGen.Intn(n)
+}

+ 93 - 0
jyBXBuyer/rpc/service/service.go

@@ -0,0 +1,93 @@
+package service
+
+import (
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	elastic "app.yhyue.com/moapp/jybase/es"
+	"fmt"
+	"jyBXBuyer/rpc/type/bxbuyer"
+	"log"
+	"math/rand"
+	"time"
+)
+
+func GetRelatesInfo(in *bxbuyer.RelatesInformationReq) *bxbuyer.RelatesInformationResp {
+	relatesInfo := &bxbuyer.RelatesInformationResp{Data: &bxbuyer.RelatesInformation{BiddingList: []*bxbuyer.InfoList{}, BuyerList: []*bxbuyer.InfoList{}}}
+	if err := Checking(in); err != nil {
+		relatesInfo.ErrCode = -1
+		relatesInfo.ErrMsg = err.Error()
+		return relatesInfo
+	}
+	query := `{"query": {"bool": {"must": [{"exists": {"field": "name"}}%s%s}]}}%s%s}`
+	//获取随机数
+	// 使用当前时间作为随机数生成器的种子
+	randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
+	// 获取一个范围在 [0, 100) 的随机整数
+	start := randGen.Intn(100)
+	//关联采购单位:同省份采购单位名称随机展示30个
+	if in.Area != "" {
+		in.Area = fmt.Sprintf(`,{"term": {"province": "%s"}`, in.Area)
+	}
+	//
+	if in.City != "" {
+		in.City = fmt.Sprintf(`,{"term": {"city": "%s"}}`, in.City)
+	}
+	countQuery := fmt.Sprintf(query, in.Area, in.City, "", "")
+	if c := elastic.Count("buyer", "buyer", countQuery); c > 0 {
+		//数据量不够30
+		if c-in.BuyerCount < int64(start) {
+			start = common.If(c-in.BuyerCount > 0, int(c-in.BuyerCount), 0).(int)
+		}
+		fromQuery := fmt.Sprintf(`,"from": %d`, start)
+		sizeQuery := fmt.Sprintf(`,"size": %d`, in.BuyerCount)
+		buyerQuery := fmt.Sprintf(query, in.Area, in.City, fromQuery, sizeQuery)
+		log.Println("buyerQuery:", buyerQuery)
+		buyerList := elastic.Get("buyer", "buyer", buyerQuery)
+		if len(*buyerList) > 0 {
+			log.Println("--------:", len(*buyerList))
+			var buyers []*bxbuyer.InfoList
+			for _, b := range *buyerList {
+				buyers = append(buyers, &bxbuyer.InfoList{
+					Name: common.ObjToString(b["name"]),
+					Id:   encrypt.EncodeArticleId2ByCheck(common.ObjToString(b["_id"])),
+				})
+			}
+			relatesInfo.Data.BuyerList = buyers
+		}
+	}
+	//关联动态:采购单位标讯动态
+	if in.Buyer != "" {
+		biddingQuery := fmt.Sprintf(`{"query":{"bool":{"must":[{"term":{"buyer":"%s"}}],"must_not":[{"terms":{"subtype":["采购意向","拟建"]}}]}},"sort": [{"publishtime": "desc"}],"from":0,"size":%d }`, in.Buyer, in.BuyerCount)
+		biddingList := elastic.Get("bidding", "bidding", biddingQuery)
+		if len(*biddingList) > 0 {
+			var biddingInfos []*bxbuyer.InfoList
+			for _, b := range *biddingList {
+				publishtime := common.Int64All(b["publishtime"])
+				biddingInfos = append(biddingInfos, &bxbuyer.InfoList{
+					Name:        common.ObjToString(b["title"]),
+					Id:          encrypt.EncodeArticleId2ByCheck(common.ObjToString(b["id"])),
+					PublishTime: date.FormatDateByInt64(&publishtime, date.Date_Small_Layout),
+				})
+			}
+			relatesInfo.Data.BiddingList = biddingInfos
+		}
+	}
+	log.Println("relatesinfo:", relatesInfo)
+	return relatesInfo
+}
+
+func Checking(in *bxbuyer.RelatesInformationReq) error {
+	if in.Buyer == "" && in.Area == "" {
+		return fmt.Errorf("参数异常")
+	}
+	//默认30个采购单位
+	if in.BuyerCount == 0 {
+		in.BuyerCount = 30
+	}
+	//默认10条招标信息
+	if in.BiddingCount == 0 {
+		in.BiddingCount = 10
+	}
+	return nil
+}

Plik diff jest za duży
+ 815 - 116
jyBXBuyer/rpc/type/bxbuyer/bxbuyer.pb.go


+ 77 - 1
jyBXBuyer/rpc/type/bxbuyer/bxbuyer_grpc.pb.go

@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
 // - protoc-gen-go-grpc v1.2.0
-// - protoc             v3.15.5
+// - protoc             v3.19.4
 // source: bxbuyer.proto
 
 package bxbuyer
@@ -24,6 +24,10 @@ const _ = grpc.SupportPackageIsVersion7
 type BxbuyerClient interface {
 	//采购单位搜索
 	BuyerList(ctx context.Context, in *BuyerListReq, opts ...grpc.CallOption) (*BuyerListResp, error)
+	// 采购单位搜索补充信息 招标动态数量 、历史联系人数量、项目数量、采购规模
+	BuyerSupplyInfo(ctx context.Context, in *BuyerSupplyInfoReq, opts ...grpc.CallOption) (*BuyerSupplyResp, error)
+	//采购单位画像 关联信息
+	RelatesInfo(ctx context.Context, in *RelatesInformationReq, opts ...grpc.CallOption) (*RelatesInformationResp, error)
 }
 
 type bxbuyerClient struct {
@@ -43,12 +47,34 @@ func (c *bxbuyerClient) BuyerList(ctx context.Context, in *BuyerListReq, opts ..
 	return out, nil
 }
 
+func (c *bxbuyerClient) BuyerSupplyInfo(ctx context.Context, in *BuyerSupplyInfoReq, opts ...grpc.CallOption) (*BuyerSupplyResp, error) {
+	out := new(BuyerSupplyResp)
+	err := c.cc.Invoke(ctx, "/bxbuyer.Bxbuyer/BuyerSupplyInfo", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bxbuyerClient) RelatesInfo(ctx context.Context, in *RelatesInformationReq, opts ...grpc.CallOption) (*RelatesInformationResp, error) {
+	out := new(RelatesInformationResp)
+	err := c.cc.Invoke(ctx, "/bxbuyer.Bxbuyer/RelatesInfo", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // BxbuyerServer is the server API for Bxbuyer service.
 // All implementations must embed UnimplementedBxbuyerServer
 // for forward compatibility
 type BxbuyerServer interface {
 	//采购单位搜索
 	BuyerList(context.Context, *BuyerListReq) (*BuyerListResp, error)
+	// 采购单位搜索补充信息 招标动态数量 、历史联系人数量、项目数量、采购规模
+	BuyerSupplyInfo(context.Context, *BuyerSupplyInfoReq) (*BuyerSupplyResp, error)
+	//采购单位画像 关联信息
+	RelatesInfo(context.Context, *RelatesInformationReq) (*RelatesInformationResp, error)
 	mustEmbedUnimplementedBxbuyerServer()
 }
 
@@ -59,6 +85,12 @@ type UnimplementedBxbuyerServer struct {
 func (UnimplementedBxbuyerServer) BuyerList(context.Context, *BuyerListReq) (*BuyerListResp, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method BuyerList not implemented")
 }
+func (UnimplementedBxbuyerServer) BuyerSupplyInfo(context.Context, *BuyerSupplyInfoReq) (*BuyerSupplyResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method BuyerSupplyInfo not implemented")
+}
+func (UnimplementedBxbuyerServer) RelatesInfo(context.Context, *RelatesInformationReq) (*RelatesInformationResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RelatesInfo not implemented")
+}
 func (UnimplementedBxbuyerServer) mustEmbedUnimplementedBxbuyerServer() {}
 
 // UnsafeBxbuyerServer may be embedded to opt out of forward compatibility for this service.
@@ -90,6 +122,42 @@ func _Bxbuyer_BuyerList_Handler(srv interface{}, ctx context.Context, dec func(i
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Bxbuyer_BuyerSupplyInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(BuyerSupplyInfoReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BxbuyerServer).BuyerSupplyInfo(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bxbuyer.Bxbuyer/BuyerSupplyInfo",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BxbuyerServer).BuyerSupplyInfo(ctx, req.(*BuyerSupplyInfoReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Bxbuyer_RelatesInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(RelatesInformationReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BxbuyerServer).RelatesInfo(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bxbuyer.Bxbuyer/RelatesInfo",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BxbuyerServer).RelatesInfo(ctx, req.(*RelatesInformationReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // Bxbuyer_ServiceDesc is the grpc.ServiceDesc for Bxbuyer service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -101,6 +169,14 @@ var Bxbuyer_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "BuyerList",
 			Handler:    _Bxbuyer_BuyerList_Handler,
 		},
+		{
+			MethodName: "BuyerSupplyInfo",
+			Handler:    _Bxbuyer_BuyerSupplyInfo_Handler,
+		},
+		{
+			MethodName: "RelatesInfo",
+			Handler:    _Bxbuyer_RelatesInfo_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "bxbuyer.proto",

+ 8 - 4
jyBXCore/api/etc/bxcore-api.yaml

@@ -17,10 +17,14 @@ Core:
 AppId: 10000
 MgoLogsName: jybxcore_logs
 MgoLogsCount: 500
-DetailMosaicTxt: 
+DetailMosaicTxt: 免费注册即可查看
 SearchMosaic:
+  buyerPerson: true
+  buyerTel: true
+  winnerPerson: true
+  winnerTel: true
+  agencyPerson: true
+  agencyTel: true
   budget: true
   bidAmount: true
-  buyer: true
-  winner: true
-  bidOpenTime: true
+

+ 1 - 7
jyBXCore/api/internal/config/config.go

@@ -17,13 +17,7 @@ type Config struct {
 	MgoLogsName     string
 	MgoLogsCount    int
 	DetailMosaicTxt string
-	SearchMosaic    struct {
-		Budget      bool `json:"budget"`
-		BidAmount   bool `json:"bidAmount"`
-		Buyer       bool `json:"buyer"`
-		Winner      bool `json:"winner"`
-		BidOpenTime bool `json:"bidOpenTime"`
-	}
+	SearchMosaic    map[string]bool
 }
 
 type Db struct {

+ 6 - 2
jyBXCore/api/internal/logic/searchListLogic.go

@@ -93,9 +93,13 @@ func (l *SearchListLogic) SearchList(req *types.SearchReq) (resp *types.CommonRe
 			d := common.StructToMapMore(v)
 			for name, t1 := range sm {
 				ts, _ := t1.(bool)
-				if v1, ok := d[name]; ok && v1 != "" && v1 != 0 && ts {
-					d[name] = detailMosaicTxt
+				if !ts {
+					continue
 				}
+				d[name] = detailMosaicTxt
+				//if v1, ok := d[name]; ok && v1 != "" && v1 != 0 && ts {
+				//	d[name] = detailMosaicTxt
+				//}
 			}
 			data = append(data, d)
 		}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików