CoopHistoryService.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "strings"
  7. "time"
  8. "app.yhyue.com/moapp/jybase/common"
  9. "app.yhyue.com/moapp/jybase/encrypt"
  10. "app.yhyue.com/moapp/jybase/redis"
  11. T "bp.jydev.jianyu360.cn/CRM/networkManage/api/common"
  12. "bp.jydev.jianyu360.cn/CRM/networkManage/api/internal/types"
  13. "github.com/ClickHouse/clickhouse-go/v2/lib/driver"
  14. "github.com/shopspring/decimal"
  15. "github.com/zeromicro/go-zero/core/logx"
  16. )
  17. var (
  18. INDEX_1 = "transaction_info_all"
  19. sql_2_0 = `SELECT buyer_id FROM information.transaction_info_all WHERE project_id = ?`
  20. sql_2_2 = `select id as buyer_id from ent_info where company_name=? order by id desc limit 1`
  21. sql_2_1 = `SELECT project_id, project_name, zbtime FROM information.transaction_info_all WHERE buyer_id = ? AND has(winner, ?) ORDER BY zbtime DESC`
  22. sql_2_1_1 = `SELECT project_id, project_name, zbtime FROM information.transaction_info_all WHERE buyer_id = ? AND agency = ? ORDER BY zbtime DESC`
  23. )
  24. type ResultData struct {
  25. SourceType string `json:"SourceType"`
  26. EntName string `json:"EntName"`
  27. EntId string `json:"EntId"`
  28. EntPerson string `json:"EntPerson"`
  29. Middleman string `json:"Middleman"`
  30. ProjectNum int `json:"ProjectNum"`
  31. TotalAmount float64 `json:"TotalAmount"`
  32. RecentTime int64 `json:"RecentTime"`
  33. NearlyYears bool `json:"NearlyYears"`
  34. SupEnt string `json:"SupEnt"` // 上级
  35. NextEnt string `json:"NextEnt"` // 下级
  36. Relationship string `json:"Relationship"` // 关系
  37. BuyerId string `json:"BuyerId"`
  38. IsIgnore bool `json:"isIgnore"`
  39. }
  40. type ResultDatas []*ResultData
  41. func (n *ResultDatas) Len() int {
  42. return len(*n)
  43. }
  44. func (n *ResultDatas) Less(i, j int) bool {
  45. if (*n)[i].RecentTime == (*n)[j].RecentTime {
  46. return (*n)[i].EntName < (*n)[j].EntName
  47. }
  48. return (*n)[i].RecentTime > (*n)[j].RecentTime
  49. }
  50. func (n *ResultDatas) Swap(i, j int) {
  51. (*n)[i], (*n)[j] = (*n)[j], (*n)[i]
  52. }
  53. type ProjectTmp struct {
  54. BuyerId string `ch:"buyer_id"`
  55. }
  56. type Cooperate struct {
  57. Near bool
  58. ZbTime int64
  59. }
  60. type AggStruct struct {
  61. Id string `ch:"id"`
  62. Name string `ch:"name"`
  63. Sum uint64 `ch:"sum"`
  64. ProjectMoney decimal.Decimal `ch:"project_money"`
  65. Zbtime int64 `ch:"zbtime"`
  66. }
  67. func GetPrList(req *types.CoopHistoryReq) (result []*ResultData, size_1, size_2, size_3, size_4 int64) {
  68. pTmp := ProjectTmp{}
  69. var err error
  70. if req.Pid != "" {
  71. err = T.ClickhouseConn.QueryRow(context.TODO(), sql_2_0, req.Pid).ScanStruct(&pTmp)
  72. } else if req.Buyer != "" {
  73. err = T.ClickhouseConn.QueryRow(context.TODO(), sql_2_2, req.Buyer).ScanStruct(&pTmp)
  74. } else {
  75. return
  76. }
  77. if err != nil || pTmp.BuyerId == "" {
  78. return
  79. }
  80. // firstparty:甲方 supplier:供应商 adiffb:同甲异业 middleman:中间人 agency:招标代理机构 sup_sub: 上下级
  81. // 1、同甲异业数据/ 3、招标代理机构渠道
  82. // 中间人可介绍业主
  83. if req.ChannelType == "0" || req.ChannelType == "4" {
  84. var r3 []map[string]interface{}
  85. r3 = FindMiddleman([]string{fmt.Sprintf("'%s'", pTmp.BuyerId)}, req.PositionId, r3)
  86. size_4 = int64(len(r3))
  87. for _, m := range r3 {
  88. tmp := ResultData{
  89. SourceType: "middleman",
  90. EntName: common.ObjToString(m["b_name"]),
  91. EntId: common.ObjToString(m["b_id"]),
  92. EntPerson: common.ObjToString(m["personName"]),
  93. Relationship: "业主的关系人",
  94. BuyerId: pTmp.BuyerId,
  95. }
  96. result = append(result, &tmp)
  97. }
  98. }
  99. // 关联单位
  100. if req.ChannelType == "0" || req.ChannelType == "2" {
  101. var r4 []map[string]interface{}
  102. r4 = Findfirstparty([]string{fmt.Sprintf("'%s'", pTmp.BuyerId)}, r4)
  103. size_2 = int64(len(r4))
  104. for _, m := range r4 {
  105. tmp := ResultData{
  106. SourceType: "sup_sub",
  107. EntName: common.ObjToString(m["b_name"]),
  108. EntId: common.ObjToString(m["b_id"]),
  109. EntPerson: common.ObjToString(m["personName"]),
  110. Relationship: common.ObjToString(m["relationship"]),
  111. BuyerId: pTmp.BuyerId,
  112. }
  113. result = append(result, &tmp)
  114. }
  115. }
  116. if req.ChannelType == "0" || req.ChannelType == "1" {
  117. scopeClass := FindBusiness(req.EntId, req.EntUserId)
  118. r1 := GetWinnerData(scopeClass, pTmp.BuyerId)
  119. size_1 = int64(len(r1))
  120. for _, m := range r1 {
  121. tmp := ResultData{
  122. SourceType: "adiffb",
  123. EntName: m.Name,
  124. ProjectNum: int(m.Sum),
  125. BuyerId: pTmp.BuyerId,
  126. RecentTime: m.Zbtime,
  127. }
  128. tmp.TotalAmount, _ = m.ProjectMoney.Float64()
  129. if time.Now().AddDate(-3, 0, 0).Unix() <= tmp.RecentTime {
  130. tmp.NearlyYears = true
  131. }
  132. result = append(result, &tmp)
  133. }
  134. }
  135. if req.ChannelType == "0" || req.ChannelType == "3" {
  136. r2 := GetAgencyData(pTmp.BuyerId)
  137. size_3 = int64(len(r2))
  138. for _, m := range r2 {
  139. tmp := ResultData{
  140. SourceType: "agency",
  141. EntName: m.Name,
  142. ProjectNum: int(m.Sum),
  143. BuyerId: pTmp.BuyerId,
  144. RecentTime: m.Zbtime,
  145. }
  146. tmp.TotalAmount, _ = m.ProjectMoney.Float64()
  147. if time.Now().AddDate(-3, 0, 0).Unix() <= tmp.RecentTime {
  148. tmp.NearlyYears = true
  149. }
  150. result = append(result, &tmp)
  151. }
  152. }
  153. return
  154. }
  155. func GetWinnerData(scopeClass string, bid string) []AggStruct {
  156. ass := []AggStruct{}
  157. if scopeClass == "" {
  158. return ass
  159. }
  160. winnerKey := fmt.Sprintf("networkManage_coopHistory_winner_%s", common.GetMd5String(scopeClass+"_"+bid))
  161. wb, err := redis.GetBytes("newother", winnerKey)
  162. if err == nil && wb != nil {
  163. json.Unmarshal(*wb, &ass)
  164. return ass
  165. }
  166. args := []interface{}{bid, bid}
  167. wh, newArgs := common.WhArgs(strings.Split(scopeClass, ","))
  168. args = append(args, newArgs...)
  169. rows, err1 := T.ClickhouseConn.Query(context.TODO(), `select winner as name,winner_id as id,sum(1) as sum,sum(project_money) as project_money,max(zbtime) as zbtime from information.transaction_info_all ARRAY JOIN winner_id,winner
  170. WHERE buyer_id IN (SELECT buyer_id from information.transaction_info_all WHERE has(winner_id,?) and buyer_id<>'') and winner_id<>? AND hasAny(topscopeclass,[`+wh+`])=0 group by winner,winner_id`, args...)
  171. if err1 != nil {
  172. logx.Error(err1)
  173. return ass
  174. }
  175. for rows.Next() {
  176. as := AggStruct{}
  177. if err := rows.ScanStruct(&as); err != nil {
  178. logx.Error(err)
  179. continue
  180. }
  181. ass = append(ass, as)
  182. }
  183. rows.Close()
  184. if err := rows.Err(); err != nil {
  185. logx.Error(err)
  186. }
  187. redis.Put("newother", winnerKey, ass, T.C.CacheTimeOut)
  188. return ass
  189. }
  190. //代理机构
  191. func GetAgencyData(bid string) []AggStruct {
  192. ass := []AggStruct{}
  193. agencyKey := fmt.Sprintf("networkManage_coopHistory_agency_%s", bid)
  194. wb, err := redis.GetNewBytes("newother", agencyKey)
  195. if err == nil && wb != nil {
  196. json.Unmarshal(*wb, &ass)
  197. return ass
  198. }
  199. rows, err1 := T.ClickhouseConn.Query(context.TODO(), `select agency as name,agency_id as id,sum(1) as sum,sum(project_money) as project_money,max(zbtime) as zbtime from information.transaction_info_all where buyer_id=? and agency<>'' and agency_id<>'' GROUP by agency,agency_id`, bid)
  200. if err1 != nil {
  201. logx.Error(err1)
  202. return ass
  203. }
  204. for rows.Next() {
  205. as := AggStruct{}
  206. if err := rows.ScanStruct(&as); err != nil {
  207. logx.Error(err)
  208. continue
  209. }
  210. ass = append(ass, as)
  211. }
  212. rows.Close()
  213. if err := rows.Err(); err != nil {
  214. logx.Error(err)
  215. }
  216. redis.Put("newother", agencyKey, ass, T.C.CacheTimeOut)
  217. return ass
  218. }
  219. type P_History struct {
  220. ProjectId string `ch:"project_id"`
  221. ProjectName string `ch:"project_name"`
  222. ZbTime int64 `ch:"zbtime"`
  223. Href string `ch:"href"`
  224. }
  225. // @Author jianghan
  226. // @Description 合作历史
  227. // @Date 2024/4/20
  228. func GetData3(source string, buyerId, winnerId string) (result []*P_History) {
  229. var rows driver.Rows
  230. if source == "1" {
  231. rows, _ = T.ClickhouseConn.Query(context.TODO(), sql_2_1_1, buyerId, winnerId)
  232. } else if source == "2" {
  233. rows, _ = T.ClickhouseConn.Query(context.TODO(), sql_2_1, buyerId, winnerId)
  234. }
  235. for rows.Next() {
  236. pHis := P_History{}
  237. _ = rows.ScanStruct(&pHis)
  238. pHis.Href = fmt.Sprintf("/article/content/%s.html", encrypt.CommonEncodeArticle("content", pHis.ProjectId))
  239. result = append(result, &pHis)
  240. }
  241. return
  242. }
  243. // @Author jianghan
  244. // @Description 上次合作时间
  245. // @Date 2024/4/24
  246. func LastTimeCoop(buyerId, ent, stype string) (bool, int64) {
  247. zbtime := int64(0)
  248. near := false
  249. if stype == "adiffb" {
  250. sql := `SELECT zbtime FROM information.transaction_info_all WHERE buyer_id = ? AND has(winner, ?) ORDER BY zbtime DESC LIMIT 1`
  251. _ = T.ClickhouseConn.QueryRow(context.TODO(), sql, buyerId, ent).Scan(&zbtime)
  252. } else if stype == "agency" {
  253. sql := `SELECT zbtime FROM information.transaction_info_all WHERE buyer_id = ? AND agency = ? ORDER BY zbtime DESC LIMIT 1`
  254. _ = T.ClickhouseConn.QueryRow(context.TODO(), sql, buyerId, ent).Scan(&zbtime)
  255. }
  256. timestamp := time.Now().AddDate(-3, 0, 0).Unix()
  257. if timestamp <= zbtime {
  258. near = true
  259. }
  260. return near, zbtime
  261. }
  262. func LastTimeCoopBath(positionId int64, buyerId string, winners, agencys []string) (map[string]*Cooperate, map[string]*Cooperate) {
  263. adiffb, agency := map[string]*Cooperate{}, map[string]*Cooperate{}
  264. if buyerId == "" {
  265. return adiffb, agency
  266. }
  267. var toSearch = func(tp int, query string, ws []string) {
  268. logx.Info("LastTimeCoopBath once start ", positionId)
  269. defer logx.Info("LastTimeCoopBath once over ", positionId)
  270. wh, newArgs := T.NetworkCom.WhArgs(ws)
  271. query = fmt.Sprintf(query, wh)
  272. args := []interface{}{buyerId}
  273. args = append(args, newArgs...)
  274. rows, err := T.ClickhouseConn.Query(context.Background(), query, args...)
  275. if err != nil {
  276. logx.Error(err)
  277. return
  278. }
  279. for rows.Next() {
  280. var (
  281. one string
  282. zbtime int64
  283. )
  284. if err := rows.Scan(&one, &zbtime); err != nil {
  285. logx.Error(err)
  286. continue
  287. }
  288. c := &Cooperate{
  289. ZbTime: zbtime,
  290. }
  291. timestamp := time.Now().AddDate(-3, 0, 0).Unix()
  292. if timestamp <= c.ZbTime {
  293. c.Near = true
  294. }
  295. if tp == 1 {
  296. adiffb[one] = c
  297. } else {
  298. agency[one] = c
  299. }
  300. }
  301. rows.Close()
  302. if err := rows.Err(); err != nil {
  303. logx.Error(err)
  304. }
  305. }
  306. if len(winners) > 0 {
  307. key := fmt.Sprintf("networkManage_lastTimeCoop_winner_%s", common.GetMd5String(buyerId+"_"+strings.Join(winners, ",")))
  308. wb, err := redis.GetBytes("newother", key)
  309. if err == nil {
  310. json.Unmarshal(*wb, &adiffb)
  311. } else {
  312. sql := `SELECT winner_one,max(zbtime) FROM information.transaction_info_all ARRAY JOIN winner AS winner_one WHERE buyer_id=? AND hasAny(winner,[%s])) group by winner_one`
  313. wns := []string{}
  314. for _, v := range winners {
  315. wns = append(wns, v)
  316. if len(wns) == 50 {
  317. toSearch(1, sql, wns)
  318. wns = []string{}
  319. }
  320. }
  321. if len(wns) > 0 {
  322. toSearch(1, sql, wns)
  323. }
  324. redis.Put("newother", key, adiffb, T.C.CacheTimeOut)
  325. }
  326. }
  327. if len(agencys) > 0 {
  328. key := fmt.Sprintf("networkManage_lastTimeCoop_agency_%s", common.GetMd5String(buyerId+"_"+strings.Join(agencys, ",")))
  329. wb, err := redis.GetBytes("newother", key)
  330. if err == nil {
  331. json.Unmarshal(*wb, &agency)
  332. } else {
  333. sql := `SELECT agency,max(zbtime) FROM information.transaction_info_all WHERE buyer_id=? AND agency in (%s) group by agency`
  334. acs := []string{}
  335. for _, v := range agencys {
  336. acs = append(acs, v)
  337. if len(acs) == 50 {
  338. toSearch(2, sql, acs)
  339. acs = []string{}
  340. }
  341. }
  342. if len(acs) > 0 {
  343. toSearch(2, sql, acs)
  344. }
  345. redis.Put("newother", key, agency, T.C.CacheTimeOut)
  346. }
  347. }
  348. return adiffb, agency
  349. }