edb_data_calculate_nhcc.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. package models
  2. import (
  3. "errors"
  4. "eta_gn/eta_index_lib/global"
  5. "eta_gn/eta_index_lib/utils"
  6. "fmt"
  7. "github.com/shopspring/decimal"
  8. "gorm.io/gorm"
  9. "math"
  10. "strings"
  11. "time"
  12. )
  13. type EdbDataCalculateNhcc struct {
  14. EdbDataId int `gorm:"primaryKey;autoIncrement;column:edb_data_id"`
  15. EdbInfoId int `gorm:"column:edb_info_id" description:"指标ID"`
  16. EdbCode string `gorm:"column:edb_code" description:"指标编码"`
  17. DataTime string `gorm:"column:data_time" description:"数据日期"`
  18. Value float64 `gorm:"column:value" description:"数据值"`
  19. Status int `gorm:"column:status" description:"状态"`
  20. CreateTime time.Time `gorm:"column:create_time" description:"创建时间"`
  21. ModifyTime time.Time `gorm:"column:modify_time" description:"修改时间"`
  22. DataTimestamp int64 `gorm:"column:data_timestamp" description:"数据日期时间戳"`
  23. }
  24. type NhccDate struct {
  25. StartDate time.Time
  26. EndDate time.Time
  27. }
  28. func AddCalculateNhcc(req *EdbInfoCalculateBatchSaveReq, firstEdbInfo, secondEdbInfo *EdbInfo, edbCode, uniqueCode string, nhccDate NhccDate, sysUserId int, sysUserRealName string) (edbInfo *EdbInfo, err error, errMsg string) {
  29. to := global.DEFAULT_DmSQL.Begin()
  30. defer func() {
  31. if err != nil {
  32. to.Rollback()
  33. } else {
  34. to.Commit()
  35. }
  36. }()
  37. if req.EdbInfoId <= 0 {
  38. edbInfo = &EdbInfo{
  39. SourceName: "拟合残差",
  40. Source: utils.DATA_SOURCE_CALCULATE_NHCC,
  41. EdbCode: edbCode,
  42. EdbName: req.EdbName,
  43. EdbNameSource: req.EdbName,
  44. Frequency: req.Frequency,
  45. Unit: req.Unit,
  46. StartDate: firstEdbInfo.StartDate,
  47. EndDate: firstEdbInfo.EndDate,
  48. ClassifyId: req.ClassifyId,
  49. SysUserId: sysUserId,
  50. SysUserRealName: sysUserRealName,
  51. UniqueCode: uniqueCode,
  52. CreateTime: time.Now(),
  53. ModifyTime: time.Now(),
  54. CalculateFormula: req.Formula,
  55. EdbNameEn: req.EdbName,
  56. UnitEn: req.Unit,
  57. EdbType: 2,
  58. Sort: GetAddEdbMaxSortByClassifyId(req.ClassifyId, utils.EDB_INFO_TYPE),
  59. }
  60. tmpErr := to.Create(edbInfo).Error
  61. if tmpErr != nil {
  62. err = tmpErr
  63. return
  64. }
  65. } else {
  66. edbInfo, err = GetEdbInfoById(req.EdbInfoId)
  67. if err != nil {
  68. return
  69. }
  70. tmpEdbInfo, tmpErr := GetEdbInfoById(edbInfo.EdbInfoId)
  71. if tmpErr != nil {
  72. err = tmpErr
  73. return
  74. }
  75. tmpEdbInfo.EdbName = req.EdbName
  76. tmpEdbInfo.ClassifyId = req.ClassifyId
  77. tmpEdbInfo.Frequency = req.Frequency
  78. tmpEdbInfo.Unit = req.Unit
  79. tmpEdbInfo.CalculateFormula = req.Formula
  80. edbInfo = tmpEdbInfo
  81. dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_NHCC, utils.DATA_SUB_SOURCE_EDB)
  82. fmt.Println("dataTableName:" + dataTableName)
  83. deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
  84. deleteSql = fmt.Sprintf(deleteSql, dataTableName)
  85. err = to.Exec(deleteSql, req.EdbInfoId).Error
  86. if err != nil {
  87. return
  88. }
  89. sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id=? `
  90. err = to.Exec(sql, edbInfo.EdbInfoId).Error
  91. }
  92. var existItemA, existItemB *EdbInfoCalculateMapping
  93. {
  94. existItemA = &EdbInfoCalculateMapping{
  95. EdbInfoCalculateMappingId: 0,
  96. EdbInfoId: edbInfo.EdbInfoId,
  97. Source: edbInfo.Source,
  98. SourceName: edbInfo.SourceName,
  99. EdbCode: edbInfo.EdbCode,
  100. FromEdbInfoId: firstEdbInfo.EdbInfoId,
  101. FromEdbCode: firstEdbInfo.EdbCode,
  102. FromEdbName: firstEdbInfo.EdbName,
  103. FromSource: firstEdbInfo.Source,
  104. FromSourceName: firstEdbInfo.SourceName,
  105. FromTag: "A",
  106. MoveValue: req.EdbInfoIdArr[0].MoveValue,
  107. Sort: 1,
  108. CreateTime: time.Now(),
  109. ModifyTime: time.Now(),
  110. FromSubSource: firstEdbInfo.SubSource,
  111. }
  112. tmpErr := to.Create(existItemA).Error
  113. if tmpErr != nil {
  114. err = tmpErr
  115. return
  116. }
  117. }
  118. {
  119. existItemB = &EdbInfoCalculateMapping{
  120. EdbInfoCalculateMappingId: 0,
  121. EdbInfoId: edbInfo.EdbInfoId,
  122. Source: edbInfo.Source,
  123. SourceName: edbInfo.SourceName,
  124. EdbCode: edbInfo.EdbCode,
  125. FromEdbInfoId: secondEdbInfo.EdbInfoId,
  126. FromEdbCode: secondEdbInfo.EdbCode,
  127. FromEdbName: secondEdbInfo.EdbName,
  128. FromSource: secondEdbInfo.Source,
  129. FromSourceName: secondEdbInfo.SourceName,
  130. FromTag: "B",
  131. MoveValue: req.EdbInfoIdArr[1].MoveValue,
  132. Sort: 1,
  133. CreateTime: time.Now(),
  134. ModifyTime: time.Now(),
  135. FromSubSource: secondEdbInfo.SubSource,
  136. }
  137. tmpErr := to.Create(existItemB).Error
  138. if tmpErr != nil {
  139. err = tmpErr
  140. return
  141. }
  142. }
  143. err, errMsg = refreshAllCalculateNhcc(to, edbInfo, existItemA, existItemB, nhccDate)
  144. return
  145. }
  146. func EditCalculateNhcc(req *EdbInfoCalculateBatchEditReq, edbInfo, firstEdbInfo, secondEdbInfo *EdbInfo, nhccDate NhccDate) (err error, errMsg string) {
  147. to := global.DEFAULT_DmSQL.Begin()
  148. defer func() {
  149. if err != nil {
  150. to.Rollback()
  151. } else {
  152. to.Commit()
  153. }
  154. }()
  155. nowEdbInfo := *edbInfo // 现在的指标信息
  156. edbInfo.EdbName = req.EdbName
  157. edbInfo.EdbNameSource = req.EdbName
  158. edbInfo.Frequency = req.Frequency
  159. edbInfo.Unit = req.Unit
  160. edbInfo.ClassifyId = req.ClassifyId
  161. edbInfo.CalculateFormula = req.Formula
  162. edbInfo.EdbNameEn = req.EdbNameEn
  163. edbInfo.UnitEn = req.UnitEn
  164. edbInfo.ModifyTime = time.Now()
  165. err = to.Model(edbInfo).Select([]string{"EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "CalculateFormula", "ModifyTime", "EdbNameEn", "UnitEn"}).Updates(edbInfo).Error
  166. if err != nil {
  167. return
  168. }
  169. var existCondition string
  170. var existPars []interface{}
  171. existCondition += " AND edb_info_id=? "
  172. existPars = append(existPars, edbInfo.EdbInfoId)
  173. existList, err := GetEdbInfoCalculateListByCondition(existCondition, existPars)
  174. if err != nil {
  175. err = fmt.Errorf("判断指标是否改变失败,Err:" + err.Error())
  176. return
  177. }
  178. var existItemA, existItemB *EdbInfoCalculateMapping
  179. for _, existItem := range existList {
  180. if existItem.FromTag == "A" {
  181. existItemA = existItem
  182. } else if existItem.FromTag == "B" {
  183. existItemB = existItem
  184. }
  185. }
  186. isNeedCalculateData := false
  187. if req.Formula != nowEdbInfo.CalculateFormula {
  188. isNeedCalculateData = true
  189. }
  190. var isDeleteA, isDeleteB bool
  191. {
  192. if existItemA.FromEdbInfoId != firstEdbInfo.EdbInfoId {
  193. sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? and from_edb_info_id = ?`
  194. err = to.Exec(sql, edbInfo.EdbInfoId, existItemA.FromEdbInfoId).Error
  195. if err != nil {
  196. err = fmt.Errorf("删除指标A关联关系失败,Err:" + err.Error())
  197. return
  198. }
  199. isDeleteA = true
  200. }
  201. if existItemB.FromEdbInfoId != secondEdbInfo.EdbInfoId {
  202. sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? and from_edb_info_id = ?`
  203. err = to.Exec(sql, edbInfo.EdbInfoId, existItemB.FromEdbInfoId).Error
  204. if err != nil {
  205. err = fmt.Errorf("删除指标B关联关系失败,Err:" + err.Error())
  206. return
  207. }
  208. isDeleteB = true
  209. }
  210. }
  211. {
  212. if isDeleteA {
  213. {
  214. existItemA = &EdbInfoCalculateMapping{
  215. EdbInfoCalculateMappingId: 0,
  216. EdbInfoId: edbInfo.EdbInfoId,
  217. Source: edbInfo.Source,
  218. SourceName: edbInfo.SourceName,
  219. EdbCode: edbInfo.EdbCode,
  220. FromEdbInfoId: firstEdbInfo.EdbInfoId,
  221. FromEdbCode: firstEdbInfo.EdbCode,
  222. FromEdbName: firstEdbInfo.EdbName,
  223. FromSource: firstEdbInfo.Source,
  224. FromSourceName: firstEdbInfo.SourceName,
  225. FromTag: "A",
  226. MoveValue: req.EdbInfoIdArr[0].MoveValue,
  227. Sort: 1,
  228. CreateTime: time.Now(),
  229. ModifyTime: time.Now(),
  230. FromSubSource: firstEdbInfo.SubSource,
  231. }
  232. tmpErr := to.Create(existItemA).Error
  233. if tmpErr != nil {
  234. err = tmpErr
  235. return
  236. }
  237. isNeedCalculateData = true
  238. }
  239. } else if existItemA.MoveValue != req.EdbInfoIdArr[0].MoveValue {
  240. existItemA.ModifyTime = time.Now()
  241. existItemA.MoveValue = req.EdbInfoIdArr[0].MoveValue
  242. err = to.Model(existItemA).Select([]string{"ModifyTime", "MoveValue"}).Updates(existItemA).Error
  243. if err != nil {
  244. return
  245. }
  246. isNeedCalculateData = true
  247. }
  248. }
  249. {
  250. if isDeleteB {
  251. existItemB = &EdbInfoCalculateMapping{
  252. EdbInfoCalculateMappingId: 0,
  253. EdbInfoId: edbInfo.EdbInfoId,
  254. Source: edbInfo.Source,
  255. SourceName: edbInfo.SourceName,
  256. EdbCode: edbInfo.EdbCode,
  257. FromEdbInfoId: secondEdbInfo.EdbInfoId,
  258. FromEdbCode: secondEdbInfo.EdbCode,
  259. FromEdbName: secondEdbInfo.EdbName,
  260. FromSource: secondEdbInfo.Source,
  261. FromSourceName: secondEdbInfo.SourceName,
  262. FromTag: "B",
  263. MoveValue: req.EdbInfoIdArr[1].MoveValue,
  264. Sort: 2,
  265. CreateTime: time.Now(),
  266. ModifyTime: time.Now(),
  267. FromSubSource: secondEdbInfo.SubSource,
  268. }
  269. tmpErr := to.Create(existItemB).Error
  270. if tmpErr != nil {
  271. err = tmpErr
  272. return
  273. }
  274. isNeedCalculateData = true
  275. } else if existItemB.MoveValue != req.EdbInfoIdArr[1].MoveValue {
  276. existItemB.ModifyTime = time.Now()
  277. existItemB.MoveValue = req.EdbInfoIdArr[1].MoveValue
  278. err = to.Model(existItemB).Select([]string{"ModifyTime", "MoveValue"}).Updates(existItemB).Error
  279. if err != nil {
  280. return
  281. }
  282. isNeedCalculateData = true
  283. }
  284. }
  285. if isNeedCalculateData {
  286. tableName := GetEdbDataTableName(edbInfo.Source, edbInfo.SubSource)
  287. sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? `, tableName)
  288. err = to.Exec(sql, edbInfo.EdbInfoId).Error
  289. if err != nil {
  290. err = fmt.Errorf("删除历史数据失败,Err:" + err.Error())
  291. return
  292. }
  293. err, errMsg = refreshAllCalculateNhcc(to, edbInfo, existItemA, existItemB, nhccDate)
  294. }
  295. return
  296. }
  297. func RefreshAllCalculateNhcc(edbInfo *EdbInfo) (err error) {
  298. to := global.DEFAULT_DmSQL.Begin()
  299. defer func() {
  300. if err != nil {
  301. to.Rollback()
  302. } else {
  303. to.Commit()
  304. }
  305. }()
  306. var existCondition string
  307. var existPars []interface{}
  308. existCondition += " AND edb_info_id=? "
  309. existPars = append(existPars, edbInfo.EdbInfoId)
  310. existList, err := GetEdbInfoCalculateListByCondition(existCondition, existPars)
  311. if err != nil {
  312. err = fmt.Errorf("判断指标是否改变失败,Err:" + err.Error())
  313. return
  314. }
  315. var existItemA, existItemB *EdbInfoCalculateMapping
  316. for _, existItem := range existList {
  317. if existItem.FromTag == "A" {
  318. existItemA = existItem
  319. } else if existItem.FromTag == "B" {
  320. existItemB = existItem
  321. }
  322. }
  323. timeList := strings.Split(edbInfo.CalculateFormula, ",")
  324. startDate, err := time.ParseInLocation(utils.FormatDate, timeList[0], time.Local)
  325. if err != nil {
  326. return
  327. }
  328. endDate, err := time.ParseInLocation(utils.FormatDate, timeList[1], time.Local)
  329. if err != nil {
  330. return
  331. }
  332. if endDate.Sub(startDate).Hours() < 48 {
  333. return
  334. }
  335. nhccDate := NhccDate{
  336. StartDate: startDate,
  337. EndDate: endDate,
  338. }
  339. err, _ = refreshAllCalculateNhcc(to, edbInfo, existItemA, existItemB, nhccDate)
  340. return
  341. }
  342. func refreshAllCalculateNhcc(to *gorm.DB, edbInfo *EdbInfo, existItemA, existItemB *EdbInfoCalculateMapping, nhccDate NhccDate) (err error, errMsg string) {
  343. var condition string
  344. var pars []interface{}
  345. condition += " AND edb_info_id=? "
  346. pars = append(pars, edbInfo.EdbInfoId)
  347. var dataList []*EdbDataCalculateNhcc
  348. sql := ` SELECT * FROM edb_data_calculate_nhcc WHERE edb_info_id=? ORDER BY data_time DESC `
  349. err = to.Raw(sql, edbInfo.EdbInfoId).Scan(&dataList).Error
  350. if err != nil {
  351. return
  352. }
  353. var dateArr []string
  354. dataMap := make(map[string]*EdbDataCalculateNhcc)
  355. removeDataTimeMap := make(map[string]int) //需要移除的日期数据
  356. for _, v := range dataList {
  357. dateArr = append(dateArr, v.DataTime)
  358. dataMap[v.DataTime] = v
  359. removeDataTimeMap[v.DataTime] = 1
  360. }
  361. addDataList := make([]*EdbDataCalculateNhcc, 0)
  362. aDataList, secondDataList, aDataMap, bDataMap, nhccDate, err, errMsg := getNhccData(to, existItemA, existItemB, nhccDate)
  363. if err != nil {
  364. return
  365. }
  366. var a, b float64
  367. {
  368. coordinateData := make([]utils.Coordinate, 0)
  369. for i := nhccDate.StartDate; i.Before(nhccDate.EndDate) || i.Equal(nhccDate.EndDate); i = i.AddDate(0, 0, 1) {
  370. dateStr := i.Format(utils.FormatDate)
  371. xValue, ok := aDataMap[dateStr]
  372. if !ok {
  373. errMsg = "指标A日期:" + dateStr + "数据异常,导致计算线性方程公式失败"
  374. err = errors.New(errMsg)
  375. return
  376. }
  377. yValue, ok := bDataMap[dateStr]
  378. if !ok {
  379. errMsg = "指标B日期:" + dateStr + "数据异常,导致计算线性方程公式失败"
  380. err = errors.New(errMsg)
  381. return
  382. }
  383. tmpCoordinate := utils.Coordinate{
  384. X: xValue,
  385. Y: yValue,
  386. }
  387. coordinateData = append(coordinateData, tmpCoordinate)
  388. }
  389. a, b = utils.GetLinearResult(coordinateData)
  390. }
  391. if math.IsNaN(a) || math.IsNaN(b) {
  392. errMsg = "线性方程公式生成失败"
  393. err = errors.New(errMsg)
  394. return
  395. }
  396. newBDataMap := make(map[string]float64)
  397. {
  398. aDecimal := decimal.NewFromFloat(a)
  399. bDecimal := decimal.NewFromFloat(b)
  400. for _, aData := range aDataList {
  401. xDecimal := decimal.NewFromFloat(aData.Value)
  402. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  403. newBDataMap[aData.DataTime] = val
  404. }
  405. }
  406. for _, bData := range secondDataList {
  407. currDate := bData.DataTime
  408. if _, ok := removeDataTimeMap[currDate]; ok {
  409. delete(removeDataTimeMap, currDate)
  410. }
  411. b2Val, ok := newBDataMap[currDate]
  412. if !ok {
  413. continue
  414. }
  415. bDecimal := decimal.NewFromFloat(bData.Value)
  416. b2Decimal := decimal.NewFromFloat(b2Val)
  417. val, _ := bDecimal.Sub(b2Decimal).Round(4).Float64()
  418. existData, ok := dataMap[currDate]
  419. if !ok { //不存在那么就添加吧
  420. currentDate, _ := time.ParseInLocation(utils.FormatDate, currDate, time.Local)
  421. timestamp := currentDate.UnixNano() / 1e6
  422. edbDataNhcc := &EdbDataCalculateNhcc{
  423. EdbInfoId: edbInfo.EdbInfoId,
  424. EdbCode: edbInfo.EdbCode,
  425. DataTime: currDate,
  426. Value: val,
  427. Status: 1,
  428. CreateTime: time.Now(),
  429. ModifyTime: time.Now(),
  430. DataTimestamp: timestamp,
  431. }
  432. addDataList = append(addDataList, edbDataNhcc)
  433. } else {
  434. if existData.Value != val {
  435. existData.Value = val
  436. _ = to.Model(existData).Select([]string{"Value"}).Updates(existData).Error
  437. if err != nil {
  438. return
  439. }
  440. }
  441. }
  442. }
  443. {
  444. removeDateList := make([]string, 0)
  445. for dateTime := range removeDataTimeMap {
  446. removeDateList = append(removeDateList, dateTime)
  447. }
  448. removeNum := len(removeDateList)
  449. if removeNum > 0 {
  450. tableName := GetEdbDataTableName(edbInfo.Source, edbInfo.SubSource)
  451. sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (`+utils.GetOrmInReplace(removeNum)+`) `, tableName)
  452. err = to.Exec(sql, edbInfo.EdbInfoId, removeDateList).Error
  453. if err != nil {
  454. err = fmt.Errorf("删除不存在的拟合残差指标数据失败,Err:" + err.Error())
  455. return
  456. }
  457. }
  458. }
  459. if len(addDataList) > 0 {
  460. tmpAddDataList := make([]*EdbDataCalculateNhcc, 0)
  461. i := 0
  462. for _, v := range addDataList {
  463. tmpAddDataList = append(tmpAddDataList, v)
  464. i++
  465. if i >= 500 {
  466. err = to.CreateInBatches(tmpAddDataList, 500).Error
  467. if err != nil {
  468. return
  469. }
  470. i = 0
  471. tmpAddDataList = make([]*EdbDataCalculateNhcc, 0)
  472. }
  473. }
  474. if len(tmpAddDataList) > 0 {
  475. err = to.CreateInBatches(tmpAddDataList, 500).Error
  476. if err != nil {
  477. return
  478. }
  479. }
  480. }
  481. return
  482. }
  483. func CalculateComputeCorrelation(req *EdbInfoCalculateBatchSaveReq, firstEdbInfo, secondEdbInfo *EdbInfo, nhccDate NhccDate) (a, b, r float64, err error, errMsg string) {
  484. var existItemA, existItemB *EdbInfoCalculateMapping
  485. {
  486. existItemA = &EdbInfoCalculateMapping{
  487. EdbInfoCalculateMappingId: 0,
  488. FromEdbInfoId: firstEdbInfo.EdbInfoId,
  489. FromEdbCode: firstEdbInfo.EdbCode,
  490. FromEdbName: firstEdbInfo.EdbName,
  491. FromSource: firstEdbInfo.Source,
  492. FromSourceName: firstEdbInfo.SourceName,
  493. FromTag: "A",
  494. MoveValue: req.EdbInfoIdArr[0].MoveValue,
  495. Sort: 1,
  496. CreateTime: time.Now(),
  497. ModifyTime: time.Now(),
  498. FromSubSource: firstEdbInfo.SubSource,
  499. }
  500. }
  501. {
  502. existItemB = &EdbInfoCalculateMapping{
  503. EdbInfoCalculateMappingId: 0,
  504. FromEdbInfoId: secondEdbInfo.EdbInfoId,
  505. FromEdbCode: secondEdbInfo.EdbCode,
  506. FromEdbName: secondEdbInfo.EdbName,
  507. FromSource: secondEdbInfo.Source,
  508. FromSourceName: secondEdbInfo.SourceName,
  509. FromTag: "B",
  510. MoveValue: req.EdbInfoIdArr[1].MoveValue,
  511. Sort: 1,
  512. CreateTime: time.Now(),
  513. ModifyTime: time.Now(),
  514. FromSubSource: secondEdbInfo.SubSource,
  515. }
  516. }
  517. to := global.DEFAULT_DmSQL.Begin()
  518. defer func() {
  519. if err != nil {
  520. to.Rollback()
  521. } else {
  522. to.Commit()
  523. }
  524. }()
  525. _, _, aDataMap, bDataMap, nhccDate, err, errMsg := getNhccData(to, existItemA, existItemB, nhccDate)
  526. if err != nil {
  527. return
  528. }
  529. coordinateData := make([]utils.Coordinate, 0)
  530. for i := nhccDate.StartDate; i.Before(nhccDate.EndDate) || i.Equal(nhccDate.EndDate); i = i.AddDate(0, 0, 1) {
  531. dateStr := i.Format(utils.FormatDate)
  532. xValue, ok := aDataMap[dateStr]
  533. if !ok {
  534. errMsg = "指标A日期:" + dateStr + "数据异常,导致计算线性方程公式失败"
  535. err = errors.New(errMsg)
  536. return
  537. }
  538. yValue, ok := bDataMap[dateStr]
  539. if !ok {
  540. errMsg = "指标B日期:" + dateStr + "数据异常,导致计算线性方程公式失败"
  541. err = errors.New(errMsg)
  542. return
  543. }
  544. tmpCoordinate := utils.Coordinate{
  545. X: xValue,
  546. Y: yValue,
  547. }
  548. coordinateData = append(coordinateData, tmpCoordinate)
  549. }
  550. a, b = utils.GetLinearResult(coordinateData)
  551. r = utils.ComputeCorrelation(coordinateData)
  552. return
  553. }
  554. func getNhccData(to *gorm.DB, existItemA, existItemB *EdbInfoCalculateMapping, nhccDate NhccDate) (aDataList []EdbInfoSearchData, secondDataList []*EdbInfoSearchData, aDataMap, bDataMap map[string]float64, newNhccDate NhccDate, err error, errMsg string) {
  555. newNhccDate = nhccDate
  556. aDataList = make([]EdbInfoSearchData, 0)
  557. aDataMap = make(map[string]float64)
  558. {
  559. firstDataList, tmpErr := GetEdbDataListAllByTo(to, existItemA.FromSource, existItemA.FromSubSource, FindEdbDataListAllCond{
  560. EdbInfoId: existItemA.FromEdbInfoId,
  561. }, 0)
  562. if tmpErr != nil {
  563. err = tmpErr
  564. return
  565. }
  566. aDataList, aDataMap = handleNhccData(firstDataList, existItemA.MoveValue)
  567. }
  568. bDataList := make([]EdbInfoSearchData, 0)
  569. secondDataList = make([]*EdbInfoSearchData, 0)
  570. bDataMap = make(map[string]float64)
  571. {
  572. secondDataList, err = GetEdbDataListAllByTo(to, existItemB.FromSource, existItemB.FromSubSource, FindEdbDataListAllCond{
  573. EdbInfoId: existItemB.FromEdbInfoId,
  574. }, 0)
  575. if err != nil {
  576. return
  577. }
  578. bDataList, bDataMap = handleNhccData(secondDataList, existItemB.MoveValue)
  579. }
  580. if len(aDataList) <= 0 {
  581. errMsg = "指标A没有数据"
  582. err = errors.New(errMsg)
  583. return
  584. }
  585. if len(bDataList) <= 0 {
  586. errMsg = "指标B没有数据"
  587. err = errors.New(errMsg)
  588. return
  589. }
  590. {
  591. startAData := aDataList[0]
  592. tmpStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, startAData.DataTime, time.Local)
  593. if tmpErr != nil {
  594. err = tmpErr
  595. return
  596. }
  597. if tmpStartDate.After(newNhccDate.StartDate) {
  598. newNhccDate.StartDate = tmpStartDate
  599. }
  600. startBData := bDataList[0]
  601. tmpStartDate, tmpErr = time.ParseInLocation(utils.FormatDate, startBData.DataTime, time.Local)
  602. if tmpErr != nil {
  603. err = tmpErr
  604. return
  605. }
  606. if tmpStartDate.After(newNhccDate.StartDate) {
  607. newNhccDate.StartDate = tmpStartDate
  608. }
  609. }
  610. {
  611. endAData := aDataList[len(aDataList)-1]
  612. tmpEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, endAData.DataTime, time.Local)
  613. if tmpErr != nil {
  614. err = tmpErr
  615. return
  616. }
  617. if tmpEndDate.Before(newNhccDate.EndDate) {
  618. newNhccDate.EndDate = tmpEndDate
  619. }
  620. endBData := bDataList[len(bDataList)-1]
  621. tmpEndDate, tmpErr = time.ParseInLocation(utils.FormatDate, endBData.DataTime, time.Local)
  622. if tmpErr != nil {
  623. err = tmpErr
  624. return
  625. }
  626. if tmpEndDate.Before(newNhccDate.EndDate) {
  627. newNhccDate.EndDate = tmpEndDate
  628. }
  629. }
  630. return
  631. }
  632. func handleNhccData(dataList []*EdbInfoSearchData, moveDay int) (newDataList []EdbInfoSearchData, dateDataMap map[string]float64) {
  633. dateMap := make(map[time.Time]float64)
  634. var minDate, maxDate time.Time
  635. dateDataMap = make(map[string]float64)
  636. for _, v := range dataList {
  637. currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  638. if minDate.IsZero() || currDate.Before(minDate) {
  639. minDate = currDate
  640. }
  641. if maxDate.IsZero() || currDate.After(maxDate) {
  642. maxDate = currDate
  643. }
  644. dateMap[currDate] = v.Value
  645. }
  646. newDateMap := make(map[time.Time]float64)
  647. for currDate, value := range dateMap {
  648. newDate := currDate.AddDate(0, 0, moveDay)
  649. newDateMap[newDate] = value
  650. }
  651. minDate = minDate.AddDate(0, 0, moveDay)
  652. maxDate = maxDate.AddDate(0, 0, moveDay)
  653. dayNum := utils.GetTimeSubDay(minDate, maxDate)
  654. for i := 0; i <= dayNum; i++ {
  655. currDate := minDate.AddDate(0, 0, i)
  656. tmpValue, ok := newDateMap[currDate]
  657. if !ok {
  658. if len(newDataList) <= 0 {
  659. continue
  660. }
  661. tmpValue = newDataList[len(newDataList)-1].Value
  662. }
  663. tmpData := EdbInfoSearchData{
  664. DataTime: currDate.Format(utils.FormatDate),
  665. Value: tmpValue,
  666. }
  667. dateDataMap[tmpData.DataTime] = tmpData.Value
  668. newDataList = append(newDataList, tmpData)
  669. }
  670. return
  671. }