edb_data.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. package services
  2. import (
  3. "eta/eta_forum_hub/models"
  4. "eta/eta_forum_hub/models/mgodb"
  5. "eta/eta_forum_hub/utils"
  6. "fmt"
  7. "strconv"
  8. "time"
  9. "github.com/shopspring/decimal"
  10. )
  11. func BatchAddOrUpdateEdbData(req []*models.AddEdbDataReq) (err error) {
  12. for _, reqData := range req {
  13. if reqData.EdbType == 1 {
  14. err = AddOrUpdateEdbData(reqData.EdbInfoId, reqData.EdbCode, reqData.DataList)
  15. if err != nil {
  16. return
  17. }
  18. } else {
  19. err = AddOrUpdateEdbDataCalculate(reqData.EdbInfoId, reqData.EdbCode, reqData.DataList)
  20. if err != nil {
  21. return
  22. }
  23. }
  24. }
  25. return
  26. }
  27. func AddOrUpdateEdbData(edbInfoId int, edbCode string, dataList []*models.EdbDataBase) (err error) {
  28. // 指标数据为空则不更新
  29. if len(dataList) == 0 {
  30. return
  31. }
  32. addList := make([]interface{}, 0)
  33. existList, err := mgodb.GetEdbDataBaseByEdbCode(edbCode)
  34. if err != nil {
  35. err = fmt.Errorf("查询指标数据出错 error, %v", err)
  36. return
  37. }
  38. existMap := make(map[string]*mgodb.EdbDataBase, len(existList))
  39. deleteMap := make(map[string]struct{}, len(existList))
  40. for _, exist := range existList {
  41. tmp := exist.DataTime.Format(utils.FormatDate)
  42. existMap[tmp] = exist
  43. deleteMap[tmp] = struct{}{}
  44. }
  45. for _, v := range dataList {
  46. dataTime, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  47. if e != nil {
  48. err = fmt.Errorf("时间格式化出错 error, %v", e)
  49. return
  50. }
  51. val, e := strconv.ParseFloat(v.Value, 64)
  52. if e != nil {
  53. err = fmt.Errorf("指标数据格式化出错 error, %v", e)
  54. return
  55. }
  56. if oldObj, ok := existMap[v.DataTime]; !ok {
  57. tmp := &mgodb.EdbDataBase{
  58. EdbInfoId: edbInfoId,
  59. EdbCode: v.EdbCode,
  60. DataTime: dataTime,
  61. Value: val,
  62. Status: v.Status,
  63. CreateTime: v.CreateTime,
  64. ModifyTime: v.ModifyTime,
  65. DataTimestamp: v.DataTimestamp,
  66. }
  67. addList = append(addList, tmp)
  68. if len(addList) >= 500 {
  69. err = mgodb.InsertEdbDataBatch(addList)
  70. if err != nil {
  71. err = fmt.Errorf("批量新增指标数据失败 error, %v", e)
  72. return
  73. }
  74. addList = make([]interface{}, 0)
  75. }
  76. } else {
  77. delete(deleteMap, v.DataTime)
  78. if val != oldObj.Value {
  79. err = mgodb.ModifyValueEdbDataValue(oldObj.EdbDataId, val, v.ModifyTime)
  80. if err != nil {
  81. err = fmt.Errorf("更新指标数据出错 error, %v", err)
  82. return
  83. }
  84. }
  85. }
  86. }
  87. //遍历deletemap,找出需要删除的日期
  88. {
  89. removeDateList := make([]time.Time, 0)
  90. for dateTime := range deleteMap {
  91. dateT, e := time.ParseInLocation(utils.FormatDate, dateTime, time.Local)
  92. if e != nil {
  93. err = fmt.Errorf("日期格式错误 error, %v", e)
  94. return
  95. }
  96. removeDateList = append(removeDateList, dateT)
  97. }
  98. removeNum := len(removeDateList)
  99. if removeNum > 0 {
  100. err = mgodb.DeleteEdbInfoDataByEdbCodeAndDateList(edbCode, removeDateList)
  101. if err != nil {
  102. err = fmt.Errorf("删除多余日期失败,error, %v", err)
  103. return
  104. }
  105. }
  106. }
  107. if len(addList) > 0 {
  108. err = mgodb.InsertEdbDataBatch(addList)
  109. }
  110. return
  111. }
  112. func AddOrUpdateEdbDataCalculate(edbInfoId int, edbCode string, dataList []*models.EdbDataBase) (err error) {
  113. // 指标数据为空则不更新
  114. if len(dataList) == 0 {
  115. return
  116. }
  117. addList := make([]interface{}, 0)
  118. existList, err := mgodb.GetEdbDataCalculateByEdbCode(edbCode)
  119. if err != nil {
  120. err = fmt.Errorf("查询指标数据出错 error, %v", err)
  121. return
  122. }
  123. existMap := make(map[string]*mgodb.EdbDataBase, len(existList))
  124. deleteMap := make(map[string]struct{}, len(existList))
  125. for _, exist := range existList {
  126. tmp := exist.DataTime.Format(utils.FormatDate)
  127. existMap[tmp] = exist
  128. deleteMap[tmp] = struct{}{}
  129. }
  130. for _, v := range dataList {
  131. dataTime, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  132. if e != nil {
  133. err = fmt.Errorf("时间格式化出错 error, %v", e)
  134. return
  135. }
  136. val, e := strconv.ParseFloat(v.Value, 64)
  137. if e != nil {
  138. err = fmt.Errorf("指标数据格式化出错 error, %v", e)
  139. return
  140. }
  141. if oldObj, ok := existMap[v.DataTime]; !ok {
  142. tmp := &mgodb.EdbDataBase{
  143. EdbInfoId: edbInfoId,
  144. EdbCode: v.EdbCode,
  145. DataTime: dataTime,
  146. Value: val,
  147. Status: v.Status,
  148. CreateTime: v.CreateTime,
  149. ModifyTime: v.ModifyTime,
  150. DataTimestamp: v.DataTimestamp,
  151. }
  152. addList = append(addList, tmp)
  153. if len(addList) >= 500 {
  154. err = mgodb.InsertEdbCalculateDataBatch(addList)
  155. if err != nil {
  156. err = fmt.Errorf("批量新增指标数据失败 error, %v", e)
  157. return
  158. }
  159. addList = make([]interface{}, 0)
  160. }
  161. } else {
  162. delete(deleteMap, v.DataTime)
  163. if val != oldObj.Value {
  164. err = mgodb.ModifyValueEdbCalculateDataValue(oldObj.EdbDataId, val, v.ModifyTime)
  165. if err != nil {
  166. err = fmt.Errorf("更新指标数据出错 error, %v", err)
  167. return
  168. }
  169. }
  170. }
  171. }
  172. //遍历deleteMap,找出需要删除的日期
  173. {
  174. removeDateList := make([]time.Time, 0)
  175. for dateTime := range deleteMap {
  176. dateT, e := time.ParseInLocation(utils.FormatDate, dateTime, time.Local)
  177. if e != nil {
  178. err = fmt.Errorf("日期格式错误 error, %v", e)
  179. return
  180. }
  181. removeDateList = append(removeDateList, dateT)
  182. }
  183. removeNum := len(removeDateList)
  184. if removeNum > 0 {
  185. err = mgodb.DeleteEdbCalculateDataByEdbCodeAndDateList(edbCode, removeDateList)
  186. if err != nil {
  187. err = fmt.Errorf("删除多余日期失败,error, %v", err)
  188. return
  189. }
  190. }
  191. }
  192. if len(addList) > 0 {
  193. err = mgodb.InsertEdbCalculateDataBatch(addList)
  194. }
  195. return
  196. }
  197. // GetEdbDataList 获取指标的数据(日期正序返回)
  198. func GetEdbDataList(endInfoId, edbType int, startDate, endDate string) (list []*models.EdbDataList, err error) {
  199. dataList := make([]*mgodb.EdbDataBase, 0)
  200. var startDateT, endDateT time.Time
  201. if startDate != "" {
  202. startDateT, err = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  203. if err != nil {
  204. err = fmt.Errorf("日期格式错误 error, %v", err)
  205. return
  206. }
  207. }
  208. if endDate != "" {
  209. endDateT, err = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  210. if err != nil {
  211. err = fmt.Errorf("日期格式错误 error, %v", err)
  212. return
  213. }
  214. }
  215. if edbType == 1 {
  216. dataList, err = mgodb.GetEdbDataList(endInfoId, startDateT, endDateT)
  217. if err != nil {
  218. err = fmt.Errorf("查询指标数据出错 error, %v", err)
  219. return
  220. }
  221. } else {
  222. dataList, err = mgodb.GetEdbCalculateDataList(endInfoId, startDateT, endDateT)
  223. if err != nil {
  224. err = fmt.Errorf("查询指标数据出错 error, %v", err)
  225. return
  226. }
  227. }
  228. list = make([]*models.EdbDataList, 0)
  229. for _, v := range dataList {
  230. // 字符串转成浮点数
  231. list = append(list, &models.EdbDataList{
  232. EdbInfoId: v.EdbInfoId,
  233. DataTime: v.DataTime.Format(utils.FormatDate),
  234. DataTimestamp: v.DataTimestamp,
  235. Value: v.Value,
  236. },
  237. )
  238. }
  239. return
  240. }
  241. // TbzDiv 同比值计算
  242. func TbzDiv(a, b float64) float64 {
  243. var valFloat float64
  244. if b != 0 {
  245. af := decimal.NewFromFloat(a)
  246. bf := decimal.NewFromFloat(b)
  247. val, _ := af.Div(bf).Float64()
  248. val = val - 1
  249. valFloat, _ = decimal.NewFromFloat(val).RoundCeil(4).Float64()
  250. } else {
  251. valFloat = 0
  252. }
  253. return valFloat
  254. }
  255. // GetEdbDataTbzForSeason 获取指标的同比值数据
  256. func GetEdbDataTbzForSeason(frequency string, tmpDataList []*models.EdbDataList, startDateTime time.Time) (dataList []*models.EdbDataList, minValue, maxValue float64, err error) {
  257. dataList = make([]*models.EdbDataList, 0)
  258. // 数据处理
  259. var dateArr []string
  260. dataMap := make(map[string]*models.EdbDataList)
  261. for _, v := range tmpDataList {
  262. dateArr = append(dateArr, v.DataTime)
  263. dataMap[v.DataTime] = v
  264. }
  265. for _, av := range dateArr {
  266. currentItem, ok := dataMap[av]
  267. // 如果找不到当前日期的数据,那么终止当前循环,进入下一循环
  268. if !ok {
  269. continue
  270. }
  271. tmpItem := *currentItem
  272. var isOk bool //是否计算出来结果
  273. //当前日期
  274. currentDate, tmpErr := time.ParseInLocation(utils.FormatDate, av, time.Local)
  275. if tmpErr != nil {
  276. err = tmpErr
  277. return
  278. }
  279. // 如果存在开始日期,同时,当前日期早于开始日期,那么终止当前循环,进入下一循环
  280. if !startDateTime.IsZero() && currentDate.Before(startDateTime) {
  281. continue
  282. }
  283. //上一年的日期
  284. preDate := currentDate.AddDate(-1, 0, 0)
  285. preDateStr := preDate.Format(utils.FormatDate)
  286. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
  287. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  288. isOk = true
  289. } else {
  290. if frequency == "月度" { //向上和向下,各找一个月
  291. for i := 0; i <= 35; i++ {
  292. nextDateDay := preDate.AddDate(0, 0, i)
  293. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  294. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  295. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  296. isOk = true
  297. break
  298. } else {
  299. preDateDay := preDate.AddDate(0, 0, -i)
  300. preDateDayStr := preDateDay.Format(utils.FormatDate)
  301. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  302. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  303. isOk = true
  304. break
  305. }
  306. }
  307. }
  308. } else if frequency == "季度" || frequency == "年度" {
  309. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
  310. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  311. isOk = true
  312. break
  313. }
  314. } else {
  315. nextDateDay := preDate.AddDate(0, 0, 1)
  316. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  317. preDateDay := preDate.AddDate(0, 0, -1)
  318. preDateDayStr := preDateDay.Format(utils.FormatDate)
  319. for i := 0; i < 35; i++ {
  320. if i >= 1 {
  321. nextDateDay = nextDateDay.AddDate(0, 0, i)
  322. nextDateDayStr = nextDateDay.Format(utils.FormatDate)
  323. }
  324. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  325. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  326. isOk = true
  327. break
  328. } else {
  329. if i >= 1 {
  330. preDateDay = preDate.AddDate(0, 0, -i)
  331. preDateDayStr = nextDateDay.Format(utils.FormatDate)
  332. }
  333. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  334. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  335. isOk = true
  336. break
  337. }
  338. }
  339. }
  340. }
  341. }
  342. if isOk {
  343. if tmpItem.Value > maxValue {
  344. maxValue = tmpItem.Value
  345. }
  346. if tmpItem.Value < minValue {
  347. minValue = tmpItem.Value
  348. }
  349. dataList = append(dataList, &tmpItem)
  350. }
  351. }
  352. return
  353. }
  354. // AddOrUpdateEdbDataWithOpType 根据操作类型,更新指标数据
  355. func AddOrUpdateEdbDataWithOpType(edbInfoId int, dataList []*models.EdbDataBaseWithOpType, minDataTime string, maxDataTime string) (err error) {
  356. // 指标数据为空则不更新
  357. if len(dataList) == 0 {
  358. return
  359. }
  360. addList := make([]interface{}, 0)
  361. minDataTimeT, err := time.ParseInLocation(utils.FormatDate, minDataTime, time.Local)
  362. if err != nil {
  363. err = fmt.Errorf("日期格式错误 error, %v", err)
  364. return
  365. }
  366. maxDataTimeT, err := time.ParseInLocation(utils.FormatDate, maxDataTime, time.Local)
  367. if err != nil {
  368. err = fmt.Errorf("日期格式错误 error, %v", err)
  369. return
  370. }
  371. existList, err := mgodb.GetEdbDataList(edbInfoId, minDataTimeT, maxDataTimeT)
  372. if err != nil {
  373. err = fmt.Errorf("查询指标数据出错 error, %v", err)
  374. return
  375. }
  376. existMap := make(map[string]*mgodb.EdbDataBase, len(existList))
  377. removeDateList := make([]time.Time, 0)
  378. for _, exist := range existList {
  379. tmp := exist.DataTime.Format(utils.FormatDate)
  380. existMap[tmp] = exist
  381. }
  382. for _, v := range dataList {
  383. dataTime, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  384. if e != nil {
  385. err = fmt.Errorf("时间格式化出错 error, %v", e)
  386. return
  387. }
  388. val, e := strconv.ParseFloat(v.Value, 64)
  389. if e != nil {
  390. err = fmt.Errorf("指标数据格式化出错 error, %v", e)
  391. return
  392. }
  393. if oldObj, ok := existMap[v.DataTime]; !ok {
  394. if v.OpType == "insert" || v.OpType == "update" {
  395. tmp := &mgodb.EdbDataBase{
  396. EdbInfoId: v.EdbInfoId,
  397. EdbCode: v.EdbCode,
  398. DataTime: dataTime,
  399. Value: val,
  400. Status: v.Status,
  401. CreateTime: v.CreateTime,
  402. ModifyTime: v.ModifyTime,
  403. DataTimestamp: v.DataTimestamp,
  404. }
  405. addList = append(addList, tmp)
  406. if len(addList) >500 {
  407. err = mgodb.InsertEdbDataBatch(addList)
  408. if err != nil {
  409. err = fmt.Errorf("批量新增指标数据失败 error, %v", e)
  410. return
  411. }
  412. addList = make([]interface{}, 0)
  413. continue
  414. }
  415. }
  416. } else {
  417. if v.OpType != "delete" {
  418. if v.ModifyTime.After(oldObj.ModifyTime) {
  419. err = mgodb.ModifyValueEdbDataValue(oldObj.EdbDataId, val, v.ModifyTime)
  420. if err != nil {
  421. err = fmt.Errorf("更新指标数据出错 error, %v", err)
  422. return
  423. }
  424. }
  425. }else if v.OpType == "delete" {
  426. removeDateList = append(removeDateList, dataTime)
  427. // 删除数据
  428. // err = mgodb.DeleteEdbInfoDataByEdbInfoIdAndDate(v.EdbCode, v.DataTime)
  429. // if err != nil {
  430. // err = fmt.Errorf("删除指标数据出错 error, %v", err)
  431. // return
  432. }
  433. }
  434. }
  435. //遍历deletemap,找出需要删除的日期
  436. removeNum := len(removeDateList)
  437. if removeNum > 0 {
  438. err = mgodb.DeleteEdbInfoDataByEdbInfoIdAndDateList(edbInfoId, removeDateList)
  439. if err != nil {
  440. err = fmt.Errorf("删除多余日期失败,error, %v", err)
  441. return
  442. }
  443. }
  444. if len(addList) > 0 {
  445. err = mgodb.InsertEdbDataBatch(addList)
  446. }
  447. return
  448. }
  449. func AddOrUpdateEdbDataCalculateWithOpType(edbInfoId int, dataList []*models.EdbDataBaseWithOpType, minDataTime string, maxDataTime string) (err error) {
  450. // 指标数据为空则不更新
  451. if len(dataList) == 0 {
  452. return
  453. }
  454. addList := make([]interface{}, 0)
  455. minDataTimeT, err := time.ParseInLocation(utils.FormatDate, minDataTime, time.Local)
  456. if err != nil {
  457. err = fmt.Errorf("日期格式错误 error, %v", err)
  458. return
  459. }
  460. maxDataTimeT, err := time.ParseInLocation(utils.FormatDate, maxDataTime, time.Local)
  461. if err != nil {
  462. err = fmt.Errorf("日期格式错误 error, %v", err)
  463. return
  464. }
  465. existList, err := mgodb.GetEdbCalculateDataList(edbInfoId, minDataTimeT, maxDataTimeT)
  466. if err != nil {
  467. err = fmt.Errorf("查询指标数据出错 error, %v", err)
  468. return
  469. }
  470. existMap := make(map[string]*mgodb.EdbDataBase, len(existList))
  471. removeDateList := make([]time.Time, 0)
  472. for _, exist := range existList {
  473. tmp := exist.DataTime.Format(utils.FormatDate)
  474. existMap[tmp] = exist
  475. }
  476. for _, v := range dataList {
  477. dataTime, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  478. if e != nil {
  479. err = fmt.Errorf("时间格式化出错 error, %v", e)
  480. return
  481. }
  482. val, e := strconv.ParseFloat(v.Value, 64)
  483. if e != nil {
  484. err = fmt.Errorf("指标数据格式化出错 error, %v", e)
  485. return
  486. }
  487. if oldObj, ok := existMap[v.DataTime]; !ok {
  488. if v.OpType == "insert" || v.OpType == "update" {
  489. tmp := &mgodb.EdbDataBase{
  490. EdbInfoId: v.EdbInfoId,
  491. EdbCode: v.EdbCode,
  492. DataTime: dataTime,
  493. Value: val,
  494. Status: v.Status,
  495. CreateTime: v.CreateTime,
  496. ModifyTime: v.ModifyTime,
  497. DataTimestamp: v.DataTimestamp,
  498. }
  499. addList = append(addList, tmp)
  500. if len(addList) >500 {
  501. err = mgodb.InsertEdbCalculateDataBatch(addList)
  502. if err != nil {
  503. err = fmt.Errorf("批量新增指标数据失败 error, %v", e)
  504. return
  505. }
  506. addList = make([]interface{}, 0)
  507. continue
  508. }
  509. }
  510. } else {
  511. if v.OpType != "delete" {
  512. if v.ModifyTime.After(oldObj.ModifyTime) {
  513. err = mgodb.ModifyValueEdbCalculateDataValue(oldObj.EdbDataId, val, v.ModifyTime)
  514. if err != nil {
  515. err = fmt.Errorf("更新指标数据出错 error, %v", err)
  516. return
  517. }
  518. }
  519. } else if v.OpType == "delete" {
  520. removeDateList = append(removeDateList, dataTime)
  521. }
  522. }
  523. }
  524. //遍历deleteMap,找出需要删除的日期
  525. removeNum := len(removeDateList)
  526. if removeNum > 0 {
  527. err = mgodb.DeleteEdbCalculateDataByEdbInfoIdAndDateList(edbInfoId, removeDateList)
  528. if err != nil {
  529. err = fmt.Errorf("删除多余日期失败,error, %v", err)
  530. return
  531. }
  532. }
  533. if len(addList) > 0 {
  534. err = mgodb.InsertEdbCalculateDataBatch(addList)
  535. }
  536. return
  537. }