marketanalysis.go 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564
  1. package marketanalysis
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/encrypt"
  5. elastic "app.yhyue.com/moapp/jybase/es"
  6. "app.yhyue.com/moapp/jybase/mongodb"
  7. "app.yhyue.com/moapp/jybase/mysql"
  8. "app.yhyue.com/moapp/jybase/redis"
  9. "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
  10. "encoding/json"
  11. "errors"
  12. "fmt"
  13. "log"
  14. "strings"
  15. "sync"
  16. "time"
  17. )
  18. var (
  19. MAPool chan bool
  20. MATimeout int
  21. MAProjectNumLimit int
  22. MAKeyWordsCount int
  23. MinKeyWordsCount int //关键词数量最低值 小于此数量,默认走线上
  24. MaxPCount int //项目最大限制数量
  25. ProjectCount int
  26. PtIndex = "projectset"
  27. PtType = "projectset"
  28. FieldsDetail = `"purchasing","projectname.pname"`
  29. Fields = `"projectname.pname"`
  30. )
  31. func MAInit(limit, timeOut, projectNumLimit, keyWordsCount, pCount, minKCount, maxPCount int, ptIndex, ptType string, fields []string) {
  32. if limit == 0 {
  33. limit = 5
  34. }
  35. MAPool = make(chan bool, limit)
  36. for i := 0; i < limit; i++ {
  37. MAPool <- true
  38. }
  39. if timeOut <= 0 {
  40. timeOut = 20
  41. }
  42. MATimeout = timeOut
  43. if projectNumLimit <= 0 {
  44. projectNumLimit = 600000
  45. }
  46. MAProjectNumLimit = projectNumLimit
  47. if keyWordsCount <= 0 {
  48. keyWordsCount = 300
  49. }
  50. MAKeyWordsCount = keyWordsCount
  51. if minKCount <= 0 {
  52. minKCount = 100
  53. }
  54. MinKeyWordsCount = minKCount
  55. if maxPCount <= 0 {
  56. maxPCount = 5000000
  57. }
  58. MaxPCount = maxPCount
  59. //项目数量
  60. ProjectCount = pCount
  61. //es 索引
  62. if ptIndex != "" {
  63. PtIndex = ptIndex
  64. PtType = ptType
  65. }
  66. //
  67. if len(fields) > 1 {
  68. Fields = fmt.Sprintf(`"%s"`, fields[0])
  69. FieldsDetail = fmt.Sprintf(`"%s"`, strings.Join(fields, `","`))
  70. }
  71. }
  72. // AnalysisRequestParam 接口原请求参数
  73. type AnalysisRequestParam struct {
  74. KeysItemsStr string //分析内容【字符串】结构和o_member_jy.a_items保持一致
  75. RangeTime string //时间【字符串】 时间戳开始-结束时间戳
  76. RangeTimeExtra string //时间【字符串】前段回显使用
  77. Area string //省份【对象字符串】
  78. Industry string //行业【对象字符串】
  79. BuyerClass string //采购单位类型【字符串】多个采购单位类型用逗号拼接
  80. Buyer string //采购单位
  81. Winner string //中标单位
  82. Sort int //排序:默认0:成交时间倒序;1:项目金额倒序
  83. PageSize int //默认每页10条
  84. PageNum int //默认当前第一页
  85. IsDetail bool //是否是项目明细请求
  86. MatchingMode string //匹配方式 title:标题 content:项目名称/标的物
  87. }
  88. type viewKeyWord struct {
  89. Keyword []string `json:"key"` //关键词
  90. Appended []string `json:"appendkey"` //附加词
  91. Exclude []string `json:"notkey"` //排除词
  92. MatchWay int `json:"matchway"` //匹配模式
  93. }
  94. // keyWordGroup 订阅词结构体
  95. type keyWordGroup struct {
  96. A_Key []viewKeyWord `json:"a_key"`
  97. ItemName string `json:"s_item"`
  98. UpdateTime int64 `json:"updatetime"`
  99. }
  100. // AnalysisRequestFormat 格式化后参数
  101. type AnalysisRequestFormat struct {
  102. KeysItems []keyWordGroup
  103. Area, City []string //省份城市
  104. STime, ETime int64 //开始结束时间
  105. Industry []string //行业
  106. BuyerClass []string //采购单位类型
  107. Buyer string //采购单位
  108. Winner string //中标单位
  109. Sort int //排序:默认0:成交时间倒序;1:项目金额倒序
  110. PageSize int //默认每页10条
  111. PageNum int //默认当前第一页
  112. }
  113. type AnalysisEntity struct {
  114. MgoRecordId string
  115. BaseParam AnalysisRequestParam
  116. FormatParam AnalysisRequestFormat
  117. UId, Pid string
  118. ProjectInfo projectInfo
  119. Offline int // 1-离线 2-实时
  120. State int // 状态:默认0:生成中;1:已生成;2:已取消;-1:生成失败
  121. MgoUserId string
  122. Phone string // 手机号
  123. PositionId int64
  124. OriginalTotal int64 // 数据总数
  125. KeysTotal int64 //关键词数量
  126. PositionType int
  127. EntId int
  128. EntUserId int
  129. Source string
  130. Mgo *mongodb.MongodbSim
  131. MySql *mysql.Mysql
  132. }
  133. type projectInfo struct {
  134. Count int64
  135. List []ProjectList
  136. }
  137. type ProjectList struct {
  138. Name string `json:"name"` //项目名称
  139. Id string `json:"id"` //项目id
  140. Area string `json:"area"` //地区
  141. DealTime int64 `json:"dealTime"` //成交时间
  142. BidStatus string `json:"bidStatus"` //项目类型
  143. BuyerClass string `json:"buyerClass"` //采购单位类型
  144. Winner []string `json:"winner"` //中标单位
  145. WinnerId []string `json:"winnerId"` //中标单位id
  146. Buyer string `json:"buyer"` //采购单位
  147. BidAmount float64 `json:"bidAmount"` //中标金额
  148. Budget float64 `json:"budget"` //预算
  149. }
  150. // ForMatData 获取格式化请求参数
  151. func (a *AnalysisEntity) ForMatData() error {
  152. //格式化订阅词
  153. if err := json.Unmarshal([]byte(a.BaseParam.KeysItemsStr), &a.FormatParam.KeysItems); err != nil {
  154. return fmt.Errorf("关键词组格式异常")
  155. }
  156. if a.FormatParam.KeysItems == nil || len(a.FormatParam.KeysItems) == 0 {
  157. return fmt.Errorf("请选择关键词组")
  158. }
  159. var flag bool
  160. // 判断关键词是不是为空
  161. for i := 0; i < len(a.FormatParam.KeysItems); i++ {
  162. items := a.FormatParam.KeysItems[i]
  163. for j := 0; j < len(items.A_Key); j++ {
  164. AKey := items.A_Key[j]
  165. if len(AKey.Keyword) > 0 {
  166. flag = true
  167. break
  168. }
  169. }
  170. if flag {
  171. break
  172. }
  173. }
  174. if !flag {
  175. return fmt.Errorf("请选择关键词组")
  176. }
  177. //格式化时间段
  178. if timeArr := strings.Split(a.BaseParam.RangeTime, "-"); len(timeArr) == 2 {
  179. a.FormatParam.STime = common.Int64All(timeArr[0])
  180. a.FormatParam.ETime = common.Int64All(timeArr[1])
  181. if a.FormatParam.STime == 0 || a.FormatParam.ETime == 0 {
  182. return fmt.Errorf("开始时间和结束时间不能为空")
  183. }
  184. } else {
  185. return fmt.Errorf("时间戳格式异常")
  186. }
  187. //格式化省份、城市
  188. if areaStr := strings.TrimSpace(a.BaseParam.Area); areaStr != "" {
  189. imap := map[string][]string{}
  190. if err := json.Unmarshal([]byte(a.BaseParam.Area), &imap); err != nil {
  191. return fmt.Errorf("非法地区信息")
  192. }
  193. var city, area []string
  194. for name, v := range imap {
  195. if len(v) == 0 {
  196. area = append(area, name)
  197. } else {
  198. for _, vv := range v {
  199. city = append(city, vv)
  200. }
  201. }
  202. }
  203. a.FormatParam.Area = area
  204. a.FormatParam.City = city
  205. }
  206. //格式化行业
  207. if industryStr := strings.TrimSpace(a.BaseParam.Industry); industryStr != "" {
  208. imap := map[string][]string{}
  209. if err := json.Unmarshal([]byte(industryStr), &imap); err != nil {
  210. return fmt.Errorf("非法行业信息")
  211. }
  212. var farr []string
  213. for name, v := range imap {
  214. for _, vv := range v {
  215. farr = append(farr, fmt.Sprintf("%s_%s", name, vv))
  216. }
  217. }
  218. if len(farr) > 0 {
  219. //P510 行业:其它
  220. if qt := jy.IndustryHandle(strings.Join(farr, ",")); len(qt) > 0 {
  221. farr = append(farr, qt...)
  222. }
  223. }
  224. a.FormatParam.Industry = farr
  225. }
  226. //格式化类型
  227. if buyerClassStr := strings.TrimSpace(a.BaseParam.BuyerClass); buyerClassStr != "" {
  228. a.FormatParam.BuyerClass = strings.Split(buyerClassStr, ",")
  229. }
  230. //中标企业
  231. a.FormatParam.Winner = a.BaseParam.Winner
  232. //采购单位
  233. a.FormatParam.Buyer = a.BaseParam.Buyer
  234. //排序
  235. a.FormatParam.Sort = common.If(a.BaseParam.Sort != 0 && a.BaseParam.Sort != 1, 0, a.BaseParam.Sort).(int)
  236. if a.BaseParam.PageNum*a.BaseParam.PageSize > ProjectCount {
  237. a.BaseParam.PageNum = ProjectCount / a.BaseParam.PageSize
  238. }
  239. //当前页码
  240. a.FormatParam.PageNum = common.If(a.BaseParam.PageNum < 1 || a.BaseParam.PageNum > 1000, 1, a.BaseParam.PageNum).(int)
  241. //默认每页10条
  242. a.FormatParam.PageSize = common.If(a.BaseParam.PageSize < 1 || a.BaseParam.PageSize > 100, 50, a.BaseParam.PageSize).(int)
  243. return nil
  244. }
  245. // ForMatData 获取格式化请求参数
  246. func (a *AnalysisEntity) ForMatDataPdf() (string, error) {
  247. //格式化订阅词
  248. if err := json.Unmarshal([]byte(a.BaseParam.KeysItemsStr), &a.FormatParam.KeysItems); err != nil {
  249. return "", fmt.Errorf("关键词组格式异常")
  250. }
  251. //格式化时间段
  252. if timeArr := strings.Split(a.BaseParam.RangeTime, "-"); len(timeArr) == 2 {
  253. a.FormatParam.STime = common.Int64All(timeArr[0])
  254. a.FormatParam.ETime = common.Int64All(timeArr[1])
  255. if a.FormatParam.STime == 0 || a.FormatParam.ETime == 0 {
  256. return "", fmt.Errorf("开始时间和结束时间不能为空")
  257. }
  258. } else {
  259. return "", fmt.Errorf("时间戳格式异常")
  260. }
  261. //格式化省份、城市
  262. if areaStr := strings.TrimSpace(a.BaseParam.Area); areaStr != "" {
  263. imap := map[string][]string{}
  264. if err := json.Unmarshal([]byte(a.BaseParam.Area), &imap); err != nil {
  265. return "", fmt.Errorf("非法地区信息")
  266. }
  267. var city, area []string
  268. for name, v := range imap {
  269. if len(v) == 0 {
  270. area = append(area, name)
  271. } else {
  272. for _, vv := range v {
  273. city = append(city, vv)
  274. }
  275. }
  276. }
  277. a.FormatParam.Area = area
  278. a.FormatParam.City = city
  279. }
  280. //格式化行业
  281. if industryStr := strings.TrimSpace(a.BaseParam.Industry); industryStr != "" {
  282. imap := map[string][]string{}
  283. if err := json.Unmarshal([]byte(industryStr), &imap); err != nil {
  284. return "", fmt.Errorf("非法行业信息")
  285. }
  286. var farr []string
  287. for name, v := range imap {
  288. for _, vv := range v {
  289. farr = append(farr, fmt.Sprintf("%s_%s", name, vv))
  290. }
  291. }
  292. a.FormatParam.Industry = farr
  293. }
  294. //格式化类型
  295. if buyerClassStr := strings.TrimSpace(a.BaseParam.BuyerClass); buyerClassStr != "" {
  296. a.FormatParam.BuyerClass = strings.Split(buyerClassStr, ",")
  297. }
  298. //中标企业
  299. a.FormatParam.Winner = a.BaseParam.Winner
  300. //采购单位
  301. a.FormatParam.Buyer = a.BaseParam.Buyer
  302. //排序
  303. a.FormatParam.Sort = common.If(a.BaseParam.Sort != 0 && a.BaseParam.Sort != 1, 0, a.BaseParam.Sort).(int)
  304. if a.BaseParam.PageNum*a.BaseParam.PageSize > ProjectCount {
  305. a.BaseParam.PageNum = ProjectCount / a.BaseParam.PageSize
  306. }
  307. //当前页码
  308. a.FormatParam.PageNum = common.If(a.BaseParam.PageNum < 1 || a.BaseParam.PageNum > 1000, 1, a.BaseParam.PageNum).(int)
  309. //默认每页10条
  310. a.FormatParam.PageSize = common.If(a.BaseParam.PageSize < 1 || a.BaseParam.PageSize > 100, 50, a.BaseParam.PageSize).(int)
  311. data := map[string]interface{}{
  312. "s_keysItems": a.BaseParam.KeysItemsStr,
  313. "s_rangeTime": a.BaseParam.RangeTime,
  314. "s_rangeTimeExtra": a.BaseParam.RangeTimeExtra,
  315. "s_area": a.BaseParam.Area,
  316. "s_industry": a.BaseParam.Industry,
  317. "s_buyerClass": a.BaseParam.BuyerClass,
  318. "s_matchingMode": a.BaseParam.MatchingMode,
  319. "s_userId": a.UId,
  320. "s_parentId": a.Pid,
  321. "s_mgoUserId": a.MgoUserId,
  322. "i_positionId": a.PositionId,
  323. "s_phone": a.Phone,
  324. "audit": 1,
  325. }
  326. if a.OriginalTotal > 0 {
  327. data["l_originalTotal"] = a.OriginalTotal
  328. }
  329. if a.Source != "" {
  330. data["source"] = a.Source
  331. }
  332. rs, b := a.Mgo.FindOne(ReportHistoryTable, data)
  333. if b && rs != nil && len(*rs) > 0 {
  334. return common.InterfaceToStr((*rs)["_id"]), errors.New("当期分析已存在")
  335. }
  336. return "", nil
  337. }
  338. // GetProjectInfoList 项目明细
  339. func (a *AnalysisEntity) GetProjectInfoList() error {
  340. var (
  341. queryDefault = `,"sort": [{%s}],"from": %d,"size": %d`
  342. start = (a.FormatParam.PageNum - 1) * a.FormatParam.PageSize
  343. sort = `"jgtime": "desc"`
  344. )
  345. if a.FormatParam.Sort > 0 {
  346. sort = `"bidamount": "desc","budget": "desc"`
  347. }
  348. countSql := fmt.Sprintf(a.GetCommonQuerySql(), "")
  349. queryDefault = fmt.Sprintf(queryDefault, sort, start, a.FormatParam.PageSize)
  350. finalSql := fmt.Sprintf(a.GetCommonQuerySql(), queryDefault)
  351. log.Println("finalSql:", finalSql)
  352. count, hits := elastic.GetWithCount(PtIndex, PtType, countSql, finalSql)
  353. //hits, count := elastic.GetOA(PtIndex, PtType, finalSql)
  354. if count > 0 {
  355. a.ProjectInfo.Count = count
  356. source := *hits
  357. for _, v := range source {
  358. var winnerIdArr []string
  359. if common.ObjToString(v["s_winner"]) != "" && v["entidlist"] != nil {
  360. idObjs, _ := v["entidlist"].([]interface{})
  361. for _, v := range common.ObjArrToStringArr(idObjs) {
  362. if v != "" && v != "-" {
  363. v = encrypt.EncodeArticleId2ByCheck(v)
  364. }
  365. winnerIdArr = append(winnerIdArr, v)
  366. }
  367. }
  368. a.ProjectInfo.List = append(a.ProjectInfo.List, ProjectList{
  369. Name: common.ObjToString(v["projectname"]),
  370. Id: encrypt.EncodeArticleId2ByCheck(common.ObjToString(v["id"])),
  371. Area: common.ObjToString(v["area"]),
  372. DealTime: common.Int64All(v["jgtime"]), //截止时间
  373. BidStatus: common.ObjToString(v["bidstatus"]),
  374. BuyerClass: common.ObjToString(v["buyerclass"]),
  375. Winner: strings.Split(common.ObjToString(v["s_winner"]), ","),
  376. WinnerId: winnerIdArr,
  377. Buyer: common.ObjToString(v["buyer"]),
  378. BidAmount: common.Float64All(v["bidamount"]), //中标金额
  379. Budget: common.Float64All(v["budget"]), //预算
  380. })
  381. }
  382. }
  383. return nil
  384. }
  385. // SaveAnalysisRecord 保存分析记录
  386. func (a *AnalysisEntity) SaveAnalysisRecord() error {
  387. if a.Offline == ValueRealTime {
  388. a.State = ReportStateGenerated
  389. } else {
  390. a.State = ReportStateGenerating
  391. }
  392. data := map[string]interface{}{
  393. "s_keysItems": a.BaseParam.KeysItemsStr,
  394. "s_rangeTime": a.BaseParam.RangeTime,
  395. "s_rangeTimeExtra": a.BaseParam.RangeTimeExtra,
  396. "s_area": a.BaseParam.Area,
  397. "s_industry": a.BaseParam.Industry,
  398. "s_buyerClass": a.BaseParam.BuyerClass,
  399. "s_matchingMode": a.BaseParam.MatchingMode,
  400. "s_userId": a.UId,
  401. "s_parentId": a.Pid,
  402. "i_state": common.If(a.Source == "analysisPDF", 1, a.State), //状态:默认0:生成中;1:已生成;2:已取消;-1:生成失败
  403. "l_updateTime": time.Now().Unix(), //生成时间 or 取消时间
  404. "l_createTime": time.Now().Unix(),
  405. "i_offline": common.If(a.Source == "analysisPDF", 2, a.Offline),
  406. "s_mgoUserId": a.MgoUserId,
  407. "i_positionId": a.PositionId,
  408. "s_phone": a.Phone,
  409. }
  410. if a.OriginalTotal > 0 {
  411. data["l_originalTotal"] = a.OriginalTotal
  412. }
  413. if a.KeysTotal > 0 {
  414. data["l_keysTotal"] = a.KeysTotal
  415. }
  416. if a.Source != "" {
  417. data["source"] = a.Source
  418. }
  419. a.MgoRecordId = a.Mgo.Save(ReportHistoryTable, data)
  420. if a.MgoRecordId == "" {
  421. return fmt.Errorf("分析创建异常")
  422. }
  423. return nil
  424. }
  425. // GetAnalysisFromMgoDb 从数据库中获取分析记录
  426. func (a *AnalysisEntity) GetAnalysisFromMgoDb() error {
  427. if a.MgoRecordId == "" {
  428. return fmt.Errorf("缺少参数")
  429. }
  430. queryMap := map[string]interface{}{
  431. "_id": mongodb.StringTOBsonId(a.MgoRecordId),
  432. "i_del": map[string]interface{}{"$ne": 1},
  433. }
  434. if a.UId == a.Pid { //主账号
  435. queryMap["s_parentId"] = a.Pid
  436. } else {
  437. queryMap["s_userId"] = a.UId
  438. }
  439. res, _ := a.Mgo.FindOne(ReportHistoryTable, queryMap)
  440. if res == nil || len(*res) == 0 {
  441. return fmt.Errorf("未查询到相关数据")
  442. }
  443. a.Offline = common.IntAll((*res)["i_offline"])
  444. a.State = common.IntAll((*res)["i_state"])
  445. a.BaseParam.KeysItemsStr, _ = (*res)["s_keysItems"].(string)
  446. a.BaseParam.RangeTime, _ = (*res)["s_rangeTime"].(string)
  447. a.BaseParam.RangeTimeExtra, _ = (*res)["s_rangeTimeExtra"].(string)
  448. a.BaseParam.Area, _ = (*res)["s_area"].(string)
  449. a.BaseParam.Industry, _ = (*res)["s_industry"].(string)
  450. a.BaseParam.BuyerClass, _ = (*res)["s_buyerClass"].(string)
  451. a.BaseParam.MatchingMode, _ = (*res)["s_matchingMode"].(string)
  452. return nil
  453. }
  454. // removeEmptyRecord 删除空报告记录
  455. func (a *AnalysisEntity) removeEmptyRecord() {
  456. queryMap := map[string]interface{}{
  457. "_id": mongodb.StringTOBsonId(a.MgoRecordId),
  458. }
  459. if a.UId == a.Pid { //主账号
  460. queryMap["s_parentId"] = a.Pid
  461. } else {
  462. queryMap["s_userId"] = a.UId
  463. }
  464. a.Mgo.Update(ReportHistoryTable, queryMap, map[string]interface{}{
  465. "$set": map[string]interface{}{"i_del": 1},
  466. }, false, false)
  467. //log.Println("删除空报告", queryMap)
  468. }
  469. // GetRecordList 获取分析记录
  470. func (a *AnalysisEntity) GetRecordList(pageNum, PageSize int, positionType int, entId, entUserId int) (total int, list []map[string]interface{}) {
  471. queryMap := map[string]interface{}{
  472. "i_del": map[string]interface{}{"$ne": 1},
  473. }
  474. if a.UId == a.Pid { //主账号
  475. queryMap["s_parentId"] = a.Pid
  476. } else {
  477. queryMap["s_userId"] = a.UId
  478. }
  479. if pageNum == 1 {
  480. total = a.Mgo.Count(ReportHistoryTable, queryMap)
  481. if total == 0 {
  482. return
  483. }
  484. } else {
  485. total = -1
  486. }
  487. res, _ := a.Mgo.Find(ReportHistoryTable, queryMap, `{"l_createTime":-1}`, nil, false, (pageNum-1)*PageSize, PageSize)
  488. if res == nil || len(*res) == 0 {
  489. return
  490. }
  491. var ids []string
  492. for _, m := range *res {
  493. ids = append(ids, common.InterfaceToStr(m["_id"]))
  494. }
  495. idMap := make(map[string]map[string]interface{})
  496. tName, _ := GetMongoColl(MarketScaleMain)
  497. mids, _ := a.Mgo.Find(tName, map[string]interface{}{
  498. "s_m_id": map[string]interface{}{
  499. "$in": ids,
  500. },
  501. }, "", `{"market_profile":1,"s_m_id":1}`, false, -1, -1)
  502. if mids != nil && len(*mids) > 0 {
  503. for _, m := range *mids {
  504. marketProfile, _ := m["market_profile"].(map[string]interface{})
  505. if common.IntAll(marketProfile["project_count"]) > 0 {
  506. idMap[common.InterfaceToStr(m["s_m_id"])] = marketProfile
  507. }
  508. }
  509. }
  510. //用户消息开关
  511. open := GetMsgOpen(a.Mgo, a.MgoUserId, positionType, entId, entUserId)
  512. for _, row := range *res {
  513. var status int
  514. if row["i_state"] != nil {
  515. status = common.IntAll(row["i_state"])
  516. if status == ReportStateFailed {
  517. status = ReportStateGenerating // 生成失败对外还是展示为生成中
  518. }
  519. }
  520. var (
  521. isDownload bool
  522. )
  523. marketProfile := make(map[string]interface{})
  524. if marketProfile = idMap[mongodb.BsonIdToSId(row["_id"])]; marketProfile != nil && common.IntAll(marketProfile["project_count"]) > 0 && status == 1 {
  525. isDownload = true
  526. }
  527. //P510 回显 移除 其它
  528. industry := common.ObjToString(row["s_industry"])
  529. if industry != "" {
  530. industry = strings.ReplaceAll(industry, "\"其它\"", "")
  531. }
  532. data := map[string]interface{}{
  533. "id": encodeId(mongodb.BsonIdToSId(row["_id"])),
  534. "keysItems": common.ObjToString(row["s_keysItems"]),
  535. "area": common.ObjToString(row["s_area"]),
  536. "industry": industry,
  537. "buyerclass": common.ObjToString(row["s_buyerClass"]),
  538. "rangeTime": common.ObjToString(row["s_rangeTime"]),
  539. "s_rangeTimeExtra": common.ObjToString(row["s_rangeTimeExtra"]),
  540. "createTime": common.Int64All(row["l_createTime"]),
  541. "matchingMode": common.ObjToString(row["s_matchingMode"]), //项目匹配方式
  542. "state": common.If(row["i_state"] == nil, nil, status),
  543. "updateTime": common.Int64All(row["l_updateTime"]),
  544. "msgOpen": open,
  545. "isDownload": isDownload,
  546. "marketProfile": marketProfile,
  547. }
  548. list = append(list, data)
  549. }
  550. return
  551. }
  552. func (a *AnalysisEntity) GetRecordPdfList(pageNum, PageSize int) (total int, list []map[string]interface{}) {
  553. queryMap := map[string]interface{}{
  554. "i_del": map[string]interface{}{"$ne": 1},
  555. "source": "analysisPDF",
  556. }
  557. if a.UId == a.Pid { //主账号
  558. queryMap["s_parentId"] = a.Pid
  559. } else {
  560. queryMap["s_userId"] = a.UId
  561. }
  562. if pageNum == 1 {
  563. total = a.Mgo.Count(ReportHistoryTable, queryMap)
  564. if total == 0 {
  565. return
  566. }
  567. } else {
  568. total = -1
  569. }
  570. res, _ := a.Mgo.Find(ReportHistoryTable, queryMap, `{"l_createTime":-1}`, nil, false, (pageNum-1)*PageSize, PageSize)
  571. if res == nil || len(*res) == 0 {
  572. return
  573. }
  574. for _, row := range *res {
  575. data := map[string]interface{}{
  576. "id": encodeId(mongodb.BsonIdToSId(row["_id"])),
  577. "keysItems": common.ObjToString(row["s_keysItems"]),
  578. "area": common.ObjToString(row["s_area"]),
  579. "industry": common.ObjToString(row["s_industry"]),
  580. "buyerclass": common.ObjToString(row["s_buyerClass"]),
  581. "rangeTime": common.ObjToString(row["s_rangeTime"]),
  582. "s_rangeTimeExtra": common.ObjToString(row["s_rangeTimeExtra"]),
  583. "createTime": common.Int64All(row["l_createTime"]),
  584. "matchingMode": common.ObjToString(row["s_matchingMode"]), //项目匹配方式
  585. "updateTime": common.Int64All(row["l_updateTime"]),
  586. "audit": common.Int64All(row["audit"]),
  587. }
  588. list = append(list, data)
  589. }
  590. return
  591. }
  592. // GetQueryItem 获取查询条件,前端回显使用
  593. func (a *AnalysisEntity) getQueryItem() (map[string]interface{}, error) {
  594. return map[string]interface{}{
  595. "keysItems": a.BaseParam.KeysItemsStr,
  596. "area": a.BaseParam.Area,
  597. "industry": a.BaseParam.Industry,
  598. "buyerclass": a.BaseParam.BuyerClass,
  599. "rangeTime": a.BaseParam.RangeTime,
  600. "s_rangeTimeExtra": a.BaseParam.RangeTimeExtra,
  601. "matchingMode": a.BaseParam.MatchingMode,
  602. }, nil
  603. }
  604. // GetPartResult 分块儿获取报告内容
  605. func (a *AnalysisEntity) GetPartResult(flag int) (map[string]interface{}, error) {
  606. defer common.Catch()
  607. if flag == MarketQueryItem { //返回查询内容
  608. return a.getQueryItem()
  609. }
  610. thisCacheKey := fmt.Sprintf(ReportCacheKey, a.MgoRecordId, flag)
  611. if cacheData := redis.Get(ReportCacheDB, thisCacheKey); cacheData != nil {
  612. if cacheMap, ok := cacheData.(map[string]interface{}); ok && len(cacheMap) > 0 {
  613. return cacheMap, nil
  614. }
  615. }
  616. rData, err := func() (map[string]interface{}, error) {
  617. //控制并发&&超时返回超时异常
  618. select {
  619. case <-time.After(time.Duration(MATimeout) * time.Second * 20):
  620. return nil, fmt.Errorf("查询超时,请稍后重试")
  621. case <-MAPool:
  622. }
  623. start := time.Now()
  624. defer func() {
  625. MAPool <- true
  626. log.Printf("report %s[%d] speed %d ms\n", a.MgoRecordId, flag, time.Now().Sub(start).Milliseconds())
  627. }()
  628. //校验报告是否合法
  629. //if flag != MarketScaleMain {
  630. // if exists, _ := redis.Exists(ReportCacheDB, fmt.Sprintf(ReportCacheKey, a.MgoRecordId, 1)); !exists {
  631. // return nil, fmt.Errorf("报告异常请求,请刷新重试")
  632. // }
  633. //}
  634. // 1. 查mongo
  635. var rData map[string]interface{}
  636. var err error
  637. rData, err = a.GetMongoData(flag)
  638. // 查到数据则直接返回
  639. if err == nil && rData != nil {
  640. return rData, nil
  641. }
  642. // 2.没有查询到数据 判断是不是离线的
  643. // 正常情况下正在离线生的不会走到这里
  644. // 离线的应该生成完报告之后才会调用获取结果接口 这里处理是防止直接调接口传正在离线生的报告
  645. if a.Offline == ValueOffline || a.Offline == 0 {
  646. return nil, err
  647. }
  648. // 3. 实时则查es
  649. rData, err = a.RealTimeQuery(flag)
  650. if err == nil && len(rData) > 0 {
  651. // 4.存库
  652. a.SaveMongoReport(rData, flag)
  653. return rData, err
  654. }
  655. return nil, err
  656. }()
  657. if err == nil && rData != nil && len(rData) > 0 {
  658. delete(rData, "s_m_id")
  659. delete(rData, "_id")
  660. redis.Put(ReportCacheDB, thisCacheKey, rData, ReportCacheTime)
  661. }
  662. return rData, err
  663. }
  664. // 离线 获取采购单位和中部单位数据
  665. func (a *AnalysisEntity) BWData() (buyers []string, winners []string) {
  666. sql := `"buyer_terms": {"terms": {"field": "buyer","size": 50000}},"winner_terms": {"terms": {"field": "winner","size": 50000}}`
  667. finalSql := fmt.Sprintf(a.GetCommonQuerySqlWithAggs(), sql)
  668. res := GetAggs(PtIndex, PtType, finalSql)
  669. if res == nil || len(res) == 0 {
  670. return
  671. }
  672. var bw = BWBuckets{}
  673. for name, object := range res {
  674. bArr, err := object.MarshalJSON()
  675. if len(bArr) == 0 || err != nil {
  676. continue
  677. }
  678. if name == "buyer_terms" {
  679. if json.Unmarshal(bArr, &bw.Buyerterms) != nil {
  680. continue
  681. }
  682. } else if name == "winner_terms" {
  683. if json.Unmarshal(bArr, &bw.Winnerterms) != nil {
  684. continue
  685. }
  686. }
  687. }
  688. for _, bv := range bw.Buyerterms.Buckets {
  689. buyers = append(buyers, bv.Key)
  690. }
  691. for _, wv := range bw.Winnerterms.Buckets {
  692. winners = append(winners, wv.Key)
  693. }
  694. return
  695. }
  696. // 实时查询
  697. func (a *AnalysisEntity) RealTimeQuery(flag int) (map[string]interface{}, error) {
  698. switch flag {
  699. case MarketScaleMain:
  700. rData, err := a.MarketTime()
  701. //非离线
  702. if a.Offline != ValueOffline && err != nil { //若无报告内容,删除报告记录
  703. go a.removeEmptyRecord()
  704. }
  705. if a.Offline == ValueOffline {
  706. //采购单位和中部单位 数据
  707. rData["buyers"], rData["winners"] = a.BWData()
  708. }
  709. return rData, err
  710. case MarketTopProject:
  711. return a.ProjectTop10()
  712. case MarketProjectAllData:
  713. return a.AllData()
  714. case MarketScaleRefine:
  715. return a.MarketScaleRefineQuery()
  716. case MarketBuyerAndWinner:
  717. return a.BuyerWinnerAnalysis(), nil
  718. }
  719. return nil, fmt.Errorf("未知请求")
  720. }
  721. // GetMongoData 从mongo库查询数据
  722. func (a *AnalysisEntity) GetMongoData(flag int) (map[string]interface{}, error) {
  723. collName, err := GetMongoColl(flag)
  724. if err != nil || collName == "" {
  725. return nil, fmt.Errorf("未知请求")
  726. }
  727. // 查询
  728. query := map[string]interface{}{
  729. "s_m_id": a.MgoRecordId,
  730. }
  731. data, b := a.Mgo.FindOne(collName, query)
  732. if !b || data == nil || len(*data) == 0 {
  733. log.Println("没有查询到数据", b, query, collName)
  734. return nil, nil
  735. }
  736. delete(*data, "s_m_id")
  737. delete(*data, "_id")
  738. return *data, nil
  739. }
  740. // GetMongoColl 获取mgo库对应的Coll
  741. func GetMongoColl(flag int) (string, error) {
  742. switch flag {
  743. case MarketScaleMain:
  744. return CollMarketScaleMain, nil
  745. case MarketTopProject:
  746. return CollMarketTopProject, nil
  747. case MarketProjectAllData:
  748. return CollMarketProjectAllData, nil
  749. case MarketScaleRefine:
  750. return CollMarketScaleRefine, nil
  751. case MarketBuyerAndWinner:
  752. return CollMarketBuyerAndWinner, nil
  753. }
  754. return "", fmt.Errorf("未知类型")
  755. }
  756. // SaveMongoReport 数据存mongo库
  757. func (a *AnalysisEntity) SaveMongoReport(rData map[string]interface{}, flag int) {
  758. collName, _ := GetMongoColl(flag)
  759. rData["s_m_id"] = a.MgoRecordId
  760. b, err := json.Marshal(rData)
  761. if err != nil {
  762. log.Println("JSON marshal error:", err)
  763. } else {
  764. var saveMap map[string]interface{}
  765. err = json.Unmarshal(b, &saveMap)
  766. if err != nil {
  767. log.Println("JSON Unmarshal error:", err)
  768. a.Mgo.Save(collName, rData)
  769. } else {
  770. a.Mgo.Save(collName, saveMap)
  771. }
  772. }
  773. }
  774. // GetAnalyzingReport 是否有正在分析的离线报告
  775. func (a *AnalysisEntity) GetAnalyzingReport() string {
  776. query := map[string]interface{}{
  777. "s_userId": a.UId,
  778. "i_state": map[string]interface{}{"$in": []int{ReportStateGenerating, ReportStateFailed}}, //状态:默认0:生成中;1:已生成;2:已取消;-1:生成失败
  779. "i_del": map[string]interface{}{"$ne": 1},
  780. }
  781. //log.Println("query:", query)
  782. rs, b := a.Mgo.FindOne(ReportHistoryTable, query)
  783. //log.Println("rs,b:", rs, b)
  784. if b && rs != nil {
  785. return mongodb.BsonIdToSId((*rs)["_id"])
  786. }
  787. return ""
  788. }
  789. // IsOffline 判断是否符合在线分析的条件
  790. func (a *AnalysisEntity) IsOffline() {
  791. //离线生成:订阅词(关键词+排除词)超过300个(数量支持配置),或单次分析数据超过60万条,则离线生成;
  792. // 查询数据量
  793. countSql := fmt.Sprintf(a.GetCommonQuerySql(), "")
  794. log.Println("IsOffline count SQL:", countSql)
  795. now := time.Now()
  796. dataCount := elastic.Count(PtIndex, PtType, countSql)
  797. if dataCount > int64(MaxPCount) { //提示用户 数据量过大,修改生成报告条件
  798. a.Offline = ValueError
  799. return
  800. }
  801. log.Println("IsOffline 数据量:", dataCount)
  802. a.OriginalTotal = dataCount
  803. keyCount := 0
  804. for i := 0; i < len(a.FormatParam.KeysItems); i++ {
  805. items := a.FormatParam.KeysItems[i]
  806. for j := 0; j < len(items.A_Key); j++ {
  807. AKey := items.A_Key[j]
  808. for k := 0; k < len(AKey.Keyword); k++ {
  809. keyCount++
  810. }
  811. for k := 0; k < len(AKey.Appended); k++ {
  812. keyCount++
  813. }
  814. for k := 0; k < len(AKey.Exclude); k++ {
  815. keyCount++
  816. }
  817. }
  818. }
  819. a.KeysTotal = int64(keyCount)
  820. //关键词数量 < 100 ,默认走线上
  821. if keyCount < MinKeyWordsCount {
  822. a.Offline = ValueRealTime
  823. return
  824. }
  825. if keyCount > MAKeyWordsCount {
  826. // 查询配置
  827. if mac := a.getMarUserAccount(); mac != nil {
  828. if keyCount >= mac.Threshold {
  829. a.Offline = ValueOffline
  830. return
  831. }
  832. } else {
  833. a.Offline = ValueOffline
  834. return
  835. }
  836. }
  837. log.Println("IsOffline 统计数据量耗时:", time.Since(now))
  838. if int(dataCount) > MAProjectNumLimit {
  839. a.Offline = ValueOffline
  840. return
  841. }
  842. a.Offline = ValueRealTime
  843. return
  844. }
  845. type MarUserAccount struct {
  846. Threshold int // 关键词离线标准量
  847. }
  848. // 获取离线市场报告分析关键词标准信息
  849. func (a *AnalysisEntity) getMarUserAccount() *MarUserAccount {
  850. rs := a.MySql.SelectBySql(fmt.Sprintf("SELECT threshold FROM %s where position_id=? and state = 0;", TablejianyuMarUserAccount), a.PositionId)
  851. if rs != nil && len(*rs) > 0 {
  852. return &MarUserAccount{Threshold: common.IntAll((*rs)[0]["threshold"])}
  853. }
  854. return nil
  855. }
  856. func (a *AnalysisEntity) GetReportState() (generated bool, needUpdate bool, err error) {
  857. // 查库
  858. err = a.GetAnalysisFromMgoDb()
  859. if err != nil {
  860. return
  861. }
  862. // 已经生成的可以直接返回
  863. if a.State == ReportStateGenerated {
  864. generated = true
  865. return
  866. }
  867. // 该字段没有值 说明是还没有被更新的历史数据 需要更新
  868. // 且判断之后后续需要更新i_state和i_offline字段
  869. if a.Offline == 0 {
  870. needUpdate = true
  871. }
  872. // 如果没有值的话 说明这是历史数据 需要接着走下面的流程进行判断
  873. // 格式化数据 用于后面校验个数
  874. if err = a.ForMatData(); err != nil {
  875. return
  876. }
  877. return
  878. }
  879. // Cancel 取消正在分析中的报告
  880. func (a *AnalysisEntity) Cancel() (bool, error) {
  881. // 取消报告
  882. queryMap := map[string]interface{}{
  883. "_id": a.MgoRecordId,
  884. "i_state": map[string]interface{}{"$in": []int{ReportStateGenerating, ReportStateFailed}}, //状态:默认0:生成中;1:已生成;2:已取消;-1:生成失败
  885. "i_del": map[string]interface{}{"$ne": 1},
  886. }
  887. if a.UId == a.Pid { //主账号
  888. queryMap["s_parentId"] = a.Pid
  889. } else {
  890. queryMap["s_userId"] = a.UId
  891. }
  892. //验证
  893. rs, b := a.Mgo.FindOne(ReportHistoryTable, queryMap)
  894. //
  895. if !b || rs == nil {
  896. return false, fmt.Errorf("未查询到该记录")
  897. }
  898. update := a.Mgo.UpdateById(ReportHistoryTable, a.MgoRecordId, map[string]interface{}{"$set": map[string]interface{}{
  899. "l_updateTime": time.Now().Unix(),
  900. "i_state": ReportStateCanceled,
  901. }})
  902. if !update {
  903. log.Println("分析报告取消失败:", a.MgoRecordId)
  904. return false, fmt.Errorf("取消失败")
  905. }
  906. // redis里面放取消标识
  907. redis.Put(ReportCacheDB, fmt.Sprintf(ReportCanceledKey, a.MgoRecordId), 1, ReportCanceledTime)
  908. return update, nil
  909. }
  910. // UpdateOffline 更新报告是否是离线报告
  911. func (a *AnalysisEntity) UpdateOffline(offline bool) bool {
  912. set := map[string]interface{}{
  913. "i_state": common.If(offline, ReportStateGenerating, ReportStateGenerated),
  914. "i_offline": common.If(offline, ValueOffline, ValueRealTime),
  915. "l_updateTime": time.Now().Unix(),
  916. "s_mgoUserId": a.MgoUserId, // 这里更新这些字段是因为这几个字段是p437 版本新加上的 历史数据没有这些字段
  917. "s_positionId": a.PositionId,
  918. "s_phone": a.Phone,
  919. }
  920. if a.OriginalTotal > 0 {
  921. set["l_originalTotal"] = a.OriginalTotal
  922. }
  923. data := map[string]interface{}{
  924. "$set": set,
  925. }
  926. update := a.Mgo.UpdateById(ReportHistoryTable, a.MgoRecordId, data)
  927. if !update {
  928. log.Println("UpdateOffline 更新报告状态失败:", data, a.MgoRecordId)
  929. }
  930. return update
  931. }
  932. // UpdateState 更新报告生成状态
  933. func (a *AnalysisEntity) UpdateState(state int) bool {
  934. setMap := map[string]interface{}{
  935. "i_state": state,
  936. "l_updateTime": time.Now().Unix(),
  937. }
  938. if state == ReportStateGenerated {
  939. setMap["l_finishTime"] = time.Now().Unix()
  940. }
  941. data := map[string]interface{}{
  942. "$set": setMap,
  943. }
  944. update := a.Mgo.UpdateById(ReportHistoryTable, a.MgoRecordId, data)
  945. if !update {
  946. log.Println("UpdateState 更新报告生成状态失败:", data, a.MgoRecordId)
  947. }
  948. return update
  949. }
  950. // Delete 删除正在分析中的报告
  951. func (a *AnalysisEntity) Delete() (bool, error) {
  952. // 删除报告
  953. queryMap := map[string]interface{}{
  954. "_id": a.MgoRecordId,
  955. "i_del": map[string]interface{}{"$ne": 1},
  956. }
  957. if a.UId == a.Pid { //主账号
  958. queryMap["s_parentId"] = a.Pid
  959. } else {
  960. queryMap["s_userId"] = a.UId
  961. }
  962. //验证
  963. rs, b := a.Mgo.FindOne(ReportHistoryTable, queryMap)
  964. //
  965. if !b || rs == nil {
  966. return false, fmt.Errorf("未查询到该记录")
  967. }
  968. update := a.Mgo.UpdateById(ReportHistoryTable, a.MgoRecordId, map[string]interface{}{"$set": map[string]interface{}{
  969. "l_updateTime": time.Now().Unix(),
  970. "i_del": 1,
  971. }})
  972. if !update {
  973. log.Println("分析报告删除失败:", a.MgoRecordId)
  974. return false, fmt.Errorf("删除失败")
  975. }
  976. // redis里面放取消标识
  977. redis.Put(ReportCacheDB, fmt.Sprintf(ReportCanceledKey, a.MgoRecordId), 1, ReportCanceledTime)
  978. return update, nil
  979. }
  980. // GetCommonQuerySql 公共筛选
  981. func (a *AnalysisEntity) GetCommonQuerySql() string {
  982. var musts, bools []string
  983. //时间
  984. musts = append(musts, fmt.Sprintf(`{"range":{"jgtime":{"gte":%d,"lte":%d}}}`, a.FormatParam.STime, a.FormatParam.ETime))
  985. //地区
  986. if len(a.FormatParam.Area) > 0 || len(a.FormatParam.City) > 0 {
  987. var areaCity []string
  988. if len(a.FormatParam.Area) > 0 {
  989. areaCity = append(areaCity, fmt.Sprintf(`{"terms":{"area":["%s"]}}`, strings.Join(a.FormatParam.Area, `","`)))
  990. }
  991. if len(a.FormatParam.City) > 0 {
  992. areaCity = append(areaCity, fmt.Sprintf(`{"terms":{"city":["%s"]}}`, strings.Join(a.FormatParam.City, `","`)))
  993. }
  994. musts = append(musts, fmt.Sprintf(`{"bool":{"should":[%s],"minimum_should_match": 1}}`, strings.Join(areaCity, ",")))
  995. }
  996. //行业
  997. if len(a.FormatParam.Industry) > 0 {
  998. musts = append(musts, fmt.Sprintf(`{"terms":{"subscopeclass":["%s"]}}`, strings.Join(a.FormatParam.Industry, `","`)))
  999. }
  1000. //类型
  1001. if len(a.FormatParam.BuyerClass) > 0 {
  1002. musts = append(musts, fmt.Sprintf(`{"terms":{"buyerclass":["%s"]}}`, strings.Join(a.FormatParam.BuyerClass, `","`)))
  1003. }
  1004. //分析报告中标状态限制
  1005. musts = append(musts, fmt.Sprintf(queryBoolMust, pSearchDecMust))
  1006. //订阅词
  1007. for _, v := range getAllKeywordArr(a.FormatParam.KeysItems) {
  1008. if sql := getKeyWordSql(v, a.BaseParam.MatchingMode); sql != "" {
  1009. bools = append(bools, sql)
  1010. }
  1011. }
  1012. //中标企业
  1013. if a.FormatParam.Winner != "" {
  1014. var winnerId string
  1015. if mongodb.IsObjectIdHex(a.FormatParam.Winner) {
  1016. winnerId = a.FormatParam.Winner
  1017. } else {
  1018. rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query": {"bool": {"must": [{"term": {"company_name": "%s"}}]}},"_source":["_id"],"size": 1}`, a.FormatParam.Winner))
  1019. if rData != nil && len(*rData) > 0 {
  1020. winnerId = common.InterfaceToStr((*rData)[0]["_id"])
  1021. }
  1022. }
  1023. if winnerId != "" {
  1024. musts = append(musts, fmt.Sprintf(`{"term":{"entidlist":"%s"}}`, winnerId))
  1025. } else {
  1026. musts = append(musts, fmt.Sprintf(`{"term":{"s_winner":"%s"}}`, a.FormatParam.Winner))
  1027. }
  1028. }
  1029. //采购单位
  1030. if a.FormatParam.Buyer != "" {
  1031. musts = append(musts, fmt.Sprintf(`{"term":{"buyer":"%s"}}`, a.FormatParam.Buyer))
  1032. }
  1033. return fmt.Sprintf(`{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}%s}`, strings.Join(musts, ","), strings.Join(bools, ","), common.If(len(bools) > 0, 1, 0).(int), "%s")
  1034. }
  1035. // GetCommonQuerySqlWithAggs 此方法用于聚合查询
  1036. func (a *AnalysisEntity) GetCommonQuerySqlWithAggs() string {
  1037. return fmt.Sprintf(a.GetCommonQuerySql(), `,"aggs":{%s},"size":0`)
  1038. }
  1039. // 市场概况+时间分布
  1040. func (a *AnalysisEntity) MarketTime() (map[string]interface{}, error) {
  1041. var (
  1042. sql []string
  1043. monthB, yearB bool
  1044. MonthRange, YearRange string
  1045. isOffline = a.Offline == 1
  1046. )
  1047. sql = append(sql, fmt.Sprintf(aggsMarketAnalysis, "thismarket", fmt.Sprintf(`{"key":"%s","from":%d,"to":%d}`, "market", a.FormatParam.STime, a.FormatParam.ETime)))
  1048. n_stime := a.FormatParam.STime
  1049. var n_mae AnalysisEntity
  1050. n_mae.FormatParam = a.FormatParam
  1051. n_mae.BaseParam = a.BaseParam
  1052. n_mae.MgoRecordId = a.MgoRecordId
  1053. n_mae.FormatParam.ETime = a.FormatParam.ETime
  1054. if time.Unix(a.FormatParam.STime, 0).AddDate(1, 0, 0).Unix() >= time.Unix(a.FormatParam.ETime, 0).Unix() {
  1055. n_stime = getPreviousMarket(time.Unix(a.FormatParam.STime, 0), time.Unix(a.FormatParam.ETime, 0))
  1056. sql = append(sql, fmt.Sprintf(aggsMarketAnalysis, "oldmarket", fmt.Sprintf(`{"key":"%s","from":%d,"to":%d}`, "market", n_stime, a.FormatParam.STime)))
  1057. }
  1058. if isOffline || time.Unix(a.FormatParam.STime, 0).AddDate(0, 1, 0).Unix() < time.Unix(a.FormatParam.ETime, 0).Unix() {
  1059. var mon_time, year_time int64
  1060. stime, etime := time.Unix(a.FormatParam.STime, 0), time.Unix(a.FormatParam.ETime, 0)
  1061. monthB, MonthRange = GetMonthData(isOffline, stime, etime)
  1062. sql = append(sql, fmt.Sprintf(projectTimeDistribution, "monthtime", MonthRange))
  1063. if monthB {
  1064. mon_time = stime.AddDate(0, -1, 0).Unix()
  1065. } else {
  1066. mon_time = a.FormatParam.STime
  1067. }
  1068. //年度数据
  1069. yearB, YearRange = GetYearData(isOffline, stime, etime)
  1070. sql = append(sql, fmt.Sprintf(projectTimeDistribution, "yeartime", YearRange))
  1071. if yearB {
  1072. year_time = stime.AddDate(-1, 0, 0).Unix()
  1073. } else {
  1074. year_time = a.FormatParam.STime
  1075. }
  1076. if n_stime > mon_time {
  1077. n_stime = mon_time
  1078. }
  1079. if n_stime > year_time {
  1080. n_stime = year_time
  1081. }
  1082. }
  1083. //非离线
  1084. if !isOffline {
  1085. n_mae.FormatParam.STime = n_stime
  1086. }
  1087. finalSql := fmt.Sprintf(n_mae.GetCommonQuerySqlWithAggs(), strings.Join(sql, ","))
  1088. log.Printf("final MarketScaleRefineQuery sql: %s", finalSql)
  1089. rMap := make(map[string]interface{})
  1090. rMapData := make(map[string]interface{})
  1091. thisRow := marketTime{}
  1092. res := GetAggs(PtIndex, PtType, finalSql)
  1093. if res == nil || len(res) == 0 {
  1094. return nil, fmt.Errorf("未查询到项目")
  1095. }
  1096. Rest(res, &thisRow)
  1097. if thisRow.Thismarket.Buckets != nil && len(thisRow.Thismarket.Buckets) != 0 {
  1098. Projectmarket := thisRow.Thismarket.Buckets[0]
  1099. if Projectmarket.ProjectCount.DocCount == 0 {
  1100. return nil, fmt.Errorf("未查询到项目数据")
  1101. }
  1102. if Projectmarket.ProjectCount.DocCount > MAProjectNumLimit {
  1103. return nil, fmt.Errorf("项目数量超出上限")
  1104. }
  1105. rMapData["project_count"] = Projectmarket.ProjectCount.DocCount
  1106. rMapData["projctamout"] = Projectmarket.ProjectAmount.Value
  1107. rMapData["projectavgmoney"] = Projectmarket.ProjectAvgMoney.Value
  1108. rMapData["buyercount"] = Projectmarket.BuyerCount.Value
  1109. rMapData["winnercount"] = Projectmarket.WinnerCount.Value
  1110. if thisRow.Oldmarket.Buckets != nil && len(thisRow.Oldmarket.Buckets) != 0 {
  1111. oldProjectmarket := thisRow.Oldmarket.Buckets[0]
  1112. //环比数据
  1113. rMapData["projctamount_ratio"] = sequential(Projectmarket.ProjectAmount.Value, oldProjectmarket.ProjectAmount.Value)
  1114. rMapData["project_count_ratio"] = sequential(float64(Projectmarket.ProjectCount.DocCount), float64(oldProjectmarket.ProjectCount.DocCount))
  1115. rMapData["projectavgmoney_ratio"] = sequential(Projectmarket.ProjectAvgMoney.Value, oldProjectmarket.ProjectAvgMoney.Value)
  1116. rMapData["buyercount_ratio"] = sequential(float64(Projectmarket.BuyerCount.Value), float64(oldProjectmarket.BuyerCount.Value))
  1117. rMapData["winnercount_ratio"] = sequential(float64(Projectmarket.WinnerCount.Value), float64(oldProjectmarket.WinnerCount.Value))
  1118. }
  1119. }
  1120. rMap["market_profile"] = rMapData
  1121. if thisRow.Monthtime.Buckets != nil && len(thisRow.Monthtime.Buckets) != 0 {
  1122. rMap["month_distribution"] = n_mae.TimeData(monthB, thisRow.Monthtime.Buckets)
  1123. }
  1124. if thisRow.Yeartime.Buckets != nil && len(thisRow.Yeartime.Buckets) != 0 {
  1125. rMap["year_distribution"] = n_mae.TimeData(yearB, thisRow.Yeartime.Buckets)
  1126. }
  1127. return rMap, nil
  1128. }
  1129. // 时间分布月,年通用数据处理
  1130. func (a *AnalysisEntity) TimeData(_b bool, thisRow []Buckets) map[string]interface{} {
  1131. var count_ss, amout_ss []map[string]interface{}
  1132. for k, v := range thisRow {
  1133. //环比多取一期数据
  1134. if _b && k == 0 {
  1135. continue
  1136. }
  1137. count := make(map[string]interface{})
  1138. amount := make(map[string]interface{})
  1139. count["minth"] = v.Key
  1140. count["value"] = v.ScaleTotal.DocCount
  1141. amount["minth"] = v.Key
  1142. amount["value"] = v.ScaleAmount.Value
  1143. //整月,年统计环比
  1144. if _b {
  1145. doccount := thisRow[k-1].ScaleTotal.DocCount
  1146. amountvalue := thisRow[k-1].ScaleAmount.Value
  1147. count["ratio"] = sequential(float64(v.ScaleTotal.DocCount), float64(doccount))
  1148. amount["ratio"] = sequential(v.ScaleAmount.Value, amountvalue)
  1149. }
  1150. count_ss = append(count_ss, count)
  1151. amout_ss = append(amout_ss, amount)
  1152. }
  1153. rMapData := make(map[string]interface{})
  1154. rMapData["project_count"] = count_ss
  1155. rMapData["project_amount"] = amout_ss
  1156. return rMapData
  1157. }
  1158. // top10
  1159. func (a *AnalysisEntity) ProjectTop10() (rMap map[string]interface{}, err error) {
  1160. finalSql := fmt.Sprintf(a.GetCommonQuerySql(), queryTop10)
  1161. log.Println("ProjectTop10:", finalSql)
  1162. hits := elastic.Get(PtIndex, PtType, finalSql)
  1163. rMap = map[string]interface{}{}
  1164. bArr := []map[string]interface{}{}
  1165. source := *hits
  1166. for _, v := range source {
  1167. bA := map[string]interface{}{}
  1168. if v["ids"] != nil && len(InterToSliceString(v["ids"])) > 0 {
  1169. idss := InterToSliceString(v["ids"])
  1170. bA["_id"] = encodeId(idss[len(idss)-1])
  1171. } else {
  1172. bA["_id"] = nil
  1173. }
  1174. if v["area"] == "" {
  1175. bA["city"] = nil
  1176. } else {
  1177. bA["area"] = v["area"]
  1178. }
  1179. if v["city"] == "" {
  1180. bA["city"] = nil
  1181. } else {
  1182. bA["city"] = v["city"]
  1183. }
  1184. bA["jgtime"] = v["jgtime"]
  1185. bA["projectname"] = v["s_projectname"]
  1186. bA["sortprice"] = v["sortprice"]
  1187. ids := v["entidlist"]
  1188. var id_s []string
  1189. var winner_s []string
  1190. for _, i := range InterToSliceString(ids) {
  1191. iid := encodeId(i)
  1192. id_s = append(id_s, iid)
  1193. }
  1194. bA["eidlist"] = id_s
  1195. bA["winner_s"] = nil
  1196. if common.ObjToString(v["s_winner"]) != "" {
  1197. w_s := strings.Split(common.ObjToString(v["s_winner"]), ",")
  1198. for _, vv := range w_s {
  1199. winner_s = append(winner_s, vv)
  1200. }
  1201. bA["winner_s"] = winner_s
  1202. }
  1203. bArr = append(bArr, bA)
  1204. }
  1205. rMap["ProjectTop10"] = bArr
  1206. return
  1207. }
  1208. func (a *AnalysisEntity) AllData() (rMap map[string]interface{}, err error) {
  1209. rMap = map[string]interface{}{}
  1210. var aggs []string
  1211. area := a.FormatParam.Area
  1212. city := a.FormatParam.City
  1213. buyclass := a.FormatParam.BuyerClass
  1214. aggs = append(aggs, aggsAllCM, fmt.Sprintf(queryAggsSortprice, sortpriceStr), aggsArea)
  1215. if (len(area) + len(city)) != 1 {
  1216. aggs = append(aggs, aggsAreaAmounttop3, aggsAreaCounttop3)
  1217. }
  1218. if len(buyclass) != 1 {
  1219. //aggs = append(aggs, aggs_buyerclass, aggs_buyerclass_other, aggs_buyerclass_amounttop3, aggs_buyerclass_counttop3)
  1220. aggs = append(aggs, aggsBuyerclass, aggsBuyerclassAmounttop3, aggsBuyerclassCounttop3)
  1221. }
  1222. finalSql := fmt.Sprintf(a.GetCommonQuerySqlWithAggs(), strings.Join(aggs, ","))
  1223. log.Println("allData sql:", finalSql)
  1224. res := GetAggs(PtIndex, PtType, finalSql)
  1225. if res == nil || len(res) == 0 {
  1226. return
  1227. }
  1228. thisRow := AreaCTop{}
  1229. for name, object := range res {
  1230. bArr, err := object.MarshalJSON()
  1231. if len(bArr) == 0 || err != nil {
  1232. continue
  1233. }
  1234. if name == "project_amount" {
  1235. if json.Unmarshal(bArr, &thisRow.Amount) != nil {
  1236. continue
  1237. }
  1238. } else if name == "project_count" {
  1239. if json.Unmarshal(bArr, &thisRow.ProjectCount) != nil {
  1240. continue
  1241. }
  1242. //} else if name == "buyerclass_scale_other" {
  1243. // if json.Unmarshal(bArr, &thisRow.BuyerclassScaleOther) != nil {
  1244. // continue
  1245. // }
  1246. } else if name == "project_count_not0" {
  1247. if json.Unmarshal(bArr, &thisRow.CountNot0) != nil {
  1248. continue
  1249. }
  1250. } else if name == "sortprice_ranges" {
  1251. if json.Unmarshal(bArr, &thisRow.SortpriceRanges) != nil {
  1252. continue
  1253. }
  1254. } else if name == "area_distribution" {
  1255. if json.Unmarshal(bArr, &thisRow.AreaDistribution) != nil {
  1256. continue
  1257. }
  1258. } else if name == "buyerclass_scale" {
  1259. if json.Unmarshal(bArr, &thisRow.BuyerclassScale) != nil {
  1260. continue
  1261. }
  1262. } else if name == "area_amount_top3" {
  1263. if json.Unmarshal(bArr, &thisRow.AreaAmountTop3) != nil {
  1264. continue
  1265. }
  1266. } else if name == "area_count_top3" {
  1267. if json.Unmarshal(bArr, &thisRow.AreaCountTop3) != nil {
  1268. continue
  1269. }
  1270. } else if name == "buyerclass_amount_top3" {
  1271. if json.Unmarshal(bArr, &thisRow.BuyclassAmountTop3) != nil {
  1272. continue
  1273. }
  1274. } else if name == "buyerclass_count_top3" {
  1275. if json.Unmarshal(bArr, &thisRow.BuyclassCountTop3) != nil {
  1276. continue
  1277. }
  1278. }
  1279. }
  1280. data := ProjectScale(thisRow)
  1281. area_data := AreaDistribute(thisRow)
  1282. customerData, customerOther := CustomerDistribute(thisRow)
  1283. //customerOther, customerData := CustomerDistributeDetails(thisRow, customerDetails)
  1284. var ids []string
  1285. for _, v := range thisRow.AreaAmountTop3.Buckets {
  1286. for _, va := range v.WinnerTop.Buckets {
  1287. ids = append(ids, va.Winner)
  1288. }
  1289. }
  1290. for _, v := range thisRow.BuyclassAmountTop3.Buckets {
  1291. for _, va := range v.WinnerTop.Buckets {
  1292. ids = append(ids, va.Winner)
  1293. }
  1294. }
  1295. for _, v := range thisRow.AreaCountTop3.Buckets {
  1296. for _, va := range v.WinnerTop.Buckets {
  1297. ids = append(ids, va.Winner)
  1298. }
  1299. }
  1300. for _, v := range thisRow.BuyclassCountTop3.Buckets {
  1301. for _, va := range v.BidcountTop.Buckets {
  1302. ids = append(ids, va.Winner)
  1303. }
  1304. }
  1305. eid := IDToName(ids)
  1306. rMap["projectScale"] = data
  1307. rMap["area_infos"] = area_data
  1308. rMap["customer_scale"] = customerData
  1309. rMap["customer_scale_other"] = customerOther //客户分布(其它)
  1310. rMap["scaleAreaAmountTop"] = AmountCompute(thisRow, "area", eid)
  1311. rMap["scaleBuyclassAmountTop"] = AmountCompute(thisRow, "buyclass", eid)
  1312. rMap["scaleAreaCountTop"] = CountCompute(thisRow, "area", eid)
  1313. rMap["scaleBuyclassCountTop"] = CountCompute(thisRow, "buyclass", eid)
  1314. return
  1315. }
  1316. // MarketScaleRefineQuery 细化聚合
  1317. func (a *AnalysisEntity) MarketScaleRefineQuery() (rMap map[string]interface{}, err error) {
  1318. //关键词分组聚合
  1319. var aggsGroup []string
  1320. //获取总金额及总数
  1321. aggsGroup = append(aggsGroup, `"projectAmount":{"sum":{"field":"sortprice"}}`)
  1322. aggsGroup = append(aggsGroup, `"projectTotal":{"filter":{"match_all":{}}}`)
  1323. itemDataMap := map[string]int64{}
  1324. for _, group := range a.FormatParam.KeysItems {
  1325. var bools []string
  1326. for _, v := range getGroupKeywordArr(group.A_Key) {
  1327. if sql := getKeyWordSql(v, a.BaseParam.MatchingMode); sql != "" {
  1328. bools = append(bools, sql)
  1329. }
  1330. }
  1331. if len(bools) > 0 {
  1332. aggsGroup = append(aggsGroup, fmt.Sprintf(`"%s":{"filter":{"bool":{"should":[%s],"minimum_should_match": 1}},"aggs":{"project_count":{"filter":{"match_all":{}}},"project_amount":{"sum":{"field":"sortprice"}},"winner_total_top":{"terms":{"field":"entidlist","exclude":["-"],"order":[{"refine_winner_total":"desc"}],"size":%d},"aggs":{"refine_winner_total":{"filter":{"match_all":{}}}}},"winner_amount_top":{"terms":{"field":"entidlist","exclude":["-"],"order":[{"refine_winner_amount":"desc"}],"size":%d},"aggs":{"refine_winner_amount":{"sum":{"field":"sortprice"}}}}}}`, group.ItemName, strings.Join(bools, ","), topWinnerLimit, topWinnerLimit))
  1333. }
  1334. itemDataMap[group.ItemName] = group.UpdateTime
  1335. }
  1336. finalSql := fmt.Sprintf(a.GetCommonQuerySqlWithAggs(), strings.Join(aggsGroup, ","))
  1337. fmt.Println("finalSql-----4", finalSql)
  1338. rMap = map[string]interface{}{}
  1339. res := GetAggs(PtIndex, PtType, finalSql)
  1340. if res == nil || len(res) == 0 {
  1341. return
  1342. }
  1343. scale := scaleRefineData{IdSwitch: map[string]string{}}
  1344. for name, object := range res {
  1345. bArr, err := object.MarshalJSON()
  1346. if len(bArr) == 0 || err != nil {
  1347. continue
  1348. }
  1349. if name == "projectTotal" {
  1350. st := simpleTotal{}
  1351. if err := json.Unmarshal(bArr, &st); err == nil {
  1352. scale.Total = st
  1353. }
  1354. continue
  1355. } else if name == "projectAmount" {
  1356. ss := simpleSum{}
  1357. if err := json.Unmarshal(bArr, &ss); err == nil {
  1358. scale.Amount = ss
  1359. }
  1360. continue
  1361. }
  1362. thisRow := scaleRefineRow{}
  1363. if err := json.Unmarshal(bArr, &thisRow); err != nil {
  1364. continue
  1365. }
  1366. thisRow.ItemName = name
  1367. thisRow.UpdateTime = itemDataMap[name]
  1368. scale.Data = append(scale.Data, &thisRow)
  1369. }
  1370. scale.formatData() //获取所需数据
  1371. scale.doIdSwitch() //补充企业名称
  1372. return map[string]interface{}{
  1373. "scaleRefineAll": scale.ReturnData.Overall,
  1374. "scaleRefineTotalTop": scale.ReturnData.TotalTop,
  1375. "scaleRefineAmountTop": scale.ReturnData.AmountTop,
  1376. }, nil
  1377. }
  1378. // 采购单位分析
  1379. func (a *AnalysisEntity) BuyerWinnerAnalysis() map[string]interface{} {
  1380. var datas []string
  1381. //采购单位-采购规模分布
  1382. //buyer_scalefmt := fmt.Sprintf(buyer_procurement_scale, sortprice_str)
  1383. //采购单位-项目数量 采购单位-项目金额
  1384. datas = append(datas, buyerProcurementScale, buyerCount, buyerSortprice)
  1385. //中标单位-规模分布
  1386. //winner_scalefmt := fmt.Sprintf(winner_procurement_scale, sortprice_str)
  1387. //中标单位-项目数量 中标单位-项目金额
  1388. datas = append(datas, winnerProcurementScale, winnerCount, winnerSortprice)
  1389. finalSql := fmt.Sprintf(a.GetCommonQuerySqlWithAggs(), strings.Join(datas, ","))
  1390. log.Printf("final PurchasingAnalysiseQuery sql: %s", finalSql)
  1391. t := time.Now()
  1392. res := GetAggs(PtIndex, PtType, finalSql)
  1393. if res == nil || len(res) == 0 {
  1394. return nil
  1395. }
  1396. //计算entidlist大于1的中标单位金额
  1397. entArrMap := make(map[string]float64)
  1398. winnerKeyMap := make(map[string]int)
  1399. newSql := strings.ReplaceAll(fmt.Sprintf(a.GetCommonQuerySql(), `,"sort": [{"sortprice": {"order": "desc"}}], "_source": ["entidlist","sortprice"],"size":10000`), `],"should":[`, fmt.Sprintf(`%s],"should":[`, `,{"script": {"script": {"source": "doc['entidlist'].length > 1"}}}`))
  1400. log.Println("winner new sql", newSql)
  1401. multiBid := elastic.Get(PtIndex, PtType, newSql)
  1402. if multiBid != nil && len(*multiBid) > 0 {
  1403. for _, m := range *multiBid {
  1404. entidlist, _ := m["entidlist"].([]interface{})
  1405. entArr := common.ObjArrToStringArr(entidlist)
  1406. sortprice := common.Float64All(m["sortprice"])
  1407. entLen := len(entArr)
  1408. switch entLen {
  1409. case 1:
  1410. entArrMap[entArr[0]] = sortprice
  1411. //winnerKeyMap[entArr[0]]++
  1412. case 0:
  1413. default:
  1414. assessedAmount := sortprice / common.Float64All(entLen)
  1415. for _, m2 := range entArr {
  1416. //winnerKeyMap[m2]++
  1417. entArrMap[m2] = assessedAmount
  1418. }
  1419. }
  1420. }
  1421. }
  1422. log.Println("采购单位-中标单位分析报告es查询耗时===", time.Since(t))
  1423. var thisBuyerWinnerRow BuyerWinnerRow
  1424. for name, object := range res {
  1425. bArr, err := object.MarshalJSON()
  1426. if len(bArr) == 0 || err != nil {
  1427. continue
  1428. }
  1429. if name == "buyer_amount_distribution" {
  1430. if json.Unmarshal(bArr, &thisBuyerWinnerRow.BuyerAmountDistribution) != nil {
  1431. continue
  1432. }
  1433. } else if name == "buyer_count_top3" {
  1434. if json.Unmarshal(bArr, &thisBuyerWinnerRow.BuyerCountTop3) != nil {
  1435. continue
  1436. }
  1437. } else if name == "buyer_amount_top3" {
  1438. if json.Unmarshal(bArr, &thisBuyerWinnerRow.BuyerAmountTop3) != nil {
  1439. continue
  1440. }
  1441. } else if name == "winner_amount_distribution" {
  1442. if json.Unmarshal(bArr, &thisBuyerWinnerRow.WinnerAmountDistribution) != nil {
  1443. continue
  1444. }
  1445. } else if name == "winner_count_top3" {
  1446. if json.Unmarshal(bArr, &thisBuyerWinnerRow.WinnerCountTop3) != nil {
  1447. continue
  1448. }
  1449. } else if name == "winner_amount_top3" {
  1450. if json.Unmarshal(bArr, &thisBuyerWinnerRow.WinnerAmountTop3) != nil {
  1451. continue
  1452. }
  1453. }
  1454. }
  1455. var winnerKeys []string
  1456. for _, v := range thisBuyerWinnerRow.BuyerCountTop3.Buckets {
  1457. for _, v1 := range v.SWinnerTop.Buckets {
  1458. winnerKeyMap[v1.Key]++
  1459. }
  1460. }
  1461. for _, v := range thisBuyerWinnerRow.BuyerAmountTop3.Buckets {
  1462. for _, v1 := range v.SWinnerTop.Buckets {
  1463. winnerKeyMap[v1.Key]++
  1464. }
  1465. }
  1466. for _, v := range thisBuyerWinnerRow.WinnerCountTop3.SWinnerCount {
  1467. winnerKeyMap[v.Key]++
  1468. }
  1469. for _, v := range thisBuyerWinnerRow.WinnerAmountTop3.SWinnerAmount {
  1470. winnerKeyMap[v.Key]++
  1471. }
  1472. for k := range winnerKeyMap {
  1473. winnerKeys = append(winnerKeys, k)
  1474. }
  1475. winnerName := GetEntNameByIds(winnerKeys)
  1476. //rMap := make(map[string]interface{})
  1477. var rMap = sync.Map{}
  1478. sy := sync.WaitGroup{}
  1479. sy.Add(2)
  1480. go BuyerAnalysis(thisBuyerWinnerRow, &rMap, winnerName, &sy)
  1481. go WinningAnalysis(thisBuyerWinnerRow, &rMap, entArrMap, winnerName, &sy)
  1482. sy.Wait()
  1483. log.Println("采购单位-中标单位分析报告程序计算耗时===", time.Since(t))
  1484. rMaps := make(map[string]interface{})
  1485. rMap.Range(func(key, value interface{}) bool {
  1486. rMaps[common.InterfaceToStr(key)] = value
  1487. return true
  1488. })
  1489. return rMaps
  1490. }
  1491. func (a *AnalysisEntity) GetPdfPageApi() (finalDate map[string]interface{}, err error) {
  1492. var (
  1493. wg = sync.WaitGroup{}
  1494. lock = &sync.Mutex{}
  1495. )
  1496. finalDate = make(map[string]interface{})
  1497. for i := 1; i <= 5; i++ {
  1498. wg.Add(1)
  1499. go func(flag int) {
  1500. defer wg.Done()
  1501. mgoData, _ := a.GetMongoData(flag)
  1502. lock.Lock()
  1503. for s, i2 := range mgoData {
  1504. finalDate[s] = i2
  1505. }
  1506. lock.Unlock()
  1507. }(i)
  1508. }
  1509. wg.Wait()
  1510. return
  1511. }