edb_data_calculate_ljz.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. package models
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta_gn/eta_index_lib/global"
  6. "eta_gn/eta_index_lib/utils"
  7. "fmt"
  8. "github.com/shopspring/decimal"
  9. "gorm.io/gorm"
  10. "reflect"
  11. "strconv"
  12. "strings"
  13. "time"
  14. )
  15. // Ljz 累计值
  16. type Ljz struct {
  17. }
  18. // Add 添加
  19. func (obj Ljz) Add(params AddCalculateBatchParams) (edbInfo *EdbInfo, err error, errMsg string) {
  20. req := params.Req
  21. fromEdbInfo := params.FromEdbInfo
  22. edbCode := params.EdbCode
  23. frequencyInt := utils.CheckFrequency(fromEdbInfo.Frequency, req.Frequency)
  24. if frequencyInt < 0 {
  25. errMsg = "频度异常,不允许低频转为高频"
  26. err = errors.New(errMsg)
  27. return
  28. }
  29. if frequencyInt == 0 {
  30. errMsg = "频度异常,不允许同频计算累计值"
  31. err = errors.New(errMsg)
  32. return
  33. }
  34. to := global.DEFAULT_DmSQL.Begin()
  35. defer func() {
  36. if err != nil {
  37. to.Rollback()
  38. } else {
  39. to.Commit()
  40. }
  41. }()
  42. edbInfo = &EdbInfo{
  43. //EdbInfoId: 0,
  44. SourceName: obj.GetSourceName(),
  45. Source: obj.GetSource(),
  46. EdbCode: edbCode,
  47. EdbName: req.EdbName,
  48. EdbNameSource: req.EdbName,
  49. Frequency: req.Frequency,
  50. Unit: req.Unit,
  51. StartDate: "",
  52. EndDate: "",
  53. ClassifyId: req.ClassifyId,
  54. SysUserId: params.SysUserId,
  55. SysUserRealName: params.SysUserRealName,
  56. UniqueCode: params.UniqueCode,
  57. CreateTime: time.Now(),
  58. ModifyTime: time.Now(),
  59. MinValue: 0,
  60. MaxValue: 0,
  61. CalculateFormula: req.Formula,
  62. EdbType: obj.GetEdbType(),
  63. Sort: GetAddEdbMaxSortByClassifyId(req.ClassifyId, utils.EDB_INFO_TYPE),
  64. MoveType: 0,
  65. MoveFrequency: "",
  66. NoUpdate: 0,
  67. ServerUrl: "",
  68. EdbInfoType: 0,
  69. EdbNameEn: req.EdbName,
  70. UnitEn: req.Unit,
  71. LatestDate: "",
  72. LatestValue: 0,
  73. ChartImage: "",
  74. Calendar: "",
  75. Extra: req.Extra,
  76. }
  77. tmpErr := to.Create(edbInfo).Error
  78. if tmpErr != nil {
  79. err = tmpErr
  80. return
  81. }
  82. //关联关系
  83. {
  84. calculateMappingItem := new(EdbInfoCalculateMapping)
  85. calculateMappingItem.CreateTime = time.Now()
  86. calculateMappingItem.ModifyTime = time.Now()
  87. calculateMappingItem.Sort = 1
  88. calculateMappingItem.EdbCode = edbCode
  89. calculateMappingItem.EdbInfoId = edbInfo.EdbInfoId
  90. calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
  91. calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
  92. calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
  93. calculateMappingItem.FromSource = fromEdbInfo.Source
  94. calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
  95. calculateMappingItem.FromTag = ""
  96. calculateMappingItem.Source = edbInfo.Source
  97. calculateMappingItem.SourceName = edbInfo.SourceName
  98. calculateMappingItem.FromSubSource = fromEdbInfo.SubSource
  99. err = to.Create(calculateMappingItem).Error
  100. if err != nil {
  101. return
  102. }
  103. }
  104. //计算数据
  105. err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "", edbInfo.Extra)
  106. return
  107. }
  108. // Edit 编辑
  109. func (obj Ljz) Edit(params EditCalculateBatchParams) (err error, errMsg string) {
  110. req := params.Req
  111. edbInfo := params.EdbInfo
  112. fromEdbInfo := params.FromEdbInfo
  113. frequencyInt := utils.CheckFrequency(fromEdbInfo.Frequency, req.Frequency)
  114. if frequencyInt < 0 {
  115. errMsg = "频度异常,不允许低频转为高频"
  116. err = errors.New(errMsg)
  117. return
  118. }
  119. if frequencyInt == 0 {
  120. errMsg = "频度异常,不允许同频计算累计值"
  121. err = errors.New(errMsg)
  122. return
  123. }
  124. to := global.DEFAULT_DmSQL.Begin()
  125. defer func() {
  126. if err != nil {
  127. to.Rollback()
  128. } else {
  129. to.Commit()
  130. }
  131. }()
  132. tableName := GetEdbDataTableName(edbInfo.Source, edbInfo.SubSource)
  133. var isRecalculate bool
  134. if edbInfo.Frequency != req.Frequency || edbInfo.Extra != req.Extra {
  135. isRecalculate = true
  136. }
  137. //修改指标信息
  138. edbInfo.EdbName = req.EdbName
  139. edbInfo.EdbNameSource = req.EdbName
  140. edbInfo.Frequency = req.Frequency
  141. edbInfo.Unit = req.Unit
  142. edbInfo.ClassifyId = req.ClassifyId
  143. edbInfo.Extra = req.Extra
  144. edbInfo.EdbNameEn = req.EdbNameEn
  145. edbInfo.UnitEn = req.UnitEn
  146. edbInfo.ModifyTime = time.Now()
  147. err = to.Model(edbInfo).Select([]string{"EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "ModifyTime", "Extra", "EdbNameEn", "UnitEn"}).Updates(edbInfo).Error
  148. if err != nil {
  149. return
  150. }
  151. var existCondition string
  152. var existPars []interface{}
  153. existCondition += " AND edb_info_id=? AND from_edb_info_id=? "
  154. existPars = append(existPars, edbInfo.EdbInfoId, req.FromEdbInfoId)
  155. //判断计算指标是否被更换
  156. count, err := GetEdbInfoCalculateCountByCondition(existCondition, existPars)
  157. if err != nil {
  158. err = errors.New("判断指标是否改变失败,Err:" + err.Error())
  159. return
  160. }
  161. if count > 0 { // 指标未被替换,无需删除关联数据
  162. // todo 频度被换了,需要重新计算
  163. if isRecalculate {
  164. err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "", req.Extra)
  165. }
  166. return
  167. }
  168. //删除,计算指标关联的,基础指标的关联关系
  169. sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
  170. err = to.Raw(sql, edbInfo.EdbInfoId).Error
  171. if err != nil {
  172. return
  173. }
  174. //清空原有数据
  175. sql = ` DELETE FROM ` + tableName + ` WHERE edb_info_id = ? `
  176. err = to.Raw(sql, edbInfo.EdbInfoId).Error
  177. if err != nil {
  178. return
  179. }
  180. //关联关系
  181. {
  182. calculateMappingItem := &EdbInfoCalculateMapping{
  183. EdbInfoCalculateMappingId: 0,
  184. EdbInfoId: edbInfo.EdbInfoId,
  185. Source: obj.GetSource(),
  186. SourceName: obj.GetSourceName(),
  187. EdbCode: edbInfo.EdbCode,
  188. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  189. FromEdbCode: fromEdbInfo.EdbCode,
  190. FromEdbName: fromEdbInfo.EdbName,
  191. FromSource: fromEdbInfo.Source,
  192. FromSourceName: fromEdbInfo.SourceName,
  193. FromTag: "",
  194. Sort: 1,
  195. CreateTime: time.Now(),
  196. ModifyTime: time.Now(),
  197. FromSubSource: fromEdbInfo.SubSource,
  198. }
  199. err = to.Create(calculateMappingItem).Error
  200. if err != nil {
  201. return
  202. }
  203. }
  204. //计算数据
  205. err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "", edbInfo.Extra)
  206. return
  207. }
  208. // Refresh 刷新
  209. func (obj Ljz) Refresh(params RefreshParams) (err error, errMsg string) {
  210. calculateMapping, err := GetEdbInfoCalculateMappingDetail(params.EdbInfo.EdbInfoId)
  211. if err != nil {
  212. errMsg = "GetEdbInfoCalculateLjzDetail Err:" + err.Error()
  213. return
  214. }
  215. fromEdbInfo, err := GetEdbInfoById(calculateMapping.FromEdbInfoId)
  216. if err != nil {
  217. errMsg = "GetEdbInfoById Err:" + err.Error()
  218. return
  219. }
  220. to := global.DEFAULT_DmSQL.Begin()
  221. defer func() {
  222. if err != nil {
  223. to.Rollback()
  224. } else {
  225. to.Commit()
  226. }
  227. }()
  228. // 计算数据
  229. err = obj.refresh(to, params.EdbInfo.EdbInfoId, params.EdbInfo.Source, params.EdbInfo.SubSource, params.EdbInfo, fromEdbInfo, params.EdbInfo.EdbCode, params.StartDate, params.EdbInfo.Extra)
  230. return
  231. }
  232. // GetSource 获取来源编码id
  233. func (obj Ljz) GetSource() int {
  234. return utils.DATA_SOURCE_CALCULATE_LJZ
  235. }
  236. // GetSourceName 获取来源名称
  237. func (obj Ljz) GetSourceName() string {
  238. return utils.DATA_SOURCE_NAME_CALCULATE_LJZ
  239. }
  240. // GetEdbType 获取指标类型
  241. func (obj Ljz) GetEdbType() int {
  242. return utils.CALCULATE_EDB_TYPE
  243. }
  244. func (obj Ljz) refresh(to *gorm.DB, edbInfoId, source, subSource int, edbInfo, fromEdbInfo *EdbInfo, edbCode, startDate string, extra string) (err error) {
  245. dataTableName := GetEdbDataTableName(source, subSource)
  246. edbInfoIdStr := strconv.Itoa(edbInfoId)
  247. //计算数据
  248. var isWeekData bool // 是否周度数据,如果是周度数据的话,是需要变频的,最后结果还需要除以7
  249. // 周度数据需要先变成日度的
  250. if fromEdbInfo.Frequency == `周度` {
  251. isWeekData = true
  252. }
  253. dataList, err := GetEdbDataListAllByTo(to, fromEdbInfo.Source, fromEdbInfo.SubSource, FindEdbDataListAllCond{
  254. EdbInfoId: fromEdbInfo.EdbInfoId,
  255. }, 1)
  256. if err != nil {
  257. return err
  258. }
  259. fromEdbDataMap := make(map[string]float64)
  260. if isWeekData {
  261. dataList, err = HandleDataByLinearRegression(dataList, fromEdbDataMap)
  262. if err != nil {
  263. return
  264. }
  265. }
  266. var lastValType int
  267. if extra != "" {
  268. var lastValConfig CalculateLjzEdbExtra
  269. err = json.Unmarshal([]byte(extra), &lastValConfig)
  270. if err != nil {
  271. err = fmt.Errorf("refreshAllCalculate,extra解析失败,Err:%s", err.Error())
  272. return
  273. }
  274. lastValType = lastValConfig.LastValType
  275. }
  276. //日度转周度:日期选周五,计算上周六到本周五的日度值的加总,最新日期为最新值对应的周五。
  277. //日度转旬度:日期选每个旬的最后一天,计算当旬所有日度值的加总,最新日期为最新值对应当旬的最后一天。
  278. //日度转月度:日期选每个月最后一天,计算当月所有日度值的加总,最新日期为最新值对应当月最后一天。
  279. //日度转季度、年度:方法类似转月度。
  280. //周度转月度/季度/年度:将周度值转成日度,空值用插值法插值,计算当月/当季/当年所有值的加总,然后除以7。
  281. //月度转季度/年度: 当季/当年月度值相加。
  282. dateList := make([]time.Time, 0)
  283. valueMap := make(map[time.Time]float64)
  284. switch edbInfo.Frequency {
  285. case "年度":
  286. yearMap := make(map[int]float64)
  287. yearList := make([]int, 0)
  288. var lastNewDate time.Time
  289. for _, item := range dataList {
  290. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
  291. if tmpErr != nil {
  292. err = tmpErr
  293. return
  294. }
  295. year := itemDate.Year()
  296. yearVal, ok := yearMap[year]
  297. if ok {
  298. yearMap[year] = item.Value + yearVal
  299. } else {
  300. yearList = append(yearList, year)
  301. yearMap[year] = item.Value
  302. }
  303. }
  304. for _, v := range yearList {
  305. currTime := time.Date(v, 12, 31, 0, 0, 0, 0, time.Local)
  306. dateList = append(dateList, currTime)
  307. valueMap[currTime] = yearMap[v]
  308. lastNewDate = currTime
  309. }
  310. // 根据配置处理最新值, 1 表示均值填充
  311. if lastValType == 1 {
  312. lastItem := dataList[len(dataList)-1]
  313. // 最后一天的累计值
  314. initVal := valueMap[lastNewDate]
  315. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
  316. if tmpErr != nil {
  317. err = tmpErr
  318. return
  319. }
  320. //获取当季的总天数, 当季最后一天减去当季第一天
  321. // 获取当年的总天数
  322. startDateT := time.Date(itemDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
  323. allDays := int(lastNewDate.Sub(startDateT).Hours() / 24)
  324. //获取距离当年第一天的天数
  325. days := int(itemDate.Sub(startDateT).Hours() / 24)
  326. daysT := decimal.NewFromInt(int64(days))
  327. initValAndMonthT := decimal.NewFromFloat(initVal * float64(allDays))
  328. val, _ := initValAndMonthT.Div(daysT).Round(4).Float64()
  329. fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", allDays, initVal, days, val)
  330. valueMap[lastNewDate] = val
  331. }
  332. case "半年度":
  333. yearMonthMap := make(map[string]float64)
  334. yearMonthList := make([]string, 0)
  335. var lastNewDate time.Time
  336. for _, item := range dataList {
  337. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
  338. if tmpErr != nil {
  339. err = tmpErr
  340. return
  341. }
  342. year := itemDate.Year()
  343. var tmpK string
  344. if itemDate.Month() <= 6 {
  345. tmpK = fmt.Sprint(year, "06")
  346. } else {
  347. tmpK = fmt.Sprint(year, "12")
  348. }
  349. yearVal, ok := yearMonthMap[tmpK]
  350. if ok {
  351. yearMonthMap[tmpK] = item.Value + yearVal
  352. } else {
  353. yearMonthList = append(yearMonthList, tmpK)
  354. yearMonthMap[tmpK] = item.Value
  355. }
  356. }
  357. for _, v := range yearMonthList {
  358. currTime, tmpErr := time.ParseInLocation(utils.FormatYearMonthUnSpace, v, time.Local)
  359. if tmpErr != nil {
  360. err = tmpErr
  361. return
  362. }
  363. currTime = currTime.AddDate(0, 1, -1)
  364. dateList = append(dateList, currTime)
  365. valueMap[currTime] = yearMonthMap[v]
  366. lastNewDate = currTime
  367. }
  368. // 根据配置处理最新值, 1 表示均值填充
  369. if lastValType == 1 {
  370. lastItem := dataList[len(dataList)-1]
  371. // 最后一天的累计值
  372. initVal := valueMap[lastNewDate]
  373. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
  374. if tmpErr != nil {
  375. err = tmpErr
  376. return
  377. }
  378. //获取上半年或者下半年的总天数, 半年度最后一天减去半年度第一天
  379. startDateT := lastNewDate.AddDate(0, -6, 0)
  380. allDays := int(lastNewDate.Sub(startDateT).Hours() / 24)
  381. //获取距离半年度第一天的天数
  382. days := int(itemDate.Sub(startDateT).Hours() / 24)
  383. daysT := decimal.NewFromInt(int64(days))
  384. initValAndMonthT := decimal.NewFromFloat(initVal * float64(allDays))
  385. val, _ := initValAndMonthT.Div(daysT).Round(4).Float64()
  386. fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", allDays, initVal, days, val)
  387. valueMap[lastNewDate] = val
  388. }
  389. case "季度":
  390. yearMonthMap := make(map[string]float64)
  391. yearMonthList := make([]string, 0)
  392. var lastNewDate time.Time
  393. for _, item := range dataList {
  394. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
  395. if tmpErr != nil {
  396. err = tmpErr
  397. return
  398. }
  399. year := itemDate.Year()
  400. var tmpK string
  401. if itemDate.Month() <= 3 {
  402. tmpK = fmt.Sprint(year, "03")
  403. } else if itemDate.Month() <= 6 {
  404. tmpK = fmt.Sprint(year, "06")
  405. } else if itemDate.Month() <= 9 {
  406. tmpK = fmt.Sprint(year, "09")
  407. } else {
  408. tmpK = fmt.Sprint(year, "12")
  409. }
  410. yearVal, ok := yearMonthMap[tmpK]
  411. if ok {
  412. yearMonthMap[tmpK] = item.Value + yearVal
  413. } else {
  414. yearMonthList = append(yearMonthList, tmpK)
  415. yearMonthMap[tmpK] = item.Value
  416. }
  417. }
  418. for _, v := range yearMonthList {
  419. currTime, tmpErr := time.ParseInLocation(utils.FormatYearMonthUnSpace, v, time.Local)
  420. if tmpErr != nil {
  421. err = tmpErr
  422. return
  423. }
  424. currTime = currTime.AddDate(0, 1, -1)
  425. dateList = append(dateList, currTime)
  426. valueMap[currTime] = yearMonthMap[v]
  427. lastNewDate = currTime
  428. }
  429. // 根据配置处理最新值, 1 表示均值填充
  430. if lastValType == 1 {
  431. lastItem := dataList[len(dataList)-1]
  432. // 最后一天的累计值
  433. initVal := valueMap[lastNewDate]
  434. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
  435. if tmpErr != nil {
  436. err = tmpErr
  437. return
  438. }
  439. //获取当季的总天数, 当季最后一天减去当季第一天
  440. startDateT := lastNewDate.AddDate(0, -3, 0)
  441. allDays := int(lastNewDate.Sub(startDateT).Hours() / 24)
  442. //获取距离当季第一天的天数
  443. days := int(itemDate.Sub(startDateT).Hours() / 24)
  444. daysT := decimal.NewFromInt(int64(days))
  445. initValAndMonthT := decimal.NewFromFloat(initVal * float64(allDays))
  446. val, _ := initValAndMonthT.Div(daysT).Round(4).Float64()
  447. fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", allDays, initVal, days, val)
  448. valueMap[lastNewDate] = val
  449. }
  450. case "月度":
  451. yearMonthMap := make(map[string]float64)
  452. yearMonthList := make([]string, 0)
  453. var lastNewDate time.Time
  454. for _, item := range dataList {
  455. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
  456. if tmpErr != nil {
  457. err = tmpErr
  458. return
  459. }
  460. year := itemDate.Year()
  461. var tmpK string
  462. tmpK = fmt.Sprint(year*100 + int(itemDate.Month()))
  463. yearVal, ok := yearMonthMap[tmpK]
  464. if ok {
  465. yearMonthMap[tmpK] = item.Value + yearVal
  466. fmt.Printf("%s 累加值:%f = %.6f + %.6f\n", tmpK, yearMonthMap[tmpK], item.Value, yearVal)
  467. } else {
  468. yearMonthList = append(yearMonthList, tmpK)
  469. yearMonthMap[tmpK] = item.Value
  470. }
  471. }
  472. for _, v := range yearMonthList {
  473. currTime, tmpErr := time.ParseInLocation(utils.FormatYearMonthUnSpace, v, time.Local)
  474. if tmpErr != nil {
  475. err = tmpErr
  476. return
  477. }
  478. currTime = currTime.AddDate(0, 1, -1)
  479. dateList = append(dateList, currTime)
  480. valueMap[currTime] = yearMonthMap[v]
  481. lastNewDate = currTime
  482. }
  483. // 根据配置处理最新值, 1 表示均值填充
  484. if lastValType == 1 {
  485. lastItem := dataList[len(dataList)-1]
  486. // 最后一天的累计值
  487. initVal := valueMap[lastNewDate]
  488. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
  489. if tmpErr != nil {
  490. err = tmpErr
  491. return
  492. }
  493. //获取当月的天数
  494. monthDays := lastNewDate.Day()
  495. //获取自然日的天数
  496. days := itemDate.Day()
  497. daysT := decimal.NewFromInt(int64(days))
  498. initValAndMonthT := decimal.NewFromFloat(initVal * float64(monthDays))
  499. val, _ := initValAndMonthT.Div(daysT).Round(4).Float64()
  500. fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", monthDays, initVal, days, val)
  501. valueMap[lastNewDate] = val
  502. }
  503. case "旬度":
  504. tmpDateDataMap := make(map[time.Time]float64)
  505. tmpDateList := make([]time.Time, 0)
  506. for _, item := range dataList {
  507. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
  508. if tmpErr != nil {
  509. err = tmpErr
  510. return
  511. }
  512. dayInt := itemDate.Year()*100 + int(itemDate.Month())
  513. var currTime time.Time
  514. if itemDate.Day() <= 10 {
  515. //本月上旬
  516. tmpK := fmt.Sprint(dayInt, "10")
  517. currTime, err = time.ParseInLocation(utils.FormatDateUnSpace, tmpK, time.Local)
  518. if err != nil {
  519. return
  520. }
  521. } else if itemDate.Day() <= 20 {
  522. // 本月中旬
  523. tmpK := fmt.Sprint(dayInt, "20")
  524. currTime, err = time.ParseInLocation(utils.FormatDateUnSpace, tmpK, time.Local)
  525. if err != nil {
  526. return
  527. }
  528. } else {
  529. // 本月下旬
  530. currTime, err = time.ParseInLocation(utils.FormatYearMonthUnSpace, fmt.Sprint(dayInt), time.Local)
  531. if err != nil {
  532. return
  533. }
  534. currTime = currTime.AddDate(0, 1, -1)
  535. }
  536. yearVal, ok := tmpDateDataMap[currTime]
  537. if ok {
  538. tmpDateDataMap[currTime] = item.Value + yearVal
  539. } else {
  540. tmpDateList = append(tmpDateList, currTime)
  541. tmpDateDataMap[currTime] = item.Value
  542. }
  543. }
  544. for _, currTime := range tmpDateList {
  545. dateList = append(dateList, currTime)
  546. valueMap[currTime] = tmpDateDataMap[currTime]
  547. }
  548. case "周度":
  549. tmpDateDataMap := make(map[time.Time]float64)
  550. tmpDateList := make([]time.Time, 0)
  551. for _, item := range dataList {
  552. itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
  553. if tmpErr != nil {
  554. err = tmpErr
  555. return
  556. }
  557. var currTime time.Time
  558. // 周六周日,这是下一个周五的数据
  559. if itemDate.Weekday() == 0 {
  560. currTime = itemDate.AddDate(0, 0, 5)
  561. } else if itemDate.Weekday() == 6 {
  562. currTime = itemDate.AddDate(0, 0, 6)
  563. } else {
  564. currTime = itemDate.AddDate(0, 0, 5-int(itemDate.Weekday()))
  565. }
  566. yearVal, ok := tmpDateDataMap[currTime]
  567. if ok {
  568. tmpDateDataMap[currTime] = item.Value + yearVal
  569. } else {
  570. tmpDateList = append(tmpDateList, currTime)
  571. tmpDateDataMap[currTime] = item.Value
  572. }
  573. }
  574. for _, currTime := range tmpDateList {
  575. dateList = append(dateList, currTime)
  576. valueMap[currTime] = tmpDateDataMap[currTime]
  577. }
  578. }
  579. //获取指标所有数据
  580. existDataList, err := GetAllEdbDataListByTo(to, edbInfoId, edbInfo.Source, edbInfo.SubSource)
  581. if err != nil {
  582. return err
  583. }
  584. existDataMap := make(map[string]string)
  585. removeDataTimeMap := make(map[string]int) //需要移除的日期数据
  586. for _, v := range existDataList {
  587. existDataMap[v.DataTime] = v.Value
  588. removeDataTimeMap[v.DataTime] = 1
  589. }
  590. needAddDateMap := make(map[time.Time]int)
  591. addSql := ` INSERT INTO ` + dataTableName + `(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
  592. var isAdd bool
  593. for _, currTime := range dateList {
  594. currDateStr := currTime.Format(utils.FormatDate)
  595. existVal, ok := existDataMap[currDateStr]
  596. tmpVal, ok2 := valueMap[currTime]
  597. if !ok2 {
  598. err = errors.New("数据异常,date:" + currDateStr)
  599. return
  600. }
  601. var saveValue string
  602. if isWeekData { //周度指标转的话,最后结果要除以7
  603. saveValue = decimal.NewFromFloat(tmpVal).Div(decimal.NewFromInt(7)).Round(4).String()
  604. } else {
  605. saveValue = decimal.NewFromFloat(tmpVal).Round(4).String()
  606. }
  607. // 如果库中已经存在该数据的话,那么就进行值的变更操作
  608. if ok {
  609. //校验待删除日期数据里面是否存在该元素,如果存在的话,那么移除该日期
  610. delete(removeDataTimeMap, currDateStr)
  611. if existVal != saveValue {
  612. sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
  613. sql = fmt.Sprintf(sql, dataTableName)
  614. err = to.Raw(sql, saveValue, edbInfoId, currDateStr).Error
  615. if err != nil {
  616. return
  617. }
  618. }
  619. continue
  620. }
  621. // 库中不存在该日期的数据
  622. timestamp := currTime.UnixNano() / 1e6
  623. timeStr := fmt.Sprintf("%d", timestamp)
  624. if _, existOk := needAddDateMap[currTime]; !existOk {
  625. addSql += GetAddSql(edbInfoIdStr, edbCode, currDateStr, timeStr, saveValue)
  626. isAdd = true
  627. }
  628. needAddDateMap[currTime] = 1
  629. }
  630. //删除已经不存在的指标数据(由于该指标当日的数据删除了)
  631. {
  632. removeDateList := make([]string, 0)
  633. for dateTime := range removeDataTimeMap {
  634. removeDateList = append(removeDateList, dateTime)
  635. }
  636. removeNum := len(removeDateList)
  637. if removeNum > 0 {
  638. sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (`+utils.GetOrmInReplace(removeNum)+`) `, dataTableName)
  639. err = to.Raw(sql, edbInfo.EdbInfoId, removeDateList).Error
  640. if err != nil {
  641. fmt.Println(reflect.TypeOf(obj).Name(), " add data ;delete Err", err.Error())
  642. err = fmt.Errorf("删除不存在的指标数据失败,Err:" + err.Error())
  643. return
  644. }
  645. }
  646. }
  647. if isAdd {
  648. addSql = strings.TrimRight(addSql, ",")
  649. err = to.Exec(addSql).Error
  650. if err != nil {
  651. fmt.Println(reflect.TypeOf(obj).Name(), " add data Err", err.Error())
  652. return
  653. }
  654. }
  655. return
  656. }