plistService.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package service
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. P "app.yhyue.com/moapp/jybase/mapping"
  5. T "bp.jydev.jianyu360.cn/CRM/application/api/common"
  6. "bp.jydev.jianyu360.cn/CRM/application/api/internal/types"
  7. "context"
  8. "fmt"
  9. "strings"
  10. )
  11. const (
  12. pageSize = 100
  13. sql_1 = `SELECT count(1) FROM information.transaction_info WHERE buyer_id = ?`
  14. sql_2 = `SELECT relate_id, is_handle, is_ignore, is_create FROM crm.connection_status WHERE position_id = ? AND itype = 2`
  15. sql_3 = `SELECT b.company_id, b.company_name, b.contact_name, a.relate_id, a.relate_name FROM connection_introduce a INNER JOIN connection b ON b.position_id =%d ND a.connection_id = b.idAND b.state = 1AND a.type = 1AND b.type = 4AND a.relate_Id = %s`
  16. )
  17. type ProjectData struct {
  18. count int64
  19. hasNextPage bool
  20. pList []*ProjectEntry
  21. }
  22. type ProjectEntry struct {
  23. projectName string
  24. buyer string
  25. buyerId string
  26. sWinner string
  27. area string
  28. city string
  29. district string
  30. startTime int64
  31. entTime int64
  32. subClass string
  33. propertyForm string
  34. businessType string
  35. }
  36. func GetProjectList(req *types.ProjectListReq) (resultList []map[string]interface{}, hasNextPage bool, total int) {
  37. preSales := preSalesStatus(req.PositionId)
  38. isSqlPage := false
  39. if req.SaleStatus == 0 {
  40. isSqlPage = true // 是否sql分页
  41. }
  42. findSql := getQuerySql(req, isSqlPage)
  43. rows, err := T.ClickhouseConn.Query(context.TODO(), findSql)
  44. defer rows.Close()
  45. if err != nil {
  46. return nil, false, 0
  47. }
  48. i := 0
  49. info := make(map[string]interface{})
  50. for rows.Next() {
  51. rows.Scan(&info)
  52. resultList = append(resultList, info)
  53. i++
  54. }
  55. filterData(req, resultList, preSales, isSqlPage)
  56. if !isSqlPage {
  57. start := (req.PageNum - 1) * req.PageSize
  58. end := start + req.PageSize
  59. if req.PageNum > 1 {
  60. resultList = resultList[start:end]
  61. } else {
  62. resultList = resultList[:pageSize]
  63. }
  64. total = len(resultList)
  65. if total > pageSize {
  66. hasNextPage = true
  67. } else {
  68. hasNextPage = false
  69. }
  70. }
  71. moreInfo(req, resultList)
  72. return
  73. }
  74. // @Author jianghan
  75. // @Description 销售机会线索状态
  76. // @Date 2024/4/18
  77. func preSalesStatus(posid int64) (m1 map[string]interface{}) {
  78. m1 = make(map[string]interface{})
  79. info := T.CrmMysql.SelectBySql(sql_2, posid)
  80. if info != nil && len(*info) > 0 {
  81. for _, m := range *info {
  82. m1[common.ObjToString(m["relate_id"])] = m
  83. }
  84. }
  85. return m1
  86. }
  87. func getQuerySql(req *types.ProjectListReq, isPage bool) (findSql string) {
  88. querys := []string{}
  89. // 商机类型
  90. if req.BusinessType != "" {
  91. querys = append(querys, fmt.Sprintf(" a.business_type in (%s) ", req.BusinessType))
  92. }
  93. if req.ProjectName != "" {
  94. querys = append(querys, " a.projectname like '% "+req.ProjectName+"%'")
  95. }
  96. if req.StartTime > 0 && req.EntTime > 0 {
  97. st := req.StartTime + 90*24*60*60
  98. et := req.StartTime + 90*24*60*60
  99. querys = append(querys, fmt.Sprintf(" a.endtime>=%d and a.endtime<=%d", st, et))
  100. } else if req.StartTime > 0 && req.EntTime == 0 {
  101. st := req.StartTime + 90*24*60*60
  102. querys = append(querys, fmt.Sprintf(" a.endtime>=%d", st))
  103. } else if req.StartTime == 0 && req.EntTime > 0 {
  104. et := req.StartTime + 90*24*60*60
  105. querys = append(querys, fmt.Sprintf(" a.endtime<=%d", et))
  106. } else {
  107. querys = append(querys, " a.endtime>0")
  108. }
  109. var regionArr = []string{}
  110. if req.Area != "" || req.City != "" || req.District != "" {
  111. //城市
  112. city := []string{}
  113. for _, v := range strings.Split(req.City, ",") {
  114. if P.BidCodeMapping.City[v] != "" {
  115. city = append(city, fmt.Sprint(P.BidCodeMapping.City[v]))
  116. }
  117. }
  118. if len(city) > 0 {
  119. regionArr = append(regionArr, fmt.Sprintf(" a.city in (%s) ", strings.Join(city, ",")))
  120. }
  121. //区域
  122. area := []string{}
  123. for _, v := range strings.Split(req.Area, ",") {
  124. if P.BidCodeMapping.Area[v] != "" {
  125. area = append(area, fmt.Sprint(P.BidCodeMapping.Area[v]))
  126. }
  127. }
  128. if len(area) > 0 {
  129. regionArr = append(regionArr, fmt.Sprintf(" a.area in (%s) ", strings.Join(area, ",")))
  130. }
  131. //区域
  132. district := []string{}
  133. if req.District != "" {
  134. for _, v := range strings.Split(req.District, ",") {
  135. cityName := strings.Split(v, "_")[0]
  136. districtName := strings.Split(v, "_")[1]
  137. if P.BidCodeMapping.District[cityName][districtName] != "" {
  138. district = append(district, fmt.Sprint(P.BidCodeMapping.District[cityName][districtName]))
  139. }
  140. }
  141. }
  142. if len(district) > 0 {
  143. regionArr = append(regionArr, fmt.Sprintf(" a.district in (%s) ", strings.Join(district, ",")))
  144. }
  145. if len(regionArr) > 0 {
  146. querys = append(querys, fmt.Sprintf("(%s)", strings.Join(regionArr, "or")))
  147. }
  148. }
  149. if req.SubClass != "" {
  150. arr := []string{}
  151. for _, v := range strings.Split(req.SubClass, ",") {
  152. arr = append(arr, fmt.Sprintf(`"物业_%s"`, v))
  153. }
  154. querys = append(querys, fmt.Sprintf(" a.subclass in (%s) ", strings.Join(regionArr, ",")))
  155. }
  156. // 项目金额
  157. if req.Amount != "" && strings.Contains(req.Amount, "-") {
  158. minPriceStr, maxPriceStr := strings.Split(req.Amount, "-")[0], strings.Split(req.Amount, "-")[1]
  159. minPrice := common.Int64All(common.Float64All(minPriceStr) * 10000) //换成元
  160. maxPrice := common.Int64All(common.Float64All(maxPriceStr) * 10000) //换成元
  161. if minPriceStr != "" && maxPriceStr != "" {
  162. querys = append(querys, fmt.Sprintf("((a.project_money>=%d and a.project_money<=%d))", minPrice, maxPrice))
  163. } else if minPriceStr != "" {
  164. querys = append(querys, fmt.Sprintf("(a.project_money>=%d)", minPrice))
  165. } else if maxPriceStr != "" {
  166. querys = append(querys, fmt.Sprintf("(a.project_money<=%d)", maxPrice))
  167. }
  168. }
  169. //物业业态
  170. if req.PropertyForm != "" {
  171. arr := []string{}
  172. for _, v := range strings.Split(req.PropertyForm, ",") {
  173. arr = append(arr, fmt.Sprintf(`"%s"`, v))
  174. }
  175. querys = append(querys, fmt.Sprintf(" a.property_form in (%s) ", strings.Join(arr, ",")))
  176. }
  177. findSql = "select a.project_id,a.project_name,a.project_budget,a.project_money,a.business_type,a.buyer from"
  178. findSql = fmt.Sprintf("%s from %s a where %s ", findSql, "information.transaction_info", strings.Join(querys, " and "))
  179. if isPage {
  180. findSql += fmt.Sprintf(" limit %d,%d", (req.PageNum-1)*pageSize, pageSize)
  181. }
  182. return
  183. }
  184. // @Author jianghan
  185. // @Description 过滤数据/补充销售机会状态信息,返回分页结果数据
  186. // @Date 2024/4/18
  187. func filterData(req *types.ProjectListReq, resultList []map[string]interface{}, preSales map[string]interface{}, isSqlPage bool) {
  188. var newList []map[string]interface{}
  189. f := ""
  190. v := 0
  191. if req.SaleStatus == 1 {
  192. f = "is_handle"
  193. v = 0
  194. } else if req.SaleStatus == 2 {
  195. f = "is_ignore"
  196. v = 0
  197. } else if req.SaleStatus == 3 {
  198. f = "is_create"
  199. v = 1
  200. }
  201. for _, m := range resultList {
  202. if m1, ok := preSales[common.ObjToString(m["project_id"])].(map[string]interface{}); ok {
  203. m["is_handle"] = m1["is_handle"]
  204. m["is_ignore"] = m1["is_ignore"]
  205. m["is_create"] = m1["is_create"]
  206. if !isSqlPage && m1[f] == v {
  207. newList = append(newList, m)
  208. }
  209. }
  210. }
  211. if len(newList) > 0 {
  212. resultList = newList
  213. }
  214. }
  215. // @Author jianghan
  216. // @Description 补充人脉 等信息
  217. // @Date 2024/4/17
  218. func moreInfo(req *types.ProjectListReq, list []map[string]interface{}) (result []map[string]interface{}) {
  219. for _, m := range list {
  220. // 人脉、人脉所在单位项目 conn_type: 1/人脉可转介绍项目 conn_type: 2
  221. field1 := ""
  222. query1 := map[string]interface{}{
  223. "position_id": req.PositionId,
  224. "company_id": common.ObjToString(m["buyer_id"]),
  225. "status": 1,
  226. }
  227. info1 := T.CrmMysql.FindOne("connection", query1, field1, "")
  228. if info1 != nil && len(*info1) > 0 {
  229. m["my_conn"] = true
  230. m["conn_type"] = 1
  231. } else {
  232. m["my_conn"] = false
  233. }
  234. if m["conn_type"] != nil {
  235. query2 := map[string]interface{}{
  236. "company_id": common.ObjToString(m["buyer_id"]),
  237. }
  238. info2 := T.CrmMysql.FindOne("connection", query2, field1, "")
  239. if info2 != nil && len(*info2) > 0 {
  240. m["conn_type"] = 1
  241. } else {
  242. m["conn_type"] = 2
  243. }
  244. }
  245. // 转介绍成功率高标签
  246. count := 0
  247. err := T.ClickhouseConn.QueryRow(context.TODO(), sql_1, common.ObjToString(m["buyer_id"])).Scan(&count)
  248. if err != nil && count > 2 {
  249. m["high_success"] = true
  250. } else {
  251. m["high_success"] = false
  252. }
  253. // 人脉路径
  254. // 有我的人脉标签时不需要查询人脉路径信息
  255. if m["my_conn"] == false {
  256. //ConnectionsHandle([]string{common.ObjToString(m["buyer_id"])}, req.PositionId, false)
  257. }
  258. }
  259. return list
  260. }