package service import ( "context" "database/sql" "encoding/json" "fmt" "math" "sort" "strings" "time" . "app.yhyue.com/moapp/jybase/common" . "app.yhyue.com/moapp/jybase/date" "app.yhyue.com/moapp/jybase/encrypt" . "app.yhyue.com/moapp/jybase/es" "app.yhyue.com/moapp/jybase/redis" . "app.yhyue.com/moapp/jybase/sort" . "bp.jydev.jianyu360.cn/CRM/networkManage/api/common" "bp.jydev.jianyu360.cn/CRM/networkManage/api/internal/types" "github.com/shopspring/decimal" "github.com/zeromicro/go-zero/core/logx" ) const ( NetworkManageAllProjectKey = "networkManage_allProject_%d" NetworkManageList = "networkManage_networkList_%d_%s" ) var Network = &network{} type network struct { } type networkTree struct { Count int64 `json:"count"` Name string `json:"name"` Children []*networkTreeChild `json:"children"` } type networkTreeChild struct { Count int64 `json:"count"` Id int64 `json:"id"` CompanyId string `json:"companyId"` CompanyName string `json:"companyName"` Type string `json:"type"` CreateTime string `json:"createTime"` } func (n *networkTree) Len() int { return len(n.Children) } func (n *networkTree) Less(i, j int) bool { if n.Name == "甲方" { return n.Children[i].CompanyName < n.Children[j].CompanyName } it, err1 := time.ParseInLocation(Date_Full_Layout, n.Children[i].CreateTime, time.Local) if err1 != nil { return true } jt, err2 := time.ParseInLocation(Date_Full_Layout, n.Children[j].CreateTime, time.Local) if err2 != nil { return true } return it.Unix() < jt.Unix() } func (n *networkTree) Swap(i, j int) { n.Children[i], n.Children[j] = n.Children[j], n.Children[i] } type projectInfo struct { BuyerCount int64 ProjectCount int64 ProjectAmount float64 ExportId []string IdNames []*idName } type firstpartyNetwork struct { CompanyId string CompanyName string Name string } type idName struct { Id string Name string } type introduceOwnerProject struct { Networks []*myNetwork FirstpartyNetwork map[string][]*firstpartyNetwork Firstparty map[string]*projectInfo Supplier map[string]*projectInfo Adiffb map[string]*projectInfo Agency map[string]*projectInfo Middleman map[string]*projectInfo } type myNetwork struct { Id int64 Company_id string Company_name string Qyxy_id string Itype int64 Person string Phone string Buyer_count int64 Project_count int64 Relate_buyer_id string Relate_buyer_name string Relate_project_id string Create_time string } type nodeTree struct { NAME string ID string SZ_PID0 string SZ_PID1 string SZ_PID2 string SZ_PID3 string CODE string PCODE string DATACOUNT int64 SZ_LEVEL int SZ_LEAF int TYPE string MYID string MYTYPE string } type nodeTrees []*nodeTree func (n *nodeTrees) Len() int { return len(*n) } func (n *nodeTrees) Less(i, j int) bool { if (*n)[i].PCODE == (*n)[j].PCODE { return (*n)[i].CODE < (*n)[j].CODE } return (*n)[i].PCODE < (*n)[j].PCODE } func (n *nodeTrees) Swap(i, j int) { (*n)[i], (*n)[j] = (*n)[j], (*n)[i] } // 人脉库-添加/修改人脉 func (n *network) AddOrUpdate(in *types.AddOrUpdateReq) *types.Reply { reply := &types.Reply{Data: map[string]interface{}{ "status": 0, }} if in.Type != "middleman" && in.Company_id == "" { return reply } if in.Company_name == "" { in.Company_name = "未填写" } nowFormat := NowFormat(Date_Full_Layout) var saveIntroduce = func(tx *sql.Tx, cid int64, isUpdate bool) bool { if in.Type != "middleman" { return true } else if in.Introduce_owner_id == "" || in.Introduce_project_id == "" { return false } values := []interface{}{} ioi := strings.Split(in.Introduce_owner_id, ",") ioqi := strings.Split(in.Introduce_owner_qyxy_id, ",") ion := strings.Split(in.Introduce_owner_name, ",") if len(ioi) != len(ion) || len(ioi) != len(ioqi) { return false } for k, v := range ioi { values = append(values, in.PositionId, in.EntId, in.EntDeptId, in.EntUserId, cid, ioqi[k], v, ion[k], 1, nowFormat) } ipi := strings.Split(in.Introduce_project_id, ",") ipn := strings.Split(in.Introduce_project_name, ",") if len(ipi) != len(ipn) { return false } for k, v := range ipi { values = append(values, in.PositionId, in.EntId, in.EntDeptId, in.EntUserId, cid, nil, v, ipn[k], 2, nowFormat) } var r2 int64 if isUpdate { r2 = CrmMysql.UpdateOrDeleteBySqlByTx(tx, `delete from crm.connection_introduce where connection_id=? and position_id=?`, in.Id, in.PositionId) } r3, _ := CrmMysql.InsertBatchByTx(tx, "crm.connection_introduce", []string{"position_id", "ent_id", "ent_dept_id", "ent_user_id", "connection_id", "qyxy_id", "relate_id", "relate_name", "itype", "create_time"}, values) return r2 >= 0 && r3 > 0 } itype := n.TypeStrConvert(in.Type) if in.Id > 0 { if CrmMysql.ExecTx("更新人脉", func(tx *sql.Tx) bool { if in.Company_id != "" { count := CrmMysql.CountBySql(`select count(1) as count from crm.connection where position_id=? and company_id=? and itype=? and id<>? and status=1`, in.PositionId, in.Company_id, itype, in.Id) if count == -1 { return false } else if count > 0 { reply.Data = map[string]interface{}{ "status": -1, } return false } } r1 := CrmMysql.UpdateOrDeleteBySqlByTx(tx, `update crm.connection set company_name=?,company_id=?,contact_person=?,contact_phone=?,update_time=? where id=? and position_id=?`, in.Company_name, in.Company_id, in.Contact_person, in.Contact_phone, nowFormat, in.Id, in.PositionId) return r1 >= 0 && saveIntroduce(tx, in.Id, true) }) { reply.Data = map[string]interface{}{ "status": 1, } } } else { if in.Company_id != "" { count := CrmMysql.CountBySql(`select count(1) as count from crm.connection where position_id=? and company_id=? and itype=? and status=1`, in.PositionId, in.Company_id, itype) if count == -1 { return reply } else if count > 0 { reply.Data = map[string]interface{}{ "status": -1, } return reply } } var r1 int64 if CrmMysql.ExecTx("新增人脉", func(tx *sql.Tx) bool { _, r1 = CrmMysql.InsertBatchByTx(tx, "crm.connection", []string{"position_id", "ent_id", "ent_dept_id", "ent_user_id", "itype", "company_name", "company_id", "qyxy_id", "contact_person", "contact_phone", "status", "create_time", "update_time"}, []interface{}{in.PositionId, in.EntId, in.EntDeptId, in.EntUserId, itype, in.Company_name, in.Company_id, in.Qyxy_id, in.Contact_person, in.Contact_phone, 1, nowFormat, nowFormat}) return r1 > 0 && saveIntroduce(tx, r1, false) }) { reply.Data = map[string]interface{}{ "status": 1, "id": r1, } } } n.DeleteCache(in.PositionId) return reply } // 人脉库-业主名称联想 func (n *network) Associate(in *types.AssociateReq) (reply *types.Reply) { //类型;firstparty:甲方 supplier:供应商 adiffb:同甲异业 middleman:中间人 middleman_owner:中间人-业主 middleman_project:中间人-项目 agency:招标代理机构 res := []map[string]string{} reply = &types.Reply{Data: res} in.Name = strings.TrimSpace(in.Name) if in.Name == "" { return } pageSize := 10 if in.Type == "adiffb" { businessType := strings.Split(FindBusiness(in.EntId, in.MgoUserId), ",") if len(businessType) > 0 { args := []interface{}{in.EntName} wh, newArgs := NetworkCom.WhArgs(businessType) args = append(args, newArgs...) q := `select DISTINCT winner_id,winner from information.transaction_info_all where buyer_id in (select buyer_id from information.transaction_info_all where has(winner, ?) and buyer_id<>'') and hasAny(topscopeclass,[` + wh + `])=0 ORDER BY project_id` rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) } else { repeat := map[string]bool{} ids := []string{} for rows.Next() { var ( winner_id []string winner []string ) if err := rows.Scan(&winner_id, &winner); err != nil { logx.Error(err) continue } for k, v := range winner { if repeat[v] || !strings.Contains(v, in.Name) { continue } repeat[v] = true if k >= len(winner_id) { continue } ids = append(ids, winner_id[k]) res = append(res, map[string]string{ "company_name": v, "company_id": winner_id[k], }) if len(res) == pageSize { break } } } rows.Close() if err := rows.Err(); err != nil { logx.Error(err) } qyxyId := n.GetQyxyId(ids) for _, v := range res { v["qyxy_id"] = qyxyId[v["company_id"]] } } } } else { must := []string{fmt.Sprintf(`{"multi_match":{"query":"%s","type":"phrase","fields":["company_name"]}}`, in.Name)} switch in.Type { case "firstparty": must = append(must, fmt.Sprintf(`{"terms":{"company_label":["%s"]}}`, strings.Join(NetworkCom.GetEntTagSeat(2), `","`))) must = append(must, `{"terms":{"company_unit_type":[1,2]}}`) case "supplier": must = append(must, fmt.Sprintf(`{"terms":{"company_label":["%s"]}}`, strings.Join(NetworkCom.GetEntTagSeat(2), `","`))) must = append(must, `{"term":{"company_unit_type":3}}`) case "middleman_owner": must = append(must, `{"terms":{"company_unit_type":[1,2]}}`) case "agency": must = append(must, `{"term":{"company_unit_type":4}}`) } q := fmt.Sprintf(`{"query":{"bool":{"must":[%s]}},"size":%d,"_source":["id","company_id","company_name"]}`, strings.Join(must, ","), pageSize) logx.Info("人脉库-业主名称联想", q) datas := VarEs.Get("ent_info", "ent_info", q) if datas != nil { for _, v := range *datas { res = append(res, map[string]string{ "company_name": ObjToString(v["company_name"]), "company_id": ObjToString(v["id"]), "qyxy_id": ObjToString(v["company_id"]), }) } } } reply.Data = res return } // 人脉库-全部人脉项目 func (n *network) AllProject(in *types.AllprojectReq) (reply *types.Reply) { reply = &types.Reply{} key := fmt.Sprintf(NetworkManageAllProjectKey, in.PositionId) rbt, rerr := redis.GetNewBytes("newother", key) if rerr == nil && rbt != nil { json.Unmarshal(*rbt, &reply) return } businessType := strings.Split(FindBusiness(in.EntId, in.MgoUserId), ",") var count int64 var list []*networkTree firstpartyChild := map[string][]*firstpartyNetwork{} if in.Id != "" { if in.Type == "firstparty" { fpn := n.FirstpartyNetwork(in.Name, []string{in.Id}) if fpn[in.Id] != nil { firstparty := n.Introduce_Firstparty(fpn, businessType) nameIndex := map[string]int{} for _, v := range fpn[in.Id] { if _, ok := nameIndex[v.Name]; !ok { nameIndex[v.Name] = len(list) list = append(list, &networkTree{ Name: v.Name, }) } ntc := &networkTreeChild{ CompanyName: v.CompanyName, CompanyId: v.CompanyId, Type: "firstparty", } if firstparty[v.CompanyId] != nil { ntc.Count = firstparty[v.CompanyId].ProjectCount } count++ list[nameIndex[v.Name]].Count += ntc.Count list[nameIndex[v.Name]].Children = append(list[nameIndex[v.Name]].Children, ntc) } } } } else { args := []interface{}{in.PositionId, in.PositionId, in.PositionId} sqlAppend1 := "" if in.Name != "" { sqlAppend1 += ` and a.company_name like ?` args = append(args, "%"+in.Name+"%") } aio := n.AllIntroduceOwner(sqlAppend1, "", args, true, businessType) firstpartyChild = aio.FirstpartyNetwork list = []*networkTree{ &networkTree{ Name: "甲方", Children: []*networkTreeChild{}, }, &networkTree{ Name: "供应商/渠道", Children: []*networkTreeChild{}, }, &networkTree{ Name: "同甲异业渠道", Children: []*networkTreeChild{}, }, &networkTree{ Name: "中间人", Children: []*networkTreeChild{}, }, &networkTree{ Name: "招标代理", Children: []*networkTreeChild{}, }, } // for _, v := range aio.Networks { if v.Itype <= 0 || v.Itype > int64(len(list)) { return } ntc := &networkTreeChild{ Id: v.Id, CompanyName: v.Company_name, CompanyId: v.Company_id, Type: n.TypeIntConvert(v.Itype), CreateTime: v.Create_time, } switch v.Itype { case 1: if aio.Firstparty[v.Company_id] != nil { ntc.Count = aio.Firstparty[v.Company_id].ProjectCount } case 2: if aio.Supplier[v.Company_id] != nil { ntc.Count = aio.Supplier[v.Company_id].ProjectCount } case 3: if aio.Adiffb[v.Company_id] != nil { ntc.Count = aio.Adiffb[v.Company_id].ProjectCount } case 4: if v.Relate_buyer_id != "" { for _, v := range strings.Split(v.Relate_buyer_id, ",") { if aio.Middleman[v] != nil { ntc.Count++ } } } case 5: if aio.Agency[v.Company_id] != nil { ntc.Count = aio.Agency[v.Company_id].ProjectCount } } count += ntc.Count list[v.Itype-1].Count += ntc.Count list[v.Itype-1].Children = append(list[v.Itype-1].Children, ntc) } } parentConvList := &nodeTrees{} convList := &nodeTrees{} for _, v := range list { pm := &nodeTree{ CODE: v.Name, NAME: v.Name, SZ_PID0: v.Name, SZ_LEVEL: 0, DATACOUNT: 0, } if len(v.Children) > 0 { pm.SZ_LEAF = 0 } else { pm.SZ_LEAF = 1 } sort.Sort(v) id, pType, pMyType, pMyId := "", "", "", "" for _, vv := range v.Children { myId := vv.CompanyId if vv.Type == "middleman" { myId = fmt.Sprint(vv.Id) } if pMyId != "" { pMyId += "," } pMyId += myId if pMyType != "" { pMyType += "," } pMyType += vv.Type myChildIds, myChildTypes := "", "" if in.Id == "" && v.Name == "甲方" { cccNodes := []*nodeTree{} cccIndexMap := map[string]int{} for _, vvv := range firstpartyChild[vv.CompanyId] { cccIndex, cccOk := cccIndexMap[vvv.Name] if cccOk { cccNodes[cccIndex].ID += "," + vvv.CompanyId cccNodes[cccIndex].MYID += "," + vvv.CompanyId cccNodes[cccIndex].TYPE += ",firstparty" cccNodes[cccIndex].MYTYPE += ",firstparty" } else { cccNodes = append(cccNodes, &nodeTree{ NAME: vvv.Name, ID: vvv.CompanyId, SZ_PID0: v.Name, SZ_PID1: v.Name + ":" + myId, SZ_PID2: v.Name + ":" + myId + ":" + vvv.Name, CODE: v.Name + ":" + myId + ":" + vvv.Name, PCODE: v.Name + ":" + myId, SZ_LEVEL: 2, SZ_LEAF: 0, TYPE: "firstparty", MYID: vvv.CompanyId, MYTYPE: "firstparty", }) cccIndexMap[vvv.Name] = len(cccNodes) - 1 } if id != "" { id += "," } id += vvv.CompanyId if pType != "" { pType += "," } pType += vv.Type if myChildIds != "" { myChildIds += "," } myChildIds += vvv.CompanyId if myChildTypes != "" { myChildTypes += "," } myChildTypes += vv.Type *convList = append(*convList, &nodeTree{ NAME: vvv.CompanyName, ID: vvv.CompanyId, SZ_PID0: v.Name, SZ_PID1: v.Name + ":" + myId, SZ_PID2: cccNodes[cccIndex].SZ_PID2, SZ_PID3: v.Name + ":" + myId + ":" + vvv.Name + ":" + vvv.CompanyId, CODE: v.Name + ":" + myId + ":" + vvv.Name + ":" + vvv.CompanyId, PCODE: cccNodes[cccIndex].CODE, SZ_LEVEL: 3, SZ_LEAF: 1, TYPE: "firstparty", MYID: vvv.CompanyId, MYTYPE: "firstparty", }) } for _, cccNode := range cccNodes { *convList = append(*convList, cccNode) } } else { if id != "" { id += "," } id += myId if pType != "" { pType += "," } pType += vv.Type myChildIds = myId myChildTypes = vv.Type } cm := &nodeTree{ NAME: vv.CompanyName, ID: myChildIds, SZ_PID0: v.Name, SZ_PID1: v.Name + ":" + myId, CODE: v.Name + ":" + myId, PCODE: v.Name, DATACOUNT: vv.Count, SZ_LEVEL: 1, SZ_LEAF: If(myChildIds == "", 1, 0).(int), TYPE: myChildTypes, MYID: myId, MYTYPE: vv.Type, } *convList = append(*convList, cm) } pm.ID = id pm.TYPE = pType pm.MYTYPE = pMyType pm.MYID = pMyId *parentConvList = append(*parentConvList, pm) } sort.Sort(convList) *parentConvList = append(*parentConvList, *convList...) reply = &types.Reply{ Data: map[string]interface{}{ "count": count, "list": parentConvList, }, } redis.Put("newother", key, reply, C.CacheTimeOut) return reply } // 人脉库-列表 func (n *network) List(in *types.NetWorkListReq) *types.Reply { if in.Page_size <= 0 { in.Page_size = 10 } if in.Current_page <= 0 { in.Current_page = 1 } dbPaging := in.Buyercount_start == 0 && in.Buyercount_end == 0 && in.Monitor == 0 && in.Monitorcount_start == 0 && in.Monitorcount_end == 0 && in.Order_amount == 0 sqlAppendArgs := []interface{}{} sqlAppend1 := "" if dbPaging && in.Type != "" { sqlAppend1 += ` and a.itype=?` sqlAppendArgs = append(sqlAppendArgs, n.TypeStrConvert(in.Type)) } comSqlAppend := "" comSqlArgs := []interface{}{} if in.Starttime != "" { comSqlAppend += ` and a.create_time>=?` comSqlArgs = append(comSqlArgs, in.Starttime+" 00:00:00") } if in.Endtime != "" { comSqlAppend += ` and a.create_time<=?` if in.Starttime == in.Endtime { in.Endtime += " 23:59:59" } else { in.Endtime += " 00:00:00" } comSqlArgs = append(comSqlArgs, in.Endtime) } if in.Name != "" { comSqlAppend += ` and a.company_name like ?` comSqlArgs = append(comSqlArgs, "%"+in.Name+"%") } sqlAppend1 += comSqlAppend sqlAppendArgs = append(sqlAppendArgs, comSqlArgs...) var count int64 start := (in.Current_page - 1) * in.Page_size args := []interface{}{in.PositionId, in.PositionId, in.PositionId} args = append(args, sqlAppendArgs...) sqlAppend2 := "" firstparty_count, supplier_count, adiffb_count, middleman_count, agency_count := 0, 0, 0, 0, 0 if dbPaging { newArgs := []interface{}{in.PositionId} newArgs = append(newArgs, sqlAppendArgs...) count = CrmMysql.CountBySql(`select count(1) as count from crm.connection a where a.position_id=?`+sqlAppend1, newArgs...) sqlAppend2 = ` limit ?,?` args = append(args, start, in.Page_size) itemArgs := []interface{}{in.PositionId} itemArgs = append(itemArgs, comSqlArgs...) items := CrmMysql.SelectBySql(`SELECT itype,SUM(1) AS sum FROM crm.connection a WHERE a.position_id=?`+comSqlAppend+` GROUP BY a.itype`, itemArgs...) if items != nil { for _, v := range *items { switch Int64All(v["itype"]) { case 1: firstparty_count = IntAll(v["sum"]) case 2: supplier_count = IntAll(v["sum"]) case 3: adiffb_count = IntAll(v["sum"]) case 4: middleman_count = IntAll(v["sum"]) case 5: agency_count = IntAll(v["sum"]) } } } } // list := []*map[string]interface{}{} isTjProject := true businessType := []string{} businessType = strings.Split(FindBusiness(in.EntId, in.MgoUserId), ",") if len(businessType) == 0 { isTjProject = false } redisKey := fmt.Sprintf(NetworkManageList, in.PositionId, GetMd5String(fmt.Sprintf("%+v", in))) aio := &introduceOwnerProject{} aioByte, aioErr := redis.GetNewBytes("newother", redisKey) if aioErr == nil && aioByte != nil { json.Unmarshal(*aioByte, &aio) } else { aio = n.AllIntroduceOwner(sqlAppend1, sqlAppend2, args, isTjProject, businessType) redis.Put("newother", redisKey, aio, C.CacheTimeOut) } entMonitor := NetworkCom.EntMonitor(in.UserId) for _, v := range aio.Networks { itype := "" buyer_count, project_count, expect_amount, monitor_count := int64(0), int64(0), float64(0), int64(0) export_id := []string{} jump_type, jump_id := "", "" switch v.Itype { case 1: itype = "甲方" jump_type = "firstparty" for _, vv := range aio.FirstpartyNetwork[v.Company_id] { if jump_id != "" { jump_id += "," } jump_id += vv.CompanyId if entMonitor[vv.CompanyName] { monitor_count++ } } if aio.Firstparty[v.Company_id] != nil { buyer_count = aio.Firstparty[v.Company_id].BuyerCount project_count = aio.Firstparty[v.Company_id].ProjectCount expect_amount = aio.Firstparty[v.Company_id].ProjectAmount export_id = aio.Firstparty[v.Company_id].ExportId } case 2: itype = "供应商/渠道" jump_type = "supplier" jump_id = v.Company_id if aio.Supplier[v.Company_id] != nil { buyer_count = aio.Supplier[v.Company_id].BuyerCount project_count = aio.Supplier[v.Company_id].ProjectCount expect_amount = aio.Supplier[v.Company_id].ProjectAmount export_id = aio.Supplier[v.Company_id].ExportId for _, vv := range aio.Supplier[v.Company_id].IdNames { if entMonitor[vv.Name] { monitor_count++ } } } case 3: itype = "同甲异业渠道" jump_type = "adiffb" jump_id = v.Company_id if aio.Adiffb[v.Company_id] != nil { buyer_count = aio.Adiffb[v.Company_id].BuyerCount project_count = aio.Adiffb[v.Company_id].ProjectCount expect_amount = aio.Adiffb[v.Company_id].ProjectAmount export_id = aio.Adiffb[v.Company_id].ExportId for _, vv := range aio.Adiffb[v.Company_id].IdNames { if entMonitor[vv.Name] { monitor_count++ } } } case 4: itype = "中间人" jump_type = "middleman" jump_id = fmt.Sprint(v.Id) buyer_count = v.Buyer_count if v.Relate_buyer_name != "" { for _, v := range strings.Split(v.Relate_buyer_name, ",") { if v == "" { continue } if entMonitor[v] { monitor_count++ } } } if v.Relate_buyer_id != "" { for _, v := range strings.Split(v.Relate_buyer_id, ",") { if aio.Middleman[v] != nil { project_count++ expect_amount += aio.Middleman[v].ProjectAmount export_id = append(export_id, aio.Middleman[v].ExportId...) } } } case 5: itype = "招标代理机构" jump_type = "agency" jump_id = v.Company_id if aio.Agency[v.Company_id] != nil { buyer_count = aio.Agency[v.Company_id].BuyerCount project_count = aio.Agency[v.Company_id].ProjectCount expect_amount = aio.Agency[v.Company_id].ProjectAmount export_id = aio.Agency[v.Company_id].ExportId for _, vv := range aio.Agency[v.Company_id].IdNames { if entMonitor[vv.Name] { monitor_count++ } } } } if buyer_count < in.Buyercount_start { continue } else if in.Buyercount_end > 0 && buyer_count > in.Buyercount_end { continue } else if in.Monitor == 1 && monitor_count <= 0 { continue } else if in.Monitor == -1 && monitor_count > 0 { continue } else if monitor_count < in.Monitorcount_start { continue } else if in.Monitorcount_end > 0 && monitor_count > in.Monitorcount_end { continue } if !dbPaging { switch v.Itype { case 1: firstparty_count++ case 2: supplier_count++ case 3: adiffb_count++ case 4: middleman_count++ case 5: agency_count++ } if in.Type != "" && n.TypeStrConvert(in.Type) != v.Itype { continue } } export_url := "" if len(export_id) > 0 { exportIdRepeat := map[string]bool{} exportId := "" for _, v := range export_id { if exportIdRepeat[v] { continue } exportIdRepeat[v] = true if exportId != "" { exportId += "," } exportId += v } md5Id := GetMd5String(exportId) redis.Put("newother", fmt.Sprintf("network_export_%s", md5Id), exportId, 259200) export_url = "/subscribepay/network/projectExport?version=1&export_id=" + md5Id } url := "" if v.Qyxy_id != "" && (jump_type == "supplier" || jump_type == "adiffb") { url = "/swordfish/page_big_pc/ent_portrait/" + encrypt.EncodeArticleId2ByCheck(v.Qyxy_id) } else if jump_type == "firstparty" && v.Company_name != "" { url = "/swordfish/page_big_pc/unit_portrayal/" + v.Company_name } list = append(list, &map[string]interface{}{ "company_id": v.Company_id, "company_name": v.Company_name, "type": itype, "jump_type": jump_type, "jump_id": jump_id, "person": v.Person, "phone": v.Phone, "buyer_count": buyer_count, "monitor_count": monitor_count, "expect_amount": RetainDecimal(expect_amount/10000, 2), "project_count": project_count, "create_time": v.Create_time, "export_url": export_url, "url": url, "id": v.Id, }) } csList := &ComSortList{ SortKeys: []*ComSortKey{ &ComSortKey{ Keys: []string{"expect_amount"}, Order: 1, Type: "float", }, }, List: list, } if in.Order_amount == -1 { csList.SortKeys[0].Order = -1 } if in.Order_amount != 0 { sort.Sort(csList) } finalList := []*map[string]interface{}{} if !dbPaging { count = int64(len(csList.List)) if count > 0 && start < count { end := start + in.Page_size if end > count { end = count } finalList = csList.List[start:end] } } else { finalList = csList.List } total_page := int64(math.Ceil(float64(count) / float64(in.Page_size))) return &types.Reply{ Data: map[string]interface{}{ "count": count, "total_page": total_page, "firstparty_count": firstparty_count, "supplier_count": supplier_count, "adiffb_count": adiffb_count, "middleman_count": middleman_count, "agency_count": agency_count, "list": finalList, }, } } func (n *network) FirstpartyNetwork(name string, values []string) map[string][]*firstpartyNetwork { result := map[string][]*firstpartyNetwork{} if len(values) == 0 { return result } wh, args := NetworkCom.WhArgs(values) q := `select DISTINCT a.a_id,a.b_id as company_id,a.b_name as company_name,b.name from information.ent_map_code a inner join information.ent_code b on (a.a_id in (` + wh + `) and b.pcode in ('0100','0200') and a.code=b.code)` if name != "" { q += ` where c.company_name like ?` args = append(args, "%"+name+"%") } q += ` order by b.name,a.a_id,a.b_name` rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) return result } for rows.Next() { var ( a_id string company_id string company_name string name string ) if err := rows.Scan(&a_id, &company_id, &company_name, &name); err != nil { logx.Error(err) continue } if company_id == "" || company_name == "" { continue } result[a_id] = append(result[a_id], &firstpartyNetwork{ CompanyId: company_id, CompanyName: company_name, Name: name, }) } return result } func (n *network) Introduce_Firstparty(fpn map[string][]*firstpartyNetwork, businessType []string) map[string]*projectInfo { values := []string{} vm := map[string]*projectInfo{} for _, v := range fpn { for _, vv := range v { vm[vv.CompanyId] = &projectInfo{} values = append(values, vv.CompanyId) } } result := map[string]*projectInfo{} if len(values) == 0 { return result } wh, args := NetworkCom.WhArgs(values) q := `select buyer_id,count(project_id) AS project_count,sum(project_money) AS project_amount,groupUniqArray(project_id) from information.transaction_info_all where buyer_id in (` + wh + `)` if len(businessType) > 0 { newWh, newArgs := NetworkCom.WhArgs(businessType) q += ` and hasAny(topscopeclass,[` + newWh + `])` args = append(args, newArgs...) } q += ` and project_bidstatus>1 group by buyer_id` rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) return nil } for rows.Next() { var ( buyer_id string project_count uint64 project_amount decimal.Decimal project_id []string ) if err := rows.Scan(&buyer_id, &project_count, &project_amount, &project_id); err != nil { logx.Error(err) continue } if vm[buyer_id] == nil { continue } vm[buyer_id].ProjectCount += int64(project_count) pf, _ := project_amount.Float64() vm[buyer_id].ProjectAmount += pf vm[buyer_id].ExportId = project_id } rows.Close() if err := rows.Err(); err != nil { logx.Error(err) } for k, v := range fpn { if result[k] == nil { result[k] = &projectInfo{} } result[k].BuyerCount = int64(len(v)) for _, vv := range v { if vm[vv.CompanyId] == nil { continue } result[k].ProjectCount += vm[vv.CompanyId].ProjectCount result[k].ProjectAmount += vm[vv.CompanyId].ProjectAmount result[k].ExportId = append(result[k].ExportId, vm[vv.CompanyId].ExportId...) } } return result } func (n *network) Introduce_Supplier(values []string, businessType []string) map[string]*projectInfo { if len(values) == 0 { return map[string]*projectInfo{} } wh, args := NetworkCom.WhArgs(values) vbs := map[string][]*idName{} repeat := map[string]bool{} whRepeat := map[string]map[string]bool{} buyers := []string{} q := `select winner_id,buyer_id,buyer from information.transaction_info_all where hasAny(winner_id,[` + wh + `])` rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) } else { for rows.Next() { var ( winner_id []string buyer_id string buyer string ) if err := rows.Scan(&winner_id, &buyer_id, &buyer); err != nil { logx.Error(err) continue } if buyer_id == "" || buyer == "" { continue } if !repeat[buyer_id] { repeat[buyer_id] = true buyers = append(buyers, buyer_id) } for _, v := range winner_id { if whRepeat[v] != nil && whRepeat[v][buyer_id] { continue } if whRepeat[v] == nil { whRepeat[v] = map[string]bool{} } whRepeat[v][buyer_id] = true vbs[v] = append(vbs[v], &idName{ Id: buyer_id, Name: buyer, }) } } rows.Close() if err := rows.Err(); err != nil { logx.Error(err) } } return n.MakeProjectInfo(buyers, vbs, businessType) } func (n *network) Introduce_Agency(values []string, businessType []string) map[string]*projectInfo { if len(values) == 0 { return map[string]*projectInfo{} } wh, args := NetworkCom.WhArgs(values) q := `select DISTINCT agency_id,buyer_id,buyer from information.transaction_info_all where agency_id in (` + wh + `)` rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) return nil } vbs := map[string][]*idName{} buyers := []string{} repeat := map[string]bool{} for rows.Next() { var ( agency_id string buyer_id string buyer string ) if err := rows.Scan(&agency_id, &buyer_id, &buyer); err != nil { logx.Error(err) continue } if buyer_id == "" || buyer == "" { continue } vbs[agency_id] = append(vbs[agency_id], &idName{ Id: buyer_id, Name: buyer, }) if !repeat[buyer_id] { repeat[buyer_id] = true buyers = append(buyers, buyer_id) } } rows.Close() if err := rows.Err(); err != nil { logx.Error(err) } return n.MakeProjectInfo(buyers, vbs, businessType) } func (n *network) Introduce_Middleman_Buyer(values []string, businessType []string) map[string]*projectInfo { return n.BuyerProjectInfo(values, businessType) } func (n *network) Introduce_Middleman_Project(values []string, businessType []string) map[string]*projectInfo { result := map[string]*projectInfo{} if len(values) == 0 { return result } wh, args := NetworkCom.WhArgs(values) q := `select DISTINCT project_id,project_money from information.transaction_info_all where project_id in (` + wh + `)` if len(businessType) > 0 { newWh, newArgs := NetworkCom.WhArgs(businessType) q += ` and hasAny(topscopeclass,[` + newWh + `])` args = append(args, newArgs...) } rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) return nil } for rows.Next() { var ( project_id string project_money decimal.Decimal ) if err := rows.Scan(&project_id, &project_money); err != nil { logx.Error(err) continue } pf, _ := project_money.Float64() result[project_id] = &projectInfo{ ProjectAmount: pf, } } rows.Close() if err := rows.Err(); err != nil { logx.Error(err) } return result } func (n *network) TypeStrConvert(itype string) int64 { //firstparty:甲方 supplier:供应商 adiffb:同甲异业 middleman:中间人 agency:招标代理机构 switch itype { case "firstparty": return 1 case "supplier": return 2 case "adiffb": return 3 case "middleman": return 4 case "agency": return 5 } return 0 } func (n *network) TypeIntConvert(itype int64) string { //firstparty:甲方 supplier:供应商 adiffb:同甲异业 middleman:中间人 agency:招标代理机构 switch itype { case 1: return "firstparty" case 2: return "supplier" case 3: return "adiffb" case 4: return "middleman" case 5: return "agency" } return "" } func (n *network) GetQyxyId(ids []string) map[string]string { m := map[string]string{} if len(ids) == 0 { return m } wh, args := NetworkCom.WhArgs(ids) q := `select id,company_id from information.ent_info where id in (` + wh + `)` rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) } else { for rows.Next() { var ( id string company_id string ) if err := rows.Scan(&id, &company_id); err != nil { logx.Error(err) continue } m[id] = company_id } rows.Close() if err := rows.Err(); err != nil { logx.Error(err) } } return m } func (n *network) BuyerProjectInfo(ids []string, businessType []string) map[string]*projectInfo { vm := map[string]*projectInfo{} if len(ids) == 0 { return vm } wh, args := NetworkCom.WhArgs(ids) q := `select buyer_id,count(DISTINCT project_id) AS project_count,sum(project_money) AS project_amount,groupUniqArray(project_id) from information.transaction_info_all where buyer_id in (` + wh + `) and project_bidstatus>1` if len(businessType) > 0 { newWh, newArgs := NetworkCom.WhArgs(businessType) q += ` and hasAny(topscopeclass,[` + newWh + `])` args = append(args, newArgs...) } q += ` group by buyer_id` rows, err := ClickhouseConn.Query(context.Background(), q, args...) if err != nil { logx.Error(err) return nil } for rows.Next() { var ( buyer_id string project_count uint64 project_amount decimal.Decimal project_id []string ) if err := rows.Scan(&buyer_id, &project_count, &project_amount, &project_id); err != nil { logx.Error(err) continue } pf, _ := project_amount.Float64() vm[buyer_id] = &projectInfo{ ProjectCount: int64(project_count), ExportId: project_id, ProjectAmount: pf, } } rows.Close() if err := rows.Err(); err != nil { logx.Error(err) } return vm } func (n *network) MakeProjectInfo(buyers []string, vbs map[string][]*idName, businessType []string) map[string]*projectInfo { pis := n.BuyerProjectInfo(buyers, businessType) vm := map[string]*projectInfo{} for k, v := range vbs { pi := &projectInfo{ BuyerCount: int64(len(v)), IdNames: v, } re := map[string]bool{} for _, vv := range v { if pis[vv.Id] != nil { pi.ProjectCount += pis[vv.Id].ProjectCount pi.ProjectAmount += pis[vv.Id].ProjectAmount for _, vvv := range pis[vv.Id].ExportId { if re[vvv] { continue } pi.ExportId = append(pi.ExportId, vvv) re[vvv] = true } } } vm[k] = pi } return vm } func (n *network) AllIntroduceOwner(sqlAppend1, sqlAppend2 string, args []interface{}, isTjProject bool, businessType []string) *introduceOwnerProject { q := `select a.id,a.company_id,a.company_name,a.qyxy_id,a.itype,a.contact_person as person,a.contact_phone as phone,count(DISTINCT if(b.itype=1,b.relate_id,null)) as buyer_count,count(DISTINCT if(b.itype=2,b.relate_id,null)) as project_count,GROUP_CONCAT(IF(b.itype=1,b.relate_id,NULL)) AS relate_buyer_id,GROUP_CONCAT(IF(b.itype=1,b.relate_name,NULL)) AS relate_buyer_name,GROUP_CONCAT(IF(b.itype=2,b.relate_id,NULL)) AS relate_project_id,a.create_time from crm.connection a left join crm.connection_introduce b on (a.position_id=? and b.position_id=? and a.id=b.connection_id) where a.position_id=?` + sqlAppend1 + ` GROUP BY a.id order by a.create_time desc` + sqlAppend2 listTemp := CrmMysql.SelectBySql(q, args...) firstparty_array, supplier_array, adiffb_array, agency_array, middleman_buyer_array, middleman_project_array := []string{}, []string{}, []string{}, []string{}, []string{}, []string{} myNetworks := []*myNetwork{} for _, v := range *listTemp { myNetwork := &myNetwork{ Id: Int64All(v["id"]), Company_id: ObjToString(v["company_id"]), Company_name: ObjToString(v["company_name"]), Qyxy_id: ObjToString(v["qyxy_id"]), Itype: Int64All(v["itype"]), Person: ObjToString(v["person"]), Phone: ObjToString(v["phone"]), Buyer_count: Int64All(v["buyer_count"]), Project_count: Int64All(v["project_count"]), Relate_buyer_id: ObjToString(v["relate_buyer_id"]), Relate_buyer_name: ObjToString(v["relate_buyer_name"]), Relate_project_id: ObjToString(v["relate_project_id"]), Create_time: ObjToString(v["create_time"]), } switch myNetwork.Itype { case 1: firstparty_array = append(firstparty_array, myNetwork.Company_id) case 2: supplier_array = append(supplier_array, myNetwork.Company_id) case 3: adiffb_array = append(adiffb_array, myNetwork.Company_id) case 4: if myNetwork.Relate_buyer_id != "" { middleman_buyer_array = append(middleman_buyer_array, strings.Split(myNetwork.Relate_buyer_id, ",")...) } if myNetwork.Relate_project_id != "" { middleman_project_array = append(middleman_project_array, strings.Split(myNetwork.Relate_project_id, ",")...) } case 5: agency_array = append(agency_array, myNetwork.Company_id) } myNetworks = append(myNetworks, myNetwork) } iop := &introduceOwnerProject{ Networks: myNetworks, FirstpartyNetwork: map[string][]*firstpartyNetwork{}, Firstparty: map[string]*projectInfo{}, Supplier: map[string]*projectInfo{}, Adiffb: map[string]*projectInfo{}, Agency: map[string]*projectInfo{}, Middleman: map[string]*projectInfo{}, } if isTjProject { iop.FirstpartyNetwork = n.FirstpartyNetwork("", firstparty_array) iop.Firstparty = n.Introduce_Firstparty(iop.FirstpartyNetwork, businessType) iop.Supplier = n.Introduce_Supplier(supplier_array, businessType) iop.Adiffb = n.Introduce_Supplier(adiffb_array, businessType) iop.Agency = n.Introduce_Agency(agency_array, businessType) iop.Middleman = n.Introduce_Middleman_Buyer(middleman_buyer_array, businessType) } return iop } func (n *network) DeleteCache(positionId int64) { redis.Del("newother", fmt.Sprintf(NetworkManageAllProjectKey, positionId)) redis.DelByCodePattern("newother", fmt.Sprintf(NetworkManageList, positionId, "*")) redis.DelByCodePattern("newother", fmt.Sprintf(NetworkManageCoopHistory, positionId, "*")) redis.DelByCodePattern("newother", fmt.Sprintf(NetworkManageOwnerlList, positionId, "*")) redis.DelByCodePattern("newother", fmt.Sprintf(NetworkManageProjectList, positionId, "*")) }