EmployService.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. package service
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/date"
  5. "app.yhyue.com/moapp/jybase/encrypt"
  6. elastic "app.yhyue.com/moapp/jybase/es"
  7. "app.yhyue.com/moapp/jybase/mongodb"
  8. "app.yhyue.com/moapp/jypkg/ent/util"
  9. "app.yhyue.com/moapp/jypkg/public"
  10. MC "bp.jydev.jianyu360.cn/CRM/application/api/common"
  11. "bp.jydev.jianyu360.cn/CRM/application/api/internal/types"
  12. "bp.jydev.jianyu360.cn/CRM/application/entity"
  13. "database/sql"
  14. "fmt"
  15. "github.com/RoaringBitmap/roaring"
  16. "go.mongodb.org/mongo-driver/bson"
  17. "time"
  18. )
  19. const (
  20. BuyerIndex = "buyer" // 采购单位index
  21. BuyerType = "buyer"
  22. query = `{%s "query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}]}}}`
  23. )
  24. type EmPloyService struct{}
  25. // 收录情况查询
  26. func (e *EmPloyService) InfoEmployinfo(in *types.InfoEmployinfoReq) []map[string]interface{} {
  27. data := []map[string]interface{}{}
  28. for _, v := range in.Id {
  29. vint := int64(0)
  30. table := entity.EMPLOY_CUSTOM
  31. id := ""
  32. source := 0
  33. if in.EmployType == 3 {
  34. //判断传过来的是名字还是ID
  35. //id转中文
  36. if len(v) > 0 && len([]rune(v)) == len(v) {
  37. //此数据是id
  38. //获取中文名字
  39. id = util.DecodeId(v)
  40. } else {
  41. //次数据传的名字
  42. id = getBuyerIdByName(v)
  43. }
  44. } else {
  45. id = util.DecodeId(v)
  46. }
  47. valueMap := map[string]interface{}{
  48. "id": v,
  49. }
  50. employKey := "company_id"
  51. findKey := "employ_custom_id"
  52. //有收录情况
  53. rb := roaring.NewBitmap()
  54. bytes := []byte{}
  55. byte1 := []byte{}
  56. byte2 := []byte{}
  57. byte3 := []byte{}
  58. byte4 := []byte{}
  59. MC.CrmMysql.DB.QueryRow("select search_tencent, search_buyer, search_ent, search_nzj from employ_summary where position_id=?", in.PositionId).Scan(&byte1, &byte2, &byte3, &byte4)
  60. if byte1 != nil {
  61. search_tencent := roaring.NewBitmap()
  62. search_buyer := roaring.NewBitmap()
  63. search_ent := roaring.NewBitmap()
  64. search_nzj := roaring.NewBitmap()
  65. if byte1 != nil && len(byte1) > 0 {
  66. search_tencent.UnmarshalBinary(byte1)
  67. }
  68. if byte2 != nil && len(byte2) > 0 {
  69. search_buyer.UnmarshalBinary(byte2)
  70. }
  71. if byte3 != nil && len(byte3) > 0 {
  72. search_ent.UnmarshalBinary(byte3)
  73. }
  74. if byte4 != nil && len(byte4) > 0 {
  75. search_nzj.UnmarshalBinary(byte4)
  76. }
  77. switch in.EmployType {
  78. case 1:
  79. bytes = byte1
  80. table = entity.EMPLOY_INFO
  81. employKey = "source_id"
  82. findKey = "employ_info_id"
  83. source = 1
  84. case 2:
  85. bytes = byte2
  86. source = 1
  87. case 3:
  88. bytes = byte3
  89. source = 2
  90. case 4:
  91. bytes = byte4
  92. source = 2
  93. table = entity.EMPLOY_INFO
  94. employKey = "source_id"
  95. findKey = "employ_info_id"
  96. }
  97. err := rb.UnmarshalBinary(bytes)
  98. if err != nil {
  99. break
  100. }
  101. vint = mongodb.StringTOBsonId(v).Timestamp().Unix()
  102. valueMap["isEmploy"] = rb.Contains(uint32(vint))
  103. }
  104. if len(in.Id) == 1 {
  105. //列表查询
  106. //是否忽略处理
  107. employData := MC.CrmMysql.FindOne(table, map[string]interface{}{
  108. employKey: id,
  109. "position_id": in.PositionId,
  110. "source": source,
  111. }, "", "")
  112. if employData != nil && len(*employData) > 0 {
  113. valueMap["isIgnore"] = common.Int64All((*employData)["is_ignore"])
  114. } else {
  115. valueMap["isIgnore"] = 0
  116. }
  117. //客户数量
  118. customCount := MC.CrmMysql.Count(entity.CUSTOM, map[string]interface{}{
  119. findKey: id,
  120. "position_id": in.PositionId,
  121. })
  122. valueMap["customCount"] = customCount
  123. if in.EmployType == 1 || in.EmployType == 4 {
  124. //销售线索数量
  125. clueCount := MC.CrmMysql.Count(entity.SALE_CLUE, map[string]interface{}{
  126. "employ_info_id": id,
  127. "position_id": in.PositionId,
  128. })
  129. valueMap["clueCount"] = clueCount
  130. //销售机会数量
  131. chanceCount := MC.CrmMysql.Count(entity.SALE_CHANCE, map[string]interface{}{
  132. "employ_info_id": id,
  133. "position_id": in.PositionId,
  134. })
  135. valueMap["chanceCount"] = chanceCount
  136. }
  137. }
  138. data = append(data, valueMap)
  139. }
  140. return data
  141. }
  142. // 收录操作
  143. func (e *EmPloyService) EmployOperate(in *types.EmployOperateReq) bool {
  144. //收录汇总表
  145. employSummaryData := MC.CrmMysql.FindOne(entity.EMPLOY_SUMMARY, map[string]interface{}{
  146. "position_id": in.PositionId,
  147. }, "", "")
  148. byte1 := []byte{}
  149. byte2 := []byte{}
  150. byte3 := []byte{}
  151. byte4 := []byte{}
  152. MC.CrmMysql.DB.QueryRow("select search_tencent, search_buyer, search_ent, search_nzj from employ_summary where position_id=?", in.PositionId).Scan(&byte1, &byte2, &byte3, &byte4)
  153. search_tencent := roaring.NewBitmap()
  154. search_buyer := roaring.NewBitmap()
  155. search_ent := roaring.NewBitmap()
  156. search_nzj := roaring.NewBitmap()
  157. if byte1 != nil && len(byte1) > 0 {
  158. search_tencent.UnmarshalBinary(byte1)
  159. }
  160. if byte2 != nil && len(byte2) > 0 {
  161. search_buyer.UnmarshalBinary(byte2)
  162. }
  163. if byte3 != nil && len(byte3) > 0 {
  164. search_ent.UnmarshalBinary(byte3)
  165. }
  166. if byte4 != nil && len(byte4) > 0 {
  167. search_nzj.UnmarshalBinary(byte4)
  168. }
  169. table := ""
  170. switch in.EmployType {
  171. case 1, 4:
  172. table = entity.EMPLOY_INFO
  173. case 2, 3:
  174. table = entity.EMPLOY_CUSTOM
  175. }
  176. return MC.CrmMysql.ExecTx("收录操作", func(tx *sql.Tx) bool {
  177. for _, v1 := range in.IdArr {
  178. //id转中文
  179. id := ""
  180. name := ""
  181. findMap := map[string]interface{}{}
  182. findMap["position_id"] = in.PositionId
  183. if in.EmployType == 3 {
  184. //判断传过来的是名字还是ID
  185. //id转中文
  186. if len(v1) > 0 && len([]rune(v1)) == len(v1) {
  187. //此数据是id
  188. //获取中文名字
  189. id = util.DecodeId(v1)
  190. name = getBuyerIdByName(id)
  191. } else {
  192. //次数据传的名字
  193. name = v1
  194. id = getBuyerIdByName(v1)
  195. }
  196. findMap["company_id"] = id
  197. } else if in.EmployType == 2 {
  198. id = encrypt.DecodeArticleId2ByCheck(v1)[0]
  199. findMap["company_id"] = id
  200. } else {
  201. id = encrypt.CommonDecodeArticle("content", v1)[0]
  202. findMap["source_id"] = id
  203. }
  204. if in.IsEmploy {
  205. if MC.CrmMysql.Count(table, findMap) > 0 {
  206. MC.CrmMysql.UpdateByTx(tx, table, findMap, map[string]interface{}{
  207. "status": 1,
  208. })
  209. } else {
  210. //收录新增
  211. data := map[string]interface{}{}
  212. if in.EmployType == 2 {
  213. data = CustomFind(id, "", in.EmployType)
  214. } else if in.EmployType == 3 {
  215. //id转中文
  216. data = CustomFind("", name, in.EmployType)
  217. } else {
  218. data = InfoFind(id, in.EmployType)
  219. data["type"] = in.SourceType
  220. data["source"] = in.EmployType
  221. data["employ_way"] = 1
  222. data["jybx_url"] = "/article/content/" + v1 + ".html"
  223. }
  224. data["position_id"] = in.PositionId
  225. data["ent_id"] = in.EntId
  226. MC.CrmMysql.InsertByTx(tx, table, data)
  227. }
  228. } else {
  229. //取消收录
  230. MC.CrmMysql.UpdateByTx(tx, table, findMap, map[string]interface{}{
  231. "status": -1,
  232. })
  233. }
  234. //收录汇总表处理
  235. KeyHandle(mongodb.StringTOBsonId(id).Timestamp().Unix(), in.EmployType, in.IsEmploy, search_tencent, search_buyer, search_ent, search_nzj)
  236. }
  237. search_tencent_byte, _ := search_tencent.ToBytes()
  238. search_buyer_byte, _ := search_buyer.ToBytes()
  239. search_ent_byte, _ := search_ent.ToBytes()
  240. search_nzj_byte, _ := search_nzj.ToBytes()
  241. if employSummaryData != nil && len(*employSummaryData) > 0 {
  242. //修改
  243. MC.CrmMysql.UpdateByTx(tx, entity.EMPLOY_SUMMARY, map[string]interface{}{
  244. "position_id": in.PositionId,
  245. }, map[string]interface{}{
  246. "search_tencent": search_tencent_byte,
  247. "search_buyer": search_buyer_byte,
  248. "search_ent": search_ent_byte,
  249. "search_nzj": search_nzj_byte,
  250. })
  251. } else {
  252. //新增
  253. MC.CrmMysql.InsertByTx(tx, entity.EMPLOY_SUMMARY, map[string]interface{}{
  254. "position_id ": in.PositionId,
  255. "search_tencent": search_tencent_byte,
  256. "search_buyer": search_buyer_byte,
  257. "search_ent": search_ent_byte,
  258. "search_nzj": search_nzj_byte,
  259. })
  260. }
  261. return true
  262. })
  263. }
  264. // 收录数据处理
  265. func KeyHandle(id int64, employType int64, isEmploy bool, search_tencent, search_buyer, search_ent, search_nzj *roaring.Bitmap) {
  266. switch employType {
  267. case 1:
  268. if isEmploy {
  269. search_tencent.Add(uint32(id))
  270. } else {
  271. search_tencent.Remove(uint32(id))
  272. }
  273. case 2:
  274. if isEmploy {
  275. search_buyer.Add(uint32(id))
  276. } else {
  277. search_buyer.Remove(uint32(id))
  278. }
  279. case 3:
  280. if isEmploy {
  281. search_ent.Add(uint32(id))
  282. } else {
  283. search_ent.Remove(uint32(id))
  284. }
  285. case 4:
  286. if isEmploy {
  287. search_nzj.Add(uint32(id))
  288. } else {
  289. search_nzj.Remove(uint32(id))
  290. }
  291. }
  292. return
  293. }
  294. // 企业信息查询
  295. func CustomFind(id string, name string, employType int64) map[string]interface{} {
  296. data := map[string]interface{}{}
  297. //company_id 企业id name户名称 address 地址
  298. if employType == 2 {
  299. //企业详情
  300. entinfo, _ := MC.MgoEnt.FindOneByField("qyxy_std", map[string]interface{}{"_id": id}, map[string]interface{}{
  301. "company_address": 1, //注册地
  302. "company_name": 1,
  303. })
  304. if entinfo != nil && len(*entinfo) > 0 {
  305. data["name"] = (*entinfo)["company_name"]
  306. data["address"] = (*entinfo)["company_address"]
  307. data["company_id"] = (*entinfo)["id"]
  308. }
  309. } else {
  310. //采购单位详情
  311. entNameQuery := fmt.Sprintf(`{"query":{"bool":{"must":[{"term":{"buyer_name":"%s"}}]}},"size":1,"_source":["city","buyer_name","id"]}`, name)
  312. rs := elastic.Get(BuyerIndex, BuyerType, entNameQuery)
  313. if rs != nil && len(*rs) > 0 {
  314. data["name"] = (*rs)[0]["buyer_name"]
  315. data["address"] = (*rs)[0]["city"]
  316. data["company_id"] = (*rs)[0]["id"]
  317. }
  318. }
  319. data["status"] = 1
  320. data["create_time"] = time.Now().Format(date.Date_Full_Layout)
  321. return data
  322. }
  323. // 标讯信息查询
  324. func InfoFind(id string, employType int64) map[string]interface{} {
  325. data := map[string]interface{}{}
  326. //source_id 信息id、项目id- title 标题-area 省 -city 市 -subtype 信息类型二级分类
  327. //buyerclass 采购单位行业 -budget 预算 -bidamount 中标金额 buyer采购单位 annex有无附件 publishtime发布时间 projectname 项目时间
  328. //ownerclass 业主类型(拟在建搜索) expurasing_time 预计采购时间 jybx_url 标讯详情页
  329. if employType == 1 {
  330. //标讯信息
  331. obj := map[string]interface{}{}
  332. brobj, ok := MC.Mgo.Find("bidding_rec", bson.M{"s_id": id}, `{"l_recoverydate":-1}`, public.MgoBiddingFields, false, 0, 1)
  333. if ok && (*brobj) != nil && len(*brobj) == 1 && (*brobj)[0] != nil {
  334. obj = (*brobj)[0]
  335. } else {
  336. aobj, ok := MC.MgoBidding.FindById("bidding", id, public.MgoBiddingFields)
  337. if ok && (aobj == nil || *aobj == nil || len(*aobj) == 0) {
  338. aobj, ok = MC.MgoBidding.FindById("bidding_back", id, public.MgoBiddingFields)
  339. }
  340. obj = *aobj
  341. }
  342. if ok && obj != nil && len(obj) > 0 {
  343. titleTmp := common.ObjToString(obj["title"])
  344. if len([]rune(titleTmp)) > 100 {
  345. titleTmp = string([]rune(titleTmp)[:100]) + "..."
  346. }
  347. titleTmp = public.ClearHtml.ReplaceAllString(titleTmp, "")
  348. data["title"] = titleTmp
  349. data["city"] = obj["city"]
  350. data["area"] = obj["area"]
  351. data["subtype"] = obj["subtype"]
  352. data["buyerclass"] = obj["buyerclass"]
  353. data["budget"] = obj["budget"]
  354. data["bidamount"] = obj["bidamount"]
  355. data["annex"] = 0
  356. if obj["projectinfo"] != nil {
  357. projectinfo := common.ObjToMap(obj["projectinfo"])
  358. if (*projectinfo)["attachments"] != nil {
  359. data["annex"] = 1
  360. }
  361. }
  362. data["publishtime"] = time.Unix(common.Int64All(obj["publishtime"]), 0).Format(date.Date_Full_Layout)
  363. data["show_time"] = time.Unix(common.Int64All(obj["publishtime"]), 0).Format(date.Date_Full_Layout)
  364. data["projectname"] = obj["projectname"]
  365. procurementlist, _ := obj["procurementlist"].([]interface{})
  366. for _, vs := range procurementlist { //1.采购意向清单数据集打码处理
  367. vsMap, _ := vs.(map[string]interface{})
  368. if vsMap["expurasingtime"] != nil {
  369. data["expurasing_time"] = vsMap["expurasingtime"]
  370. break
  371. }
  372. }
  373. }
  374. }
  375. data["status"] = 1
  376. data["employ_way"] = 1
  377. data["source_id"] = id
  378. data["create_time"] = time.Now().Format(date.Date_Full_Layout)
  379. return data
  380. }
  381. func getBuyerNameById(buyerId string) (buyerName string) {
  382. r := elastic.Get(BuyerIndex, BuyerType, fmt.Sprintf(`{"query":{"bool":{"must":[{"terms":{"_id":["%s"]}}]}},"size":1,"_source":["name"]}`, buyerId))
  383. if r == nil || len(*r) == 0 {
  384. return
  385. }
  386. buyerName, _ = (*r)[0]["name"].(string)
  387. return
  388. }
  389. func getBuyerIdByName(buyeName string) (buyerId string) {
  390. r := elastic.Get("buyer", "buyer", fmt.Sprintf(`{"query":{"bool":{"must":[{"term":{"buyer_name":"%s"}}]}},"size":1,"_source":["city","id"]}`, buyeName))
  391. if r == nil || len(*r) == 0 {
  392. return
  393. }
  394. buyerId, _ = (*r)[0]["_id"].(string)
  395. return
  396. }