package service import ( "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/date" elastic "app.yhyue.com/moapp/jybase/es" "app.yhyue.com/moapp/jypkg/ent/util" "app.yhyue.com/moapp/jypkg/public" MC "bp.jydev.jianyu360.cn/CRM/application/api/common" "bp.jydev.jianyu360.cn/CRM/application/api/internal/types" "bp.jydev.jianyu360.cn/CRM/application/entity" "database/sql" "fmt" "github.com/RoaringBitmap/roaring" "go.mongodb.org/mongo-driver/bson" "log" "regexp" "strconv" "strings" "time" ) const ( BuyerIndex = "buyer" // 采购单位index BuyerType = "buyer" ) type EmPloyService struct{} // InfoEmployinfo 收录情况查询 func (e *EmPloyService) InfoEmployinfo(in *types.InfoEmployinfoReq) []map[string]interface{} { var data []map[string]interface{} for _, v := range strings.Split(in.IdArr, ",") { table, findKey, employKey, source := EmployKeyFormat(in.EmployType) id := "" id = IdFormat(v, in.EmployType) if id == "" { log.Println(v, in.EmployType, "该信息查询不到数据") break } valueMap := map[string]interface{}{ "id": v, } //有收录情况 //summaryMap := SummaryFormat(in.PositionId) //vint = mongodb.StringTOBsonId(id).Timestamp().Unix() //vint = extractNumbers(id) //valueMap["isEmploy"] = summaryMap[in.EmployType].Contains(uint32(vint)) employData := MC.CrmMysql.FindOne(table, map[string]interface{}{ employKey: id, "position_id": in.PositionId, "source": source, }, "is_ignore,status,id", "") employId := int64(0) if employData != nil && len(*employData) > 0 { valueMap["isIgnore"] = common.If(common.Int64All((*employData)["is_ignore"]) == 1, true, false) valueMap["isEmploy"] = common.If(common.Int64All((*employData)["status"]) == 1, true, false) employId = common.Int64All((*employData)["id"]) valueMap["employId"] = employId } else { valueMap["isIgnore"] = false valueMap["isEmploy"] = false } if len(strings.Split(in.IdArr, ",")) == 1 && employId > 0 { //列表查询 //是否忽略处理 //客户数量 customCount := MC.CrmMysql.Count(entity.CUSTOM, map[string]interface{}{ findKey: employId, "position_id": in.PositionId, }) valueMap["customCount"] = customCount if in.EmployType == 1 || in.EmployType == 4 { //销售线索数量 clueCount := MC.CrmMysql.Count(entity.SALE_CLUE, map[string]interface{}{ "employ_info_id": employId, "position_id": in.PositionId, }) valueMap["clueCount"] = clueCount //销售机会数量 chanceCount := MC.CrmMysql.Count(entity.SALE_CHANCE, map[string]interface{}{ "employ_info_id": id, "position_id": in.PositionId, }) valueMap["chanceCount"] = chanceCount } } else { valueMap["chanceCount"] = 0 valueMap["clueCount"] = 0 valueMap["isIgnore"] = false valueMap["customCount"] = 0 } data = append(data, valueMap) } return data } // EmployOperate 收录操作 func (e *EmPloyService) EmployOperate(in *types.EmployOperateReq) bool { //收录汇总表 table, _, employKey, source := EmployKeyFormat(in.EmployType) //summaryMap := SummaryFormat(in.PositionId) return MC.CrmMysql.ExecTx("收录操作", func(tx *sql.Tx) bool { for _, v1 := range strings.Split(in.IdArr, ",") { //id转中文 id := "" findMap := map[string]interface{}{} findMap["position_id"] = in.PositionId id = IdFormat(v1, in.EmployType) findMap[employKey] = id if id == "" { log.Println(v1, in.EmployType, "该信息查询不到数据") break } if in.IsEmploy { if MC.CrmMysql.Count(table, findMap) > 0 { MC.CrmMysql.UpdateByTx(tx, table, findMap, map[string]interface{}{ "status": 1, }) } else { //收录新增 data := map[string]interface{}{} if in.EmployType == 1 || in.EmployType == 4 { data = InfoFind(id, in.EmployType) data["employ_way"] = 1 data["jybx_url"] = "/article/content/" + v1 + ".html" } else if in.EmployType == 2 { data = CustomFind(id, in.EmployType) data["jybx_url"] = "/swordfish/page_big_pc/svip/ent_ser_portrait/" + v1 } else if in.EmployType == 3 { data = CustomFind(id, in.EmployType) data["jybx_url"] = "/swordfish/page_big_pc/unit_portrayal/" + v1 } data["position_id"] = in.PositionId data["ent_id"] = in.EntId data["source"] = source ok := MC.CrmMysql.InsertByTx(tx, table, data) if ok <= 0 { log.Println(v1, id, in.EmployType, "收录失败") break } } } else { //取消收录 ok := MC.CrmMysql.UpdateByTx(tx, table, findMap, map[string]interface{}{ "status": -1, }) if !ok { log.Println(v1, id, in.EmployType, "取消收录失败") } } /*//收录汇总表处理 vint := extractNumbers(id) if in.IsEmploy { summaryMap[in.EmployType].Add(uint32(vint)) } else { summaryMap[in.EmployType].Remove(uint32(vint)) }*/ //fool = true } /*if fool { return SummarySave(tx, in.PositionId, summaryMap) } else { return false }*/ return true }) } // CustomFind 企业信息查询 func CustomFind(id string, employType int64) map[string]interface{} { data := map[string]interface{}{} //company_id 企业id name户名称 address 地址 industry 行业 if employType == 2 { //企业详情 entinfo, _ := MC.MgoEnt.FindOneByField("qyxy_std", map[string]interface{}{"_id": id}, map[string]interface{}{ "company_address": 1, //注册地 "company_name": 1, }) if entinfo != nil && len(*entinfo) > 0 { data["name"] = (*entinfo)["company_name"] data["address"] = (*entinfo)["company_address"] data["company_id"] = id } } else { //采购单位详情 rs := elastic.Get(BuyerIndex, BuyerType, fmt.Sprintf(`{"query":{"bool":{"must":[{"terms":{"_id":["%s"]}}]}},"size":1,"_source":["buyer_name","city"]}`, id)) if rs != nil && len(*rs) > 0 { data["name"] = (*rs)[0]["buyer_name"] data["address"] = (*rs)[0]["city"] data["company_id"] = id } } data["status"] = 1 data["create_time"] = time.Now().Format(date.Date_Full_Layout) return data } // InfoFind 标讯信息查询 func InfoFind(id string, employType int64) map[string]interface{} { data := map[string]interface{}{} //source_id 信息id、项目id- title 标题-area 省 -city 市 -subtype 信息类型二级分类 //buyerclass 采购单位行业 -budget 预算 -bidamount 中标金额 buyer采购单位 annex有无附件 publishtime发布时间 projectname 项目时间 //ownerclass 业主类型(拟在建搜索) expurasing_time 预计采购时间 jybx_url 标讯详情页 if employType == 1 { //标讯信息 obj := map[string]interface{}{} brobj, ok := MC.Mgo.Find("bidding_rec", bson.M{"s_id": id}, `{"l_recoverydate":-1}`, public.MgoBiddingFields, false, 0, 1) if ok && (*brobj) != nil && len(*brobj) == 1 && (*brobj)[0] != nil { obj = (*brobj)[0] } else { aobj, ok := MC.MgoBidding.FindById("bidding", id, public.MgoBiddingFields) if ok && (aobj == nil || *aobj == nil || len(*aobj) == 0) { aobj, ok = MC.MgoBidding.FindById("bidding_back", id, public.MgoBiddingFields) } obj = *aobj } if ok && obj != nil && len(obj) > 0 { toptype := common.InterfaceToStr(obj["toptype"]) subtype := common.InterfaceToStr(obj["subtype"]) data["title"] = common.ObjToString(obj["title"]) data["city"] = obj["city"] data["area"] = obj["area"] data["subtype"] = obj["subtype"] data["buyerclass"] = obj["buyerclass"] data["budget"] = obj["budget"] data["bidamount"] = obj["bidamount"] data["annex"] = 0 data["buyer"] = obj["buyer"] data["winner"] = obj["s_winner"] //类型处理 /*if subtype == "拟建" { data["type"] = 1 data["type"] = 2 } else */ if toptype == "采购意向" || toptype == "预告" || toptype == "招标" { data["type"] = 2 } else { if subtype == "废标" || subtype == "流标" || subtype == "其它" { data["type"] = 2 } else if subtype == "成交" || subtype == "中标" || subtype == "合同" || subtype == "验收" || subtype == "违规" { data["type"] = 3 } else { data["type"] = 1 } } if common.InterfaceToStr(obj["subtype"]) == "拟建" { } else { } //data["type"] = in.SourceType if obj["projectinfo"] != nil { projectinfo := common.ObjToMap(obj["projectinfo"]) if (*projectinfo)["attachments"] != nil { data["annex"] = 1 } } data["publishtime"] = time.Unix(common.Int64All(obj["publishtime"]), 0).Format(date.Date_Full_Layout) data["show_time"] = time.Unix(common.Int64All(obj["publishtime"]), 0).Format(date.Date_Full_Layout) data["projectname"] = obj["projectname"] procurementlist, _ := obj["procurementlist"].([]interface{}) for _, vs := range procurementlist { //1.采购意向清单数据集打码处理 vsMap, _ := vs.(map[string]interface{}) if vsMap["expurasingtime"] != nil { data["expurasing_time"] = vsMap["expurasingtime"] break } } } } data["status"] = 1 data["employ_way"] = 1 data["source_id"] = id data["create_time"] = time.Now().Format(date.Date_Full_Layout) return data } // GetBuyerIdByName 通过采购单位名称获取id func GetBuyerIdByName(buyerName string) (buyerId string) { r := elastic.Get(BuyerIndex, BuyerType, fmt.Sprintf(`{"query":{"bool":{"must":[{"term":{"buyer_name":"%s"}}]}},"size":1,"_source":["city","id"]}`, buyerName)) if r == nil || len(*r) == 0 { return } buyerId, _ = (*r)[0]["_id"].(string) return } // IdFormat id解密 func IdFormat(encryptionId string, employType int64) string { decryptId := "" switch employType { case 1, 2: decryptId = util.DecodeId(encryptionId) case 3: if len(encryptionId) > 0 && len([]rune(encryptionId)) == len(encryptionId) { //此数据是id //获取中文名字 decryptId = util.DecodeId(encryptionId) } else { //次数据传的名字 decryptId = GetBuyerIdByName(encryptionId) } } return decryptId } // SummaryFormat 汇总表处理 func SummaryFormat(positionId int64) map[int64]*roaring.Bitmap { var byte1 []byte var byte2 []byte var byte3 []byte var byte4 []byte err := MC.CrmMysql.DB.QueryRow("select search_tencent, search_buyer, search_ent, search_nzj from employ_summary where position_id=?", positionId).Scan(&byte1, &byte3, &byte2, &byte4) if err != nil { return nil } rb1 := roaring.NewBitmap() rb2 := roaring.NewBitmap() rb3 := roaring.NewBitmap() rb4 := roaring.NewBitmap() data := map[int64]*roaring.Bitmap{} if byte1 != nil && len(byte1) > 0 { rb1.UnmarshalBinary(byte1) } if byte2 != nil && len(byte2) > 0 { rb2.UnmarshalBinary(byte2) } if byte3 != nil && len(byte3) > 0 { rb3.UnmarshalBinary(byte3) } if byte4 != nil && len(byte4) > 0 { rb4.UnmarshalBinary(byte4) } data[1] = rb1 data[2] = rb2 data[3] = rb3 data[4] = rb4 return data } // SummarySave 汇总表保存 func SummarySave(tx *sql.Tx, positionId int64, data map[int64]*roaring.Bitmap) bool { employSummaryData := MC.CrmMysql.FindOne(entity.EMPLOY_SUMMARY, map[string]interface{}{ "position_id": positionId, }, "", "") if employSummaryData != nil && len(*employSummaryData) > 0 { //修改 updateData := map[string]interface{}{} updateData["search_tencent"], _ = data[1].ToBytes() updateData["search_buyer"], _ = data[3].ToBytes() updateData["search_ent"], _ = data[2].ToBytes() updateData["search_nzj"], _ = data[4].ToBytes() ok := MC.CrmMysql.UpdateByTx(tx, entity.EMPLOY_SUMMARY, map[string]interface{}{ "position_id": positionId, }, updateData) return ok } else { //新增 insertData := map[string]interface{}{} insertData["position_id"] = positionId insertData["search_tencent"], _ = data[1].ToBytes() insertData["search_buyer"], _ = data[3].ToBytes() insertData["search_ent"], _ = data[2].ToBytes() insertData["search_nzj"], _ = data[4].ToBytes() ok := MC.CrmMysql.InsertByTx(tx, entity.EMPLOY_SUMMARY, insertData) return ok > 0 } } // EmployKeyFormat 根据收录类型 字段处理 table,findKey,employKey,source func EmployKeyFormat(employType int64) (string, string, string, int64) { table := "" employKey := "company_id" findKey := "employ_custom_id" source := int64(0) switch employType { case 1: table = entity.EMPLOY_INFO employKey = "source_id" findKey = "employ_info_id" source = 1 case 2: table = entity.EMPLOY_CUSTOM source = 1 case 3: table = entity.EMPLOY_CUSTOM source = 2 case 4: table = entity.EMPLOY_INFO source = 2 employKey = "source_id" findKey = "employ_info_id" } return table, findKey, employKey, source } // IgnoreOperate 忽略操作 func (e *EmPloyService) IgnoreOperate(in *types.IgnoreOperateReq) { // table := "" switch in.EmployType { case 1, 4: table = entity.EMPLOY_INFO case 2, 3: table = entity.EMPLOY_CUSTOM } for _, v := range strings.Split(in.IdArr, ",") { id := IdFormat(v, in.EmployType) if id == "" { log.Println(v, id, in.EmployType, "忽略处理,id解析失败") break } findMap := map[string]interface{}{ "position_id": in.PositionId, } if in.EmployType == 3 || in.EmployType == 2 { findMap["company_id"] = id } else { findMap["source_id"] = id } if MC.CrmMysql.Count(table, findMap) == 0 { log.Println(v, id, in.EmployType, "忽略处理,id所对应数据不存在") break } if in.IsIgnore { MC.CrmMysql.Update(table, findMap, map[string]interface{}{ "is_ignore": 1, "is_handle": 1, }) } else { MC.CrmMysql.Update(table, findMap, map[string]interface{}{ "is_ignore": 0, "is_handle": 1, }) } } } type PersonSmmary struct { EntUserId int64 Summary map[int64]*roaring.Bitmap } // DistributePerson 分发操作 func (e *EmPloyService) DistributePerson(in *types.EmployDistributeReq) bool { return MC.CrmMysql.ExecTx("收录操作", func(tx *sql.Tx) bool { personMap := map[int64]PersonSmmary{} //汇总表查询 for _, person := range in.Person { personMap[person.PositionId] = PersonSmmary{ EntUserId: person.EntUserId, } } //分发数据处理 infoMap := map[string]map[string]interface{}{} onlyMap := map[string]interface{}{} for _, v := range strings.Split(in.EmployIdArr, ",") { if onlyMap[v] == nil { //查询信息 infoDataList := MC.CrmMysql.SelectBySqlByTx(tx, "SELECT * FROM employ_info WHERE id=?", v) if infoDataList != nil && len(*infoDataList) > 0 { source_id := common.InterfaceToStr((*infoDataList)[0]["source_id"]) if onlyMap[source_id] == nil { (*infoDataList)[0]["dis_id"] = v (*infoDataList)[0]["is_handle"] = 0 (*infoDataList)[0]["is_ignore"] = 0 (*infoDataList)[0]["is_dis"] = 0 (*infoDataList)[0]["is_create_clue"] = 0 (*infoDataList)[0]["is_create_chance"] = 0 (*infoDataList)[0]["is_create_custom"] = 0 (*infoDataList)[0]["create_time"] = time.Now().Format(date.Date_Full_Layout) delete((*infoDataList)[0], "id") if common.IntAll((*infoDataList)[0]["is_dis"]) != 1 { MC.CrmMysql.UpdateByTx(tx, entity.EMPLOY_INFO, map[string]interface{}{ "id": v, }, map[string]interface{}{ "is_dis": 1, }) } infoMap[source_id] = (*infoDataList)[0] onlyMap[source_id] = v } else { log.Println(v, "查询不到改收录信息") continue } } } } for positionId, personSmmary := range personMap { for _, v := range infoMap { //查询时候收录过 findMap := map[string]interface{}{ "position_id": positionId, "source_id": v["source_id"], } if MC.CrmMysql.Count(entity.EMPLOY_INFO, findMap) == 0 { //新增 v["ent_user_id"] = personSmmary.EntUserId v["position_id"] = positionId MC.CrmMysql.InsertByTx(tx, entity.EMPLOY_INFO, v) } } } return true }) } // 提取字符串中的数字 func ExtractNumbers(str string) int64 { re := regexp.MustCompile(`\d+`) matches := re.FindAllString(str, -1) numbers := make([]int, len(matches)) for i, match := range matches { number, err := strconv.Atoi(match) if err == nil { numbers[i] = number } } result := 0 for _, number := range numbers { result = result*10 + number } return int64(result) }