edb_data_calculate_qjjs.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  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. "math"
  11. "strconv"
  12. "strings"
  13. "time"
  14. )
  15. type CalculateRangeAnalysis struct {
  16. }
  17. type RangeAnalysisCalculateFormula struct {
  18. DateRangeType int `description:"区间划分类型 0:智能划分,1:手工划分,2:跨年划分"`
  19. AutoDateConf ChartRangeAnalysisAutoDateConf `description:"智能划分时间区间配置"`
  20. ManualDateConf []ChartRangeAnalysisManualDateConf `description:"手工划分时间区间配置"`
  21. YearDateConf ChartRangeAnalysisYearDateConf `description:"跨年划分时间区间配置"`
  22. CalculateType int `description:"计算类型 0: 区间均值,1: 区间累计值,2:区间涨幅,3:区间年化增长率,4:区间最大值,5:区间最小值"`
  23. UnNormalDataDealType int `description:"异常值处理配置 0:不处理,1:剔除,2替换"`
  24. UnNormalDataConf ChartRangeAnalysisDeleteDataConf
  25. DataConvertType int `description:"数据转换类型 0不转, 1乘 2除 3对数"`
  26. DataConvertConf ChartRangeAnalysisDataConvertConf `description:"数据转换详情"`
  27. }
  28. type ChartRangeAnalysisAutoDateConf struct { //智能划分
  29. IsAutoStartDate int `description:"起始日期是否是动态设置:0固定,1动态"`
  30. StartDate string `description:"起始日期"` //固定模式下,截止日期为指标的最新日期
  31. EndDate string `description:"固定模式下的截止日期"`
  32. IsAutoEndDate int `description:"截止日期是否是动态设置:0固定,1动态"`
  33. StartDateConf ChartRangeAnalysisAutoDateChangeConf `description:"动态起始日期配置"`
  34. EndDateConf ChartRangeAnalysisAutoDateChangeConf `description:"动态截止日期配置"`
  35. }
  36. type ChartRangeAnalysisAutoDateChangeConf struct {
  37. BaseDateType int `description:"基准日期类型:0指标日期,1系统日期,2固定日期"`
  38. MoveForward int `description:"前移的期数"`
  39. DateChange []*EdbDataDateChangeConf
  40. }
  41. type EdbDataDateChangeConf struct {
  42. Year int
  43. Month int
  44. Day int
  45. Frequency string `description:"频度变换"`
  46. FrequencyDay string `description:"频度的固定日期"`
  47. ChangeType int `description:"日期变换类型1日期位移,2指定频率"`
  48. }
  49. type ChartRangeAnalysisManualDateConf struct { //手工划分
  50. StartDate string `description:"开始日期"`
  51. EndDate string `description:"结束日期"`
  52. }
  53. type ChartRangeAnalysisYearDateConf struct {
  54. StartDay string `description:"开始日"`
  55. EndDay string `description:"结束日"`
  56. }
  57. type ChartRangeAnalysisDeleteDataConf struct {
  58. Formula string
  59. Value float64
  60. ReplaceValue float64 `description:"替换的值"`
  61. }
  62. type ChartRangeAnalysisDataConvertConf struct {
  63. Value float64 `description:"数据转换值"`
  64. Unit string `description:"数据转换单位"`
  65. EnUnit string `description:"数据转换单位"`
  66. }
  67. type ChartRangeAnalysisDateDataItem struct {
  68. StartDate time.Time
  69. EndDate time.Time
  70. DataList []*EdbInfoSearchData
  71. }
  72. func (obj CalculateRangeAnalysis) Add(params AddCalculateBatchParams) (edbInfo *EdbInfo, err error, errMsg string) {
  73. req := params.Req
  74. edbCode := params.EdbCode
  75. uniqueCode := params.UniqueCode
  76. sysUserId := params.SysUserId
  77. sysUserRealName := params.SysUserRealName
  78. to := global.DEFAULT_DmSQL.Begin()
  79. defer func() {
  80. if err != nil {
  81. to.Rollback()
  82. } else {
  83. to.Commit()
  84. }
  85. }()
  86. if req.EdbInfoId > 0 {
  87. err = errors.New("无法新增")
  88. return
  89. }
  90. edbInfo = new(EdbInfo)
  91. edbInfo.Source = obj.GetSource()
  92. edbInfo.SourceName = obj.GetSourceName()
  93. edbInfo.EdbCode = edbCode
  94. edbInfo.EdbName = req.EdbName
  95. edbInfo.EdbNameSource = req.EdbName
  96. edbInfo.Frequency = req.Frequency
  97. edbInfo.Unit = req.Unit
  98. edbInfo.ClassifyId = req.ClassifyId
  99. edbInfo.SysUserId = sysUserId
  100. edbInfo.SysUserRealName = sysUserRealName
  101. edbInfo.CreateTime = time.Now()
  102. edbInfo.ModifyTime = time.Now()
  103. edbInfo.UniqueCode = uniqueCode
  104. edbInfo.CalculateFormula = req.CalculateFormula
  105. edbInfo.EdbNameEn = req.EdbName
  106. edbInfo.UnitEn = req.Unit
  107. edbInfo.EdbType = obj.GetEdbType()
  108. tmpErr := to.Create(edbInfo).Error
  109. if tmpErr != nil {
  110. err = tmpErr
  111. return
  112. }
  113. fromEdbInfo, e := GetEdbInfoById(req.FromEdbInfoId)
  114. if e != nil {
  115. err = fmt.Errorf("获取来源指标失败,Err:%s", e.Error())
  116. return
  117. }
  118. calculateMappingItem := new(EdbInfoCalculateMapping)
  119. calculateMappingItem.CreateTime = time.Now()
  120. calculateMappingItem.ModifyTime = time.Now()
  121. calculateMappingItem.Sort = 1
  122. calculateMappingItem.EdbCode = edbCode
  123. calculateMappingItem.EdbInfoId = edbInfo.EdbInfoId
  124. calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
  125. calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
  126. calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
  127. calculateMappingItem.FromSource = fromEdbInfo.Source
  128. calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
  129. calculateMappingItem.FromTag = ""
  130. calculateMappingItem.Source = edbInfo.Source
  131. calculateMappingItem.SourceName = edbInfo.SourceName
  132. calculateMappingItem.FromSubSource = edbInfo.SubSource
  133. err = to.Create(calculateMappingItem).Error
  134. if err != nil {
  135. return
  136. }
  137. err, errMsg = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, fromEdbInfo, edbInfo.EdbCode, edbInfo.CalculateFormula)
  138. return
  139. }
  140. func (obj CalculateRangeAnalysis) Edit(params EditCalculateBatchParams) (err error, errMsg string) {
  141. edbInfo := params.EdbInfo
  142. req := params.Req
  143. to := global.DEFAULT_DmSQL.Begin()
  144. defer func() {
  145. if err != nil {
  146. to.Rollback()
  147. } else {
  148. to.Commit()
  149. }
  150. }()
  151. edbInfo.EdbName = req.EdbName
  152. edbInfo.EdbNameSource = req.EdbName
  153. edbInfo.Frequency = req.Frequency
  154. edbInfo.Unit = req.Unit
  155. edbInfo.ClassifyId = req.ClassifyId
  156. edbInfo.CalculateFormula = req.CalculateFormula
  157. edbInfo.EdbNameEn = req.EdbNameEn
  158. edbInfo.UnitEn = req.UnitEn
  159. edbInfo.ModifyTime = time.Now()
  160. err = to.Model(edbInfo).Select([]string{"EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "CalculateFormula", "ModifyTime", "EdbNameEn", "UnitEn"}).Updates(edbInfo).Error
  161. if err != nil {
  162. return
  163. }
  164. sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
  165. err = to.Exec(sql, edbInfo.EdbInfoId).Error
  166. if err != nil {
  167. err = errors.New("删除计算指标关联关系失败,Err:" + err.Error())
  168. return
  169. }
  170. tableName := GetEdbDataTableName(edbInfo.Source, edbInfo.SubSource)
  171. sql = ` DELETE FROM ` + tableName + ` WHERE edb_info_id = ? `
  172. err = to.Exec(sql, edbInfo.EdbInfoId).Error
  173. if err != nil {
  174. return
  175. }
  176. fromEdbInfo, e := GetEdbInfoById(req.FromEdbInfoId)
  177. if e != nil {
  178. err = fmt.Errorf("获取来源指标失败,Err:%s", e.Error())
  179. return
  180. }
  181. calculateMappingItem := new(EdbInfoCalculateMapping)
  182. calculateMappingItem.CreateTime = time.Now()
  183. calculateMappingItem.ModifyTime = time.Now()
  184. calculateMappingItem.Sort = 1
  185. calculateMappingItem.EdbCode = edbInfo.EdbCode
  186. calculateMappingItem.EdbInfoId = edbInfo.EdbInfoId
  187. calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
  188. calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
  189. calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
  190. calculateMappingItem.FromSource = fromEdbInfo.Source
  191. calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
  192. calculateMappingItem.FromTag = ""
  193. calculateMappingItem.Source = edbInfo.Source
  194. calculateMappingItem.SourceName = edbInfo.SourceName
  195. calculateMappingItem.FromSubSource = edbInfo.SubSource
  196. err = to.Create(calculateMappingItem).Error
  197. if err != nil {
  198. return
  199. }
  200. err, errMsg = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, fromEdbInfo, edbInfo.EdbCode, edbInfo.CalculateFormula)
  201. return
  202. }
  203. func (obj CalculateRangeAnalysis) Refresh(params RefreshParams) (err error, errMsg string) {
  204. edbInfo := params.EdbInfo
  205. edbInfoCalculateDetailList, err := GetEdbInfoCalculateDetailList(edbInfo.EdbInfoId)
  206. if err != nil {
  207. return
  208. }
  209. var fromEdbInfo *EdbInfo
  210. for _, v := range edbInfoCalculateDetailList {
  211. fromEdbInfo, _ = GetEdbInfoById(v.FromEdbInfoId)
  212. break
  213. }
  214. if fromEdbInfo == nil {
  215. errMsg = "指标异常"
  216. err = errors.New(errMsg)
  217. return
  218. }
  219. to := global.DEFAULT_DmSQL.Begin()
  220. defer func() {
  221. if err != nil {
  222. to.Rollback()
  223. } else {
  224. to.Commit()
  225. }
  226. }()
  227. err, errMsg = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, fromEdbInfo, edbInfo.EdbCode, edbInfo.CalculateFormula)
  228. return
  229. }
  230. func (obj CalculateRangeAnalysis) refresh(to *gorm.DB, edbInfoId, source, subSource int, fromEdbInfo *EdbInfo, edbCode, calculateFormula string) (err error, errMsg string) {
  231. edbInfoIdStr := strconv.Itoa(edbInfoId)
  232. tableName := GetEdbDataTableName(obj.GetSource(), utils.DATA_SUB_SOURCE_EDB)
  233. existDataList, err := GetAllEdbDataListByTo(to, edbInfoId, source, subSource)
  234. if err != nil {
  235. return
  236. }
  237. existDataMap := make(map[string]*EdbData, 0)
  238. removeDateMap := make(map[string]string)
  239. for _, v := range existDataList {
  240. existDataMap[v.DataTime] = v
  241. removeDateMap[v.DataTime] = ``
  242. }
  243. var rangeAnalysisConf RangeAnalysisCalculateFormula
  244. err = json.Unmarshal([]byte(calculateFormula), &rangeAnalysisConf)
  245. if err != nil {
  246. err = fmt.Errorf("解析区间计算公式失败 %s", err.Error())
  247. return
  248. }
  249. rangeAnalysisChartData, err := GetRangeAnalysisChartDataByEdbInfo(fromEdbInfo, rangeAnalysisConf)
  250. if err != nil {
  251. err = fmt.Errorf("获取区间计算数据失败 %s", err.Error())
  252. return
  253. }
  254. addSql := ` INSERT INTO ` + tableName + ` (edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
  255. var isAdd bool
  256. for _, item := range rangeAnalysisChartData {
  257. currDateStr := item.DataTime
  258. currVal := item.Value
  259. if existData, ok := existDataMap[currDateStr]; ok {
  260. existValStr := existData.Value
  261. existValDeci, tmpErr := decimal.NewFromString(existValStr)
  262. if tmpErr != nil {
  263. err = tmpErr
  264. return
  265. }
  266. existVal, _ := existValDeci.Round(4).Float64()
  267. if existVal != currVal {
  268. err = ModifyEdbDataById(source, subSource, existData.EdbDataId, fmt.Sprint(currVal))
  269. if err != nil {
  270. return
  271. }
  272. }
  273. } else {
  274. timestamp := item.DataTimestamp
  275. timestampStr := fmt.Sprintf("%d", timestamp)
  276. addSql += GetAddSql(edbInfoIdStr, edbCode, currDateStr, timestampStr, fmt.Sprint(currVal))
  277. isAdd = true
  278. }
  279. delete(removeDateMap, currDateStr)
  280. }
  281. {
  282. if isAdd {
  283. addSql = strings.TrimRight(addSql, ",")
  284. err = to.Exec(addSql).Error
  285. }
  286. if len(removeDateMap) > 0 {
  287. removeDateList := make([]string, 0) //需要移除的日期
  288. for k := range removeDateMap {
  289. removeDateList = append(removeDateList, k)
  290. }
  291. removeDateStr := strings.Join(removeDateList, `","`)
  292. removeDateStr = `"` + removeDateStr + `"`
  293. sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (%s) `, tableName, removeDateStr)
  294. err = to.Exec(sql, edbInfoId).Error
  295. if err != nil {
  296. err = fmt.Errorf("删除扩散指数指标数据失败,Err:" + err.Error())
  297. return
  298. }
  299. }
  300. }
  301. return
  302. }
  303. func GetAutoCalculateDateDataList(currentDate string, dataList []*EdbInfoSearchData, req RangeAnalysisCalculateFormula) (newDataList []*EdbInfoSearchData, err error) {
  304. currentDateTime, _ := time.ParseInLocation(utils.FormatDate, currentDate, time.Local)
  305. switch req.DateRangeType {
  306. case 0:
  307. var startDateTime time.Time
  308. if req.AutoDateConf.IsAutoStartDate == 0 { //固定设置
  309. startDate := req.AutoDateConf.StartDate
  310. if startDate == "" {
  311. startDate = "2020-01-01"
  312. }
  313. startDateTime, _ = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  314. } else {
  315. startConf := req.AutoDateConf.StartDateConf
  316. startDate := ""
  317. if startConf.BaseDateType == 0 { //
  318. startDate = currentDate
  319. } else if startConf.BaseDateType == 1 {
  320. startDate = time.Now().Format(utils.FormatDate)
  321. }
  322. if startConf.MoveForward > 0 {
  323. startDate = GetEdbDateByMoveForward(startDate, startConf.MoveForward, dataList)
  324. }
  325. if len(startConf.DateChange) > 0 {
  326. startDate, err = HandleEdbDateChange(startDate, startConf.DateChange)
  327. if err != nil {
  328. err = fmt.Errorf("智能划分开始日期处理失败:%s", err.Error())
  329. return
  330. }
  331. }
  332. startDateTime, _ = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  333. }
  334. var calStartTime, calEndTime time.Time
  335. if currentDateTime.Before(startDateTime) {
  336. calStartTime = currentDateTime
  337. calEndTime = startDateTime
  338. } else {
  339. calStartTime = startDateTime
  340. calEndTime = currentDateTime
  341. }
  342. for _, vv := range dataList {
  343. dataTimeT, _ := time.ParseInLocation(utils.FormatDate, vv.DataTime, time.Local)
  344. if dataTimeT.After(calStartTime) && dataTimeT.Before(calEndTime) ||
  345. dataTimeT.Equal(calStartTime) ||
  346. dataTimeT.Equal(calEndTime) {
  347. newDataList = append(newDataList, vv)
  348. }
  349. }
  350. }
  351. return
  352. }
  353. func HandleRangeAnalysisDataByCalculateType(originList []*ChartRangeAnalysisDateDataItem, originDataList []*EdbInfoSearchData, req RangeAnalysisCalculateFormula) (newList []*EdbInfoSearchData, err error) {
  354. if len(originList) == 0 {
  355. return
  356. }
  357. calculateType := req.CalculateType
  358. switch calculateType {
  359. case 0: //均值
  360. var sum float64
  361. if req.DateRangeType == 0 && req.AutoDateConf.IsAutoStartDate > 0 {
  362. for _, item := range originList {
  363. for _, v := range item.DataList {
  364. sum = 0
  365. calDataList, e := GetAutoCalculateDateDataList(v.DataTime, originDataList, req)
  366. if e != nil {
  367. err = fmt.Errorf("获取区间数据失败:%s", e.Error())
  368. return
  369. }
  370. for _, vv := range calDataList {
  371. sum += vv.Value
  372. }
  373. val := sum / float64(len(calDataList))
  374. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  375. newList = append(newList, &EdbInfoSearchData{
  376. DataTime: v.DataTime,
  377. Value: val,
  378. DataTimestamp: v.DataTimestamp,
  379. })
  380. }
  381. }
  382. } else {
  383. for _, item := range originList {
  384. sum = 0
  385. for k, v := range item.DataList {
  386. sum += v.Value
  387. val := sum / float64(k+1)
  388. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  389. newList = append(newList, &EdbInfoSearchData{
  390. DataTime: v.DataTime,
  391. Value: val,
  392. DataTimestamp: v.DataTimestamp,
  393. })
  394. }
  395. }
  396. }
  397. case 1: //累计值
  398. var sum float64
  399. if req.DateRangeType == 0 && req.AutoDateConf.IsAutoStartDate > 0 {
  400. for _, item := range originList {
  401. sum = 0
  402. for _, v := range item.DataList {
  403. sum = 0
  404. calDataList, e := GetAutoCalculateDateDataList(v.DataTime, originDataList, req)
  405. if e != nil {
  406. err = fmt.Errorf("获取区间数据失败:%s", e.Error())
  407. return
  408. }
  409. for _, vv := range calDataList {
  410. sum += vv.Value
  411. }
  412. val := sum
  413. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  414. newList = append(newList, &EdbInfoSearchData{
  415. DataTime: v.DataTime,
  416. Value: val,
  417. DataTimestamp: v.DataTimestamp,
  418. })
  419. }
  420. }
  421. } else {
  422. for _, item := range originList {
  423. sum = 0
  424. for _, v := range item.DataList {
  425. sum += v.Value
  426. val := sum
  427. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  428. newList = append(newList, &EdbInfoSearchData{
  429. DataTime: v.DataTime,
  430. Value: val,
  431. DataTimestamp: v.DataTimestamp,
  432. })
  433. }
  434. }
  435. }
  436. case 2: //涨幅
  437. if req.DateRangeType == 0 && req.AutoDateConf.IsAutoStartDate > 0 {
  438. for _, item := range originList {
  439. for _, v := range item.DataList {
  440. var baseVal float64
  441. calDataList, e := GetAutoCalculateDateDataList(v.DataTime, originDataList, req)
  442. if e != nil {
  443. err = fmt.Errorf("获取区间数据失败:%s", e.Error())
  444. return
  445. }
  446. if len(calDataList) == 0 {
  447. continue
  448. }
  449. baseVal = calDataList[0].Value
  450. baseDate := calDataList[0].DataTime
  451. if baseVal == 0 {
  452. continue
  453. }
  454. if v.DataTime == baseDate {
  455. continue
  456. }
  457. val := (v.Value - baseVal) / baseVal
  458. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  459. newList = append(newList, &EdbInfoSearchData{
  460. DataTime: v.DataTime,
  461. Value: val,
  462. DataTimestamp: v.DataTimestamp,
  463. })
  464. }
  465. }
  466. } else {
  467. for _, item := range originList {
  468. if len(item.DataList) == 0 {
  469. break
  470. }
  471. baseVal := item.DataList[0].Value
  472. baseDate := item.DataList[0].DataTime
  473. if baseVal == 0 {
  474. break
  475. }
  476. for _, v := range item.DataList {
  477. if v.DataTime == baseDate {
  478. continue
  479. }
  480. val := (v.Value - baseVal) / baseVal
  481. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  482. newList = append(newList, &EdbInfoSearchData{
  483. DataTime: v.DataTime,
  484. Value: val,
  485. DataTimestamp: v.DataTimestamp,
  486. })
  487. }
  488. }
  489. }
  490. case 3: //复合增长率
  491. if req.DateRangeType == 0 && req.AutoDateConf.IsAutoStartDate > 0 {
  492. for _, item := range originList {
  493. for _, v := range item.DataList {
  494. var baseVal float64
  495. var baseDate string
  496. calDataList, e := GetAutoCalculateDateDataList(v.DataTime, originDataList, req)
  497. if e != nil {
  498. err = fmt.Errorf("获取区间数据失败:%s", e.Error())
  499. return
  500. }
  501. if len(calDataList) == 0 {
  502. continue
  503. }
  504. baseVal = calDataList[0].Value
  505. baseDate = calDataList[0].DataTime
  506. if v.DataTime == baseDate {
  507. continue
  508. }
  509. if baseVal == 0 {
  510. continue
  511. }
  512. baseDateT, e := time.ParseInLocation(utils.FormatDate, baseDate, time.Local)
  513. if e != nil {
  514. err = fmt.Errorf("time.ParseInLocation err: %v", e)
  515. return
  516. }
  517. tmpT, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  518. if e != nil {
  519. err = fmt.Errorf("time.ParseInLocation err: %v", e)
  520. return
  521. }
  522. diff := tmpT.Sub(baseDateT).Hours() / 24 / 365
  523. val := v.Value / baseVal
  524. val = math.Pow(val, 1/diff) - 1
  525. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  526. newList = append(newList, &EdbInfoSearchData{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  527. }
  528. }
  529. } else {
  530. for _, item := range originList {
  531. if len(item.DataList) == 0 {
  532. break
  533. }
  534. baseVal := item.DataList[0].Value
  535. baseDate := item.DataList[0].DataTime
  536. if baseVal == 0 {
  537. break
  538. }
  539. for _, v := range item.DataList {
  540. if v.DataTime == baseDate {
  541. continue
  542. }
  543. baseDateT, e := time.ParseInLocation(utils.FormatDate, baseDate, time.Local)
  544. if e != nil {
  545. err = fmt.Errorf("time.ParseInLocation err: %v", e)
  546. return
  547. }
  548. tmpT, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  549. if e != nil {
  550. err = fmt.Errorf("time.ParseInLocation err: %v", e)
  551. return
  552. }
  553. diff := tmpT.Sub(baseDateT).Hours() / 24 / 365
  554. val := v.Value / baseVal
  555. val = math.Pow(val, 1/diff) - 1
  556. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  557. newList = append(newList, &EdbInfoSearchData{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  558. }
  559. }
  560. }
  561. case 4: //最大值
  562. var maxVal float64
  563. if req.DateRangeType == 0 && req.AutoDateConf.IsAutoStartDate > 0 {
  564. for _, item := range originList {
  565. for _, v := range item.DataList {
  566. calDataList, e := GetAutoCalculateDateDataList(v.DataTime, originDataList, req)
  567. if e != nil {
  568. err = fmt.Errorf("获取区间数据失败:%s", e.Error())
  569. return
  570. }
  571. for kk, vv := range calDataList {
  572. if kk == 0 {
  573. maxVal = vv.Value
  574. }
  575. if vv.Value > maxVal {
  576. maxVal = vv.Value
  577. }
  578. }
  579. val := maxVal
  580. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  581. newList = append(newList, &EdbInfoSearchData{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  582. }
  583. }
  584. } else {
  585. for _, item := range originList {
  586. for k, v := range item.DataList {
  587. if k == 0 {
  588. maxVal = v.Value
  589. }
  590. if v.Value > maxVal {
  591. maxVal = v.Value
  592. }
  593. val := maxVal
  594. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  595. newList = append(newList, &EdbInfoSearchData{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  596. }
  597. }
  598. }
  599. case 5: //最小值
  600. var minVal float64
  601. if req.DateRangeType == 0 && req.AutoDateConf.IsAutoStartDate > 0 {
  602. for _, item := range originList {
  603. for _, v := range item.DataList {
  604. calDataList, e := GetAutoCalculateDateDataList(v.DataTime, originDataList, req)
  605. if e != nil {
  606. err = fmt.Errorf("获取区间数据失败:%s", e.Error())
  607. return
  608. }
  609. for kk, vv := range calDataList {
  610. if kk == 0 {
  611. minVal = vv.Value
  612. }
  613. if vv.Value < minVal {
  614. minVal = vv.Value
  615. }
  616. }
  617. val := minVal
  618. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  619. newList = append(newList, &EdbInfoSearchData{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  620. }
  621. }
  622. } else {
  623. for _, item := range originList {
  624. for k, v := range item.DataList {
  625. if k == 0 {
  626. minVal = v.Value
  627. }
  628. if v.Value < minVal {
  629. minVal = v.Value
  630. }
  631. val := minVal
  632. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  633. newList = append(newList, &EdbInfoSearchData{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  634. }
  635. }
  636. }
  637. }
  638. return
  639. }
  640. func GetRangeAnalysisChartDataByEdbInfo(fromEdbInfo *EdbInfo, calculateFormula RangeAnalysisCalculateFormula) (newDataList []*EdbInfoSearchData, err error) {
  641. edbStartDateTime, _ := time.ParseInLocation(utils.FormatDate, fromEdbInfo.StartDate, time.Local)
  642. edbEndDateTime, _ := time.ParseInLocation(utils.FormatDate, fromEdbInfo.EndDate, time.Local)
  643. edbEndDate := edbEndDateTime.Format(utils.FormatDate)
  644. dataList := make([]*EdbInfoSearchData, 0)
  645. switch fromEdbInfo.EdbInfoType {
  646. case 0:
  647. dataList, err = GetEdbDataListAll(fromEdbInfo.Source, fromEdbInfo.SubSource,
  648. FindEdbDataListAllCond{
  649. EdbInfoId: fromEdbInfo.EdbInfoId,
  650. }, 1)
  651. case 1:
  652. dataList, err = GetPredictEdbDataListAllByStartDate(fromEdbInfo, 1, "")
  653. default:
  654. err = errors.New(fmt.Sprint("获取失败,指标base类型异常", fromEdbInfo.EdbInfoType))
  655. return
  656. }
  657. if err != nil {
  658. err = fmt.Errorf("获取时间基准指标在时间区间内的值失败,Err:" + err.Error())
  659. return
  660. }
  661. dateList := make([]*ChartRangeAnalysisDateDataItem, 0)
  662. switch calculateFormula.DateRangeType {
  663. case 0:
  664. var startDateTime, endDateTime time.Time
  665. startDateTime = edbStartDateTime
  666. if calculateFormula.AutoDateConf.IsAutoStartDate == 0 { //固定设置
  667. startDate := calculateFormula.AutoDateConf.StartDate
  668. if startDate == "" {
  669. startDate = "2020-01-01"
  670. }
  671. startDateTime, _ = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  672. }
  673. if calculateFormula.AutoDateConf.IsAutoEndDate == 0 { //固定设置
  674. endDate := calculateFormula.AutoDateConf.EndDate
  675. if endDate == "" {
  676. err = fmt.Errorf("智能划分截止日期处理失败:请输入截止日期")
  677. return
  678. }
  679. endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  680. } else {
  681. endConf := calculateFormula.AutoDateConf.EndDateConf
  682. endDate := edbEndDate
  683. if endConf.MoveForward > 0 {
  684. endDate = GetEdbDateByMoveForward(endDate, endConf.MoveForward, dataList)
  685. }
  686. if len(endConf.DateChange) > 0 {
  687. endDate, err = HandleEdbDateChange(endDate, endConf.DateChange)
  688. if err != nil {
  689. err = fmt.Errorf("智能划分结束日期处理失败:%s", err.Error())
  690. return
  691. }
  692. }
  693. endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  694. }
  695. dateList = append(dateList, &ChartRangeAnalysisDateDataItem{
  696. StartDate: startDateTime,
  697. EndDate: endDateTime})
  698. case 1:
  699. for _, v := range calculateFormula.ManualDateConf {
  700. startDateT, _ := time.ParseInLocation(utils.FormatDate, v.StartDate, time.Local)
  701. endDateT, _ := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  702. tmp := &ChartRangeAnalysisDateDataItem{
  703. StartDate: startDateT,
  704. EndDate: endDateT,
  705. }
  706. dateList = append(dateList, tmp)
  707. }
  708. case 2:
  709. startYear := edbStartDateTime.Year()
  710. endYear := edbEndDateTime.Year()
  711. startDay := calculateFormula.YearDateConf.StartDay
  712. endDay := calculateFormula.YearDateConf.EndDay
  713. for year := startYear; year <= endYear; year++ {
  714. startDate := fmt.Sprintf("%d-%s", year, startDay)
  715. endDate := fmt.Sprintf("%d-%s", year+1, endDay)
  716. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  717. endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  718. if startDateTime.Before(edbStartDateTime) {
  719. break
  720. }
  721. tmp := &ChartRangeAnalysisDateDataItem{
  722. StartDate: startDateTime,
  723. EndDate: endDateTime,
  724. }
  725. dateList = append(dateList, tmp)
  726. }
  727. }
  728. for _, v := range dateList {
  729. for _, vv := range dataList {
  730. dataTimeT, _ := time.ParseInLocation(utils.FormatDate, vv.DataTime, time.Local)
  731. if dataTimeT.After(v.StartDate) && dataTimeT.Before(v.EndDate) ||
  732. dataTimeT.Equal(v.StartDate) ||
  733. dataTimeT.Equal(v.EndDate) {
  734. v.DataList = append(v.DataList, vv)
  735. }
  736. }
  737. }
  738. newDataList, err = HandleRangeAnalysisDataByCalculateType(dateList, dataList, calculateFormula)
  739. if err != nil {
  740. return
  741. }
  742. if calculateFormula.UnNormalDataDealType > 0 {
  743. switch calculateFormula.UnNormalDataDealType { //0:不处理,1:剔除,2替换
  744. case 1:
  745. dealDataList := make([]*EdbInfoSearchData, 0)
  746. for _, v := range newDataList {
  747. if !utils.CompareFloatByOpStrings(calculateFormula.UnNormalDataConf.Formula, v.Value, calculateFormula.UnNormalDataConf.Value) {
  748. dealDataList = append(dealDataList, v)
  749. }
  750. }
  751. case 2:
  752. for i, v := range newDataList {
  753. if utils.CompareFloatByOpStrings(calculateFormula.UnNormalDataConf.Formula, v.Value, calculateFormula.UnNormalDataConf.Value) {
  754. newDataList[i].Value = calculateFormula.UnNormalDataConf.ReplaceValue
  755. }
  756. }
  757. }
  758. }
  759. if calculateFormula.DataConvertType > 0 {
  760. switch calculateFormula.DataConvertType {
  761. case 1:
  762. for i, v := range newDataList {
  763. val := v.Value * calculateFormula.DataConvertConf.Value
  764. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  765. newDataList[i].Value = val
  766. }
  767. case 2:
  768. for i, v := range newDataList {
  769. val := v.Value / calculateFormula.DataConvertConf.Value
  770. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  771. newDataList[i].Value = val
  772. }
  773. case 3:
  774. for i, v := range newDataList {
  775. if v.Value <= 0 {
  776. err = errors.New("数据中含有负数或0,无法对数运算")
  777. return
  778. }
  779. val := math.Log(v.Value) / math.Log(calculateFormula.DataConvertConf.Value)
  780. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  781. newDataList[i].Value = val
  782. }
  783. }
  784. }
  785. return
  786. }
  787. func GetEdbDateByMoveForward(startDate string, moveForward int, edbDataList []*EdbInfoSearchData) (date string) {
  788. index := 0
  789. length := len(edbDataList)
  790. for i := length - 1; i >= 0; i-- {
  791. item := edbDataList[i]
  792. if item.DataTime == startDate {
  793. index += 1
  794. continue
  795. }
  796. if index >= moveForward {
  797. date = item.DataTime
  798. break
  799. }
  800. if index > 0 {
  801. index += 1
  802. date = item.DataTime
  803. }
  804. }
  805. return
  806. }
  807. func HandleEdbDateChange(date string, dateChange []*EdbDataDateChangeConf) (newDate string, err error) {
  808. newDate = date
  809. if newDate != "" {
  810. if len(dateChange) > 0 {
  811. var dateTime time.Time
  812. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  813. if err != nil {
  814. err = fmt.Errorf("日期解析失败: %s", err.Error())
  815. return
  816. }
  817. for _, v := range dateChange {
  818. if v.ChangeType == 1 {
  819. dateTime = dateTime.AddDate(v.Year, v.Month, v.Day)
  820. newDate = dateTime.Format(utils.FormatDate)
  821. } else if v.ChangeType == 2 {
  822. newDate, err, _ = utils.HandleSystemAppointDateT(dateTime, v.FrequencyDay, v.Frequency)
  823. if err != nil {
  824. return
  825. }
  826. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  827. if err != nil {
  828. err = fmt.Errorf("日期解析失败: %s", err.Error())
  829. return
  830. }
  831. }
  832. }
  833. }
  834. }
  835. return
  836. }
  837. func (obj CalculateRangeAnalysis) GetSource() int {
  838. return utils.DATA_SOURCE_CALCULATE_RANGEANLYSIS
  839. }
  840. func (obj CalculateRangeAnalysis) GetSourceName() string {
  841. return utils.DATA_SOURCE_NAME_CALCULATE_RANGEANLYSIS
  842. }
  843. func (obj CalculateRangeAnalysis) GetEdbType() int {
  844. return utils.CALCULATE_EDB_TYPE
  845. }