edb_info.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. package services
  2. import (
  3. "errors"
  4. "eta/eta_forum_hub/models"
  5. "eta/eta_forum_hub/models/mgodb"
  6. "eta/eta_forum_hub/services/elastic"
  7. "eta/eta_forum_hub/utils"
  8. "fmt"
  9. "github.com/shopspring/decimal"
  10. "math"
  11. "sort"
  12. "strconv"
  13. "time"
  14. )
  15. // BatchAddOrUpdateEdbInfo 添加批量添加指标到指标库
  16. func BatchAddOrUpdateEdbInfo(edbList []*models.EdbInfo, edbMapping []*models.EdbInfoCalculateMapping, sysUserId int, sysUserRealName string) (newList []*models.EdbInfo, err error, errMsg string, isSendEmail bool) {
  17. isSendEmail = true
  18. edbCodeMap := make(map[string]*models.EdbInfo)
  19. for _, v := range edbList {
  20. tmp, e, msg, _ := AddOrUpdateEdbInfo(v, sysUserId, sysUserRealName)
  21. if e != nil {
  22. err = fmt.Errorf("添加指标失败:%s,%s", e.Error(), msg)
  23. errMsg = "添加指标失败"
  24. return
  25. }
  26. newList = append(newList, tmp)
  27. edbCodeMap[tmp.EdbCode] = tmp
  28. }
  29. //批量添加指标的mapping信息
  30. calculateMappingItemList := make([]*models.EdbInfoCalculateMapping, 0)
  31. for _, v := range edbMapping {
  32. edbInfo, ok := edbCodeMap[v.EdbCode]
  33. if !ok {
  34. continue
  35. }
  36. fromEdbInfo, ok := edbCodeMap[v.FromEdbCode]
  37. if !ok {
  38. continue
  39. }
  40. calculateMappingItem := new(models.EdbInfoCalculateMapping)
  41. calculateMappingItem.CreateTime = time.Now()
  42. calculateMappingItem.ModifyTime = time.Now()
  43. calculateMappingItem.Sort = v.Sort
  44. calculateMappingItem.EdbCode = edbInfo.EdbCode
  45. calculateMappingItem.EdbInfoId = edbInfo.EdbInfoId
  46. calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
  47. calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
  48. calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
  49. calculateMappingItem.FromSource = fromEdbInfo.Source
  50. calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
  51. calculateMappingItem.FromTag = v.FromTag
  52. calculateMappingItem.Source = edbInfo.Source
  53. calculateMappingItem.SourceName = edbInfo.SourceName
  54. calculateMappingItem.FromSubSource = edbInfo.SubSource
  55. calculateMappingItemList = append(calculateMappingItemList, calculateMappingItem)
  56. }
  57. if len(calculateMappingItemList) > 0 {
  58. err = models.AddEdbInfoCalculateMappingMulti(calculateMappingItemList)
  59. if err != nil {
  60. errMsg = "指标映射关系添加失败"
  61. err = fmt.Errorf("指标映射关系添加失败, %s", err.Error())
  62. return
  63. }
  64. }
  65. return
  66. }
  67. // AddOrUpdateEdbInfo 添加指标到指标库
  68. func AddOrUpdateEdbInfo(edbItem *models.EdbInfo, sysUserId int, sysUserRealName string) (edbInfo *models.EdbInfo, err error, errMsg string, isSendEmail bool) {
  69. isSendEmail = true
  70. //判断指标是否存在
  71. //edbInfo, err = models.GetEdbInfoByEdbCode(edbItem.EdbCode)
  72. edbInfo, err = models.GetEdbInfoById(edbItem.EdbInfoId)
  73. if err != nil {
  74. if err.Error() == utils.ErrNoRow() {
  75. err = nil
  76. } else {
  77. errMsg = "判断指标名称是否存在失败"
  78. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  79. return
  80. }
  81. }
  82. var edbInfoId int64
  83. // 指标已存在
  84. if edbInfo != nil && edbInfo.EdbInfoId > 0 {
  85. edbInfoId = int64(edbInfo.EdbInfoId)
  86. // 更新指标信息
  87. edbInfo.Source = edbItem.Source
  88. edbInfo.SourceName = edbItem.SourceName
  89. edbInfo.EdbType = edbItem.EdbType
  90. edbInfo.EdbCode = edbItem.EdbCode
  91. edbInfo.EdbName = edbItem.EdbName
  92. edbInfo.EdbNameSource = edbItem.EdbNameSource
  93. edbInfo.Frequency = edbItem.Frequency
  94. edbInfo.Unit = edbItem.Unit
  95. edbInfo.StartDate = edbItem.StartDate
  96. edbInfo.EndDate = edbItem.EndDate
  97. edbInfo.ClassifyId = edbItem.ClassifyId
  98. edbInfo.SysUserId = sysUserId
  99. edbInfo.SysUserRealName = sysUserRealName
  100. edbInfo.ModifyTime = time.Now()
  101. edbInfo.ServerUrl = edbItem.ServerUrl
  102. edbInfo.Sort = edbItem.Sort
  103. edbInfo.DataDateType = edbItem.DataDateType
  104. edbInfo.TerminalCode = edbItem.TerminalCode
  105. edbInfo.SourceIndexName = edbItem.SourceIndexName
  106. edbInfo.MaxValue = edbItem.MaxValue
  107. edbInfo.MinValue = edbItem.MinValue
  108. edbInfo.EdbInfoType = edbItem.EdbInfoType
  109. edbInfo.LatestDate = edbItem.LatestDate
  110. edbInfo.LatestValue = edbItem.LatestValue
  111. edbInfo.CalculateFormula = edbItem.CalculateFormula
  112. edbInfo.ManualSave = edbItem.ManualSave
  113. edbInfo.MoveType = edbItem.MoveType
  114. edbInfo.MoveFrequency = edbItem.MoveFrequency
  115. edbInfo.NoUpdate = edbItem.NoUpdate
  116. edbInfo.EdbNameEn = edbItem.EdbNameEn
  117. edbInfo.UnitEn = edbItem.UnitEn
  118. edbInfo.ChartImage = edbItem.ChartImage
  119. edbInfo.Calendar = edbItem.Calendar
  120. edbInfo.EmptyType = edbItem.EmptyType
  121. edbInfo.MaxEmptyType = edbItem.MaxEmptyType
  122. edbInfo.DataUpdateTime = edbItem.DataUpdateTime
  123. edbInfo.ErDataUpdateDate = edbItem.ErDataUpdateDate
  124. edbInfo.EndValue = edbItem.EndValue
  125. edbInfo.SubSource = edbItem.SubSource
  126. edbInfo.SubSourceName = edbItem.SubSourceName
  127. edbInfo.IndicatorCode = edbItem.IndicatorCode
  128. edbInfo.StockCode = edbItem.StockCode
  129. edbInfo.Extra = edbItem.Extra
  130. err = edbInfo.Update([]string{})
  131. if err != nil {
  132. errMsg = "保存失败"
  133. err = errors.New("保存失败,Err:" + err.Error())
  134. return
  135. }
  136. //同时删除指标的映射信息
  137. err = models.DeleteEdbInfoMapping(edbInfoId)
  138. if err != nil {
  139. errMsg = "删除指标映射信息失败"
  140. err = errors.New("删除指标映射信息失败,Err:" + err.Error())
  141. return
  142. }
  143. } else {
  144. edbInfo = new(models.EdbInfo)
  145. edbInfo.EdbInfoId = edbItem.EdbInfoId
  146. edbInfo.Source = edbItem.Source
  147. edbInfo.SourceName = edbItem.SourceName
  148. edbInfo.EdbType = edbItem.EdbType
  149. edbInfo.EdbCode = edbItem.EdbCode
  150. edbInfo.EdbName = edbItem.EdbName
  151. edbInfo.EdbNameSource = edbItem.EdbNameSource
  152. edbInfo.Frequency = edbItem.Frequency
  153. edbInfo.Unit = edbItem.Unit
  154. edbInfo.StartDate = edbItem.StartDate
  155. edbInfo.EndDate = edbItem.EndDate
  156. edbInfo.ClassifyId = edbItem.ClassifyId
  157. edbInfo.SysUserId = sysUserId
  158. edbInfo.SysUserRealName = sysUserRealName
  159. edbInfo.CreateTime = time.Now()
  160. edbInfo.ModifyTime = time.Now()
  161. edbInfo.ServerUrl = edbItem.ServerUrl
  162. edbInfo.Sort = edbItem.Sort
  163. edbInfo.DataDateType = edbItem.DataDateType
  164. edbInfo.TerminalCode = edbItem.TerminalCode
  165. edbInfo.SourceIndexName = edbItem.SourceIndexName
  166. //timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  167. //edbInfo.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
  168. edbInfo.UniqueCode = edbItem.UniqueCode
  169. edbInfo.MaxValue = edbItem.MaxValue
  170. edbInfo.MinValue = edbItem.MinValue
  171. edbInfo.EdbInfoType = edbItem.EdbInfoType
  172. edbInfo.LatestDate = edbItem.LatestDate
  173. edbInfo.LatestValue = edbItem.LatestValue
  174. edbInfo.CalculateFormula = edbItem.CalculateFormula
  175. edbInfo.ManualSave = edbItem.ManualSave
  176. edbInfo.MoveType = edbItem.MoveType
  177. edbInfo.MoveFrequency = edbItem.MoveFrequency
  178. edbInfo.NoUpdate = edbItem.NoUpdate
  179. edbInfo.EdbNameEn = edbItem.EdbNameEn
  180. edbInfo.UnitEn = edbItem.UnitEn
  181. edbInfo.ChartImage = edbItem.ChartImage
  182. edbInfo.Calendar = edbItem.Calendar
  183. edbInfo.EmptyType = edbItem.EmptyType
  184. edbInfo.MaxEmptyType = edbItem.MaxEmptyType
  185. edbInfo.DataUpdateTime = edbItem.DataUpdateTime
  186. edbInfo.ErDataUpdateDate = edbItem.ErDataUpdateDate
  187. edbInfo.EndValue = edbItem.EndValue
  188. edbInfo.SubSource = edbItem.SubSource
  189. edbInfo.SubSourceName = edbItem.SubSourceName
  190. edbInfo.IndicatorCode = edbItem.IndicatorCode
  191. edbInfo.StockCode = edbItem.StockCode
  192. edbInfo.Extra = edbItem.Extra
  193. edbInfoId, err = models.AddEdbInfo(edbInfo)
  194. if err != nil {
  195. errMsg = "保存失败"
  196. err = errors.New("保存失败,Err:" + err.Error())
  197. return
  198. }
  199. edbInfo.EdbInfoId = int(edbInfoId)
  200. }
  201. // if edbInfo.EdbType == 1 {
  202. // err = mgodb.ModifyEdbDataEdbInfoId(edbInfoId, edbInfo.EdbCode)
  203. // if err != nil {
  204. // errMsg = "保存失败"
  205. // err = errors.New("更新指标数据失败,Err:" + err.Error())
  206. // return
  207. // }
  208. // } else {
  209. // err = mgodb.ModifyEdbCalculateDataEdbInfoId(edbInfoId, edbInfo.EdbCode)
  210. // if err != nil {
  211. // errMsg = "保存失败"
  212. // err = errors.New("更新指标数据失败,Err:" + err.Error())
  213. // return
  214. // }
  215. // }
  216. // 更新es
  217. go AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
  218. return
  219. }
  220. // 批量删除指标,
  221. func BatchDeleteEdbInfo(edbInfoIds []int) (err error, errMsg string) {
  222. for _, v := range edbInfoIds {
  223. //查询单个指标是否允许删除
  224. err, errMsg = DeleteEdbInfo(v)
  225. if err != nil {
  226. errMsg = "删除指标失败"
  227. return
  228. }
  229. }
  230. return
  231. }
  232. // 删除单个指标
  233. func DeleteEdbInfo(edbInfoId int) (err error, errMsg string) {
  234. defer func() {
  235. if err != nil {
  236. utils.FileLog.Error("删除指标失败,Err:" + err.Error(), "edbInfoId", edbInfoId)
  237. }
  238. if errMsg != "" {
  239. utils.FileLog.Error("删除指标失败,ErrMsg:" + errMsg, "edbInfoId", edbInfoId)
  240. }
  241. }()
  242. //判断指标是否存在
  243. info, err := models.GetEdbInfoById(edbInfoId)
  244. if err != nil {
  245. if err.Error() == utils.ErrNoRow() {
  246. err = nil
  247. return
  248. } else {
  249. errMsg = "判断指标名称是否存在失败"
  250. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  251. return
  252. }
  253. }
  254. //判断指标是否用于作图,如果用于作图,则不可删除
  255. chartCount, tmpErr := models.GetChartEdbMappingCount(edbInfoId)
  256. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  257. errMsg = "删除失败"
  258. err = errors.New("判断指标是否被用于作图失败,Err:" + tmpErr.Error())
  259. return
  260. }
  261. if chartCount > 0 {
  262. errMsg = "当前指标已用作画图,不可删除"
  263. return
  264. }
  265. //判断指标是否用作其他指标的计算
  266. calculateCount, tmpErr := models.GetEdbInfoCalculateMappingCount(edbInfoId)
  267. if tmpErr != nil {
  268. errMsg = "删除失败"
  269. err = errors.New("判断指标是否被用于计算失败,GetEdbInfoCalculateCount Err:" + tmpErr.Error())
  270. return
  271. }
  272. if calculateCount > 0 {
  273. errMsg = "当前指标已用作,指标运算,不可删除"
  274. return
  275. }
  276. // 删除指标,删除映射关系,删除指标数据
  277. err = models.DeleteEdbInfo(edbInfoId)
  278. if err != nil {
  279. errMsg = "删除失败"
  280. err = errors.New("删除指标失败,Err:" + err.Error())
  281. return
  282. }
  283. if info.EdbType == 1 {
  284. err = mgodb.DeleteEdbInfoDataByEdbInfoId(edbInfoId)
  285. if err != nil {
  286. errMsg = "删除失败"
  287. err = errors.New("删除指标数据失败,Err:" + err.Error())
  288. return
  289. }
  290. } else {
  291. err = mgodb.DeleteEdbInfoCalculateDataByEdbInfoId(edbInfoId)
  292. if err != nil {
  293. errMsg = "删除失败"
  294. err = errors.New("删除指标数据失败,Err:" + err.Error())
  295. return
  296. }
  297. }
  298. // 删除es中的数据
  299. go DeleteEdbInfoToEs(edbInfoId)
  300. return
  301. }
  302. // AddOrEditEdbInfoToEs 添加/修改ES中的指标
  303. func AddOrEditEdbInfoToEs(edbInfoId int) {
  304. //添加es
  305. itemInfo, _ := models.GetEdbInfoByCondition("AND edb_info_id=?", []interface{}{edbInfoId})
  306. go elastic.EsAddOrEditEdbInfoData(utils.DATA_INDEX_NAME, strconv.Itoa(itemInfo.EdbInfoId), itemInfo)
  307. }
  308. // 获取频度的英文版
  309. func GetFrequencyEn(frequency string) (frequencyEn string) {
  310. switch frequency {
  311. case "日度":
  312. frequencyEn = "day"
  313. return
  314. case "周度":
  315. frequencyEn = "week"
  316. return
  317. case "旬度":
  318. frequencyEn = "ten days"
  319. return
  320. case "月度":
  321. frequencyEn = "month"
  322. return
  323. case "季度":
  324. frequencyEn = "quarter"
  325. return
  326. case "年度":
  327. frequencyEn = "year"
  328. return
  329. }
  330. return
  331. }
  332. func GetLeadUnitEn(unit string) (unitEn string) {
  333. switch unit {
  334. case "天":
  335. unitEn = "day"
  336. return
  337. case "周":
  338. unitEn = "week"
  339. return
  340. case "月":
  341. unitEn = "month"
  342. return
  343. case "季":
  344. unitEn = "quarter"
  345. return
  346. case "年":
  347. unitEn = "year"
  348. return
  349. }
  350. return
  351. }
  352. // HandleDataByLinearRegressionToList 插值法补充数据(线性方程式)
  353. func HandleDataByLinearRegressionToList(edbInfoDataList []*models.EdbDataList, handleDataMap map[string]float64) (dataTimeList []string, valueList []float64, err error) {
  354. if len(edbInfoDataList) < 2 {
  355. return
  356. }
  357. var startEdbInfoData *models.EdbDataList
  358. for _, v := range edbInfoDataList {
  359. handleDataMap[v.DataTime] = v.Value
  360. dataTimeList = append(dataTimeList, v.DataTime)
  361. // 第一个数据就给过滤了,给后面的试用
  362. if startEdbInfoData == nil {
  363. startEdbInfoData = v
  364. //startEdbInfoData.DataTime = startEdbInfoData.DataTime[:5]+ "01-01"
  365. continue
  366. }
  367. // 获取两条数据之间相差的天数
  368. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  369. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  370. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  371. betweenDay := betweenHour / 24
  372. // 如果相差一天,那么过滤
  373. if betweenDay <= 1 {
  374. startEdbInfoData = v
  375. continue
  376. }
  377. // 生成线性方程式
  378. var a, b float64
  379. {
  380. coordinateData := make([]utils.Coordinate, 0)
  381. tmpCoordinate1 := utils.Coordinate{
  382. X: 1,
  383. Y: startEdbInfoData.Value,
  384. }
  385. coordinateData = append(coordinateData, tmpCoordinate1)
  386. tmpCoordinate2 := utils.Coordinate{
  387. X: float64(betweenDay) + 1,
  388. Y: v.Value,
  389. }
  390. coordinateData = append(coordinateData, tmpCoordinate2)
  391. a, b = utils.GetLinearResult(coordinateData)
  392. if math.IsNaN(a) || math.IsNaN(b) {
  393. err = errors.New("线性方程公式生成失败")
  394. return
  395. }
  396. }
  397. // 生成对应的值
  398. {
  399. for i := 1; i < betweenDay; i++ {
  400. tmpDataTime := startDataTime.AddDate(0, 0, i)
  401. aDecimal := decimal.NewFromFloat(a)
  402. xDecimal := decimal.NewFromInt(int64(i) + 1)
  403. bDecimal := decimal.NewFromFloat(b)
  404. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  405. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  406. dataTimeList = append(dataTimeList, tmpDataTime.Format(utils.FormatDate))
  407. valueList = append(valueList, val)
  408. }
  409. }
  410. startEdbInfoData = v
  411. }
  412. return
  413. }
  414. // HandleDataByLinearRegressionToList 保证生成365个数据点的线性插值法
  415. func HandleDataByLinearRegressionToListV2(edbInfoDataList []*models.EdbDataList, handleDataMap map[string]float64) (dataTimeList []string, valueList []float64, err error) {
  416. if len(edbInfoDataList) < 2 {
  417. return
  418. }
  419. // 确保至少有两天数据来生成线性方程
  420. if len(edbInfoDataList) < 2 {
  421. err = errors.New("至少需要两天的数据来执行线性插值")
  422. return
  423. }
  424. // 对数据按日期排序,确保顺序正确
  425. sort.Slice(edbInfoDataList, func(i, j int) bool {
  426. t1, _ := time.ParseInLocation(utils.FormatDate, edbInfoDataList[i].DataTime, time.Local)
  427. t2, _ := time.ParseInLocation(utils.FormatDate, edbInfoDataList[j].DataTime, time.Local)
  428. return t1.Before(t2)
  429. })
  430. startEdbInfoData := edbInfoDataList[0]
  431. endEdbInfoData := edbInfoDataList[len(edbInfoDataList)-1]
  432. // 计算起始和结束日期间实际的天数
  433. startDate, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  434. endDate, _ := time.ParseInLocation(utils.FormatDate, endEdbInfoData.DataTime, time.Local)
  435. actualDays := endDate.Sub(startDate).Hours() / 24
  436. // 生成365个数据点,首先处理已有数据
  437. for _, v := range edbInfoDataList {
  438. handleDataMap[v.DataTime] = v.Value
  439. dataTimeList = append(dataTimeList, v.DataTime)
  440. valueList = append(valueList, v.Value)
  441. }
  442. // 如果已有数据跨越天数不足365天,则对缺失的日期进行线性插值
  443. if actualDays < 365 {
  444. // 使用已有数据点生成线性方程(这里简化处理,实际可能需更细致处理边界情况)
  445. var a, b float64
  446. coordinateData := []utils.Coordinate{
  447. {X: 1, Y: startEdbInfoData.Value},
  448. {X: float64(len(edbInfoDataList)), Y: endEdbInfoData.Value},
  449. }
  450. a, b = utils.GetLinearResult(coordinateData)
  451. if math.IsNaN(a) || math.IsNaN(b) {
  452. err = errors.New("线性方程公式生成失败")
  453. return
  454. }
  455. // 对剩余日期进行插值
  456. for i := 1; i < 365; i++ {
  457. day := startDate.AddDate(0, 0, i)
  458. if _, exists := handleDataMap[day.Format(utils.FormatDate)]; !exists {
  459. aDecimal := decimal.NewFromFloat(a)
  460. xDecimal := decimal.NewFromInt(int64(i) + 1)
  461. bDecimal := decimal.NewFromFloat(b)
  462. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  463. handleDataMap[day.Format(utils.FormatDate)] = val
  464. dataTimeList = append(dataTimeList, day.Format(utils.FormatDate))
  465. valueList = append(valueList, val)
  466. }
  467. }
  468. }
  469. return
  470. }
  471. func GetRefreshEdbInfoFromBase(edbInfoId, source int) (baseEdbInfoArr, calculateInfoArr []*models.EdbInfo, err error) {
  472. calculateList, err := models.GetEdbInfoCalculateMap(edbInfoId, source)
  473. if err != nil && err.Error() != utils.ErrNoRow() {
  474. return
  475. }
  476. for _, item := range calculateList {
  477. if item.EdbInfoId == edbInfoId { // 如果查出来关联的指标就是自己的话,那么就过滤
  478. continue
  479. }
  480. if item.EdbType == 1 {
  481. baseEdbInfoArr = append(baseEdbInfoArr, item)
  482. } else {
  483. calculateInfoArr = append(calculateInfoArr, item)
  484. newBaseEdbInfoArr, newCalculateInfoArr, _ := GetRefreshEdbInfoFromBase(item.EdbInfoId, item.Source)
  485. baseEdbInfoArr = append(baseEdbInfoArr, newBaseEdbInfoArr...)
  486. calculateInfoArr = append(calculateInfoArr, newCalculateInfoArr...)
  487. }
  488. }
  489. return
  490. }