edb_data.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. package data
  2. import (
  3. "errors"
  4. "eta/eta_hub/models/data_manage"
  5. "eta/eta_hub/models/mgo"
  6. "eta/eta_hub/utils"
  7. "fmt"
  8. "github.com/shopspring/decimal"
  9. "go.mongodb.org/mongo-driver/bson"
  10. "time"
  11. )
  12. // GetEdbDataTbz 获取指标的同比值数据
  13. func GetEdbDataTbz(edbInfo *data_manage.EdbInfo, tmpDataList []*data_manage.EdbDataList, startDateTime time.Time) (dataList []*data_manage.EdbDataList, minValue, maxValue float64, err error) {
  14. dataList = make([]*data_manage.EdbDataList, 0)
  15. // 数据处理
  16. var dateArr []string
  17. dataMap := make(map[string]*data_manage.EdbDataList)
  18. for _, v := range tmpDataList {
  19. dateArr = append(dateArr, v.DataTime)
  20. dataMap[v.DataTime] = v
  21. }
  22. for _, av := range dateArr {
  23. currentItem, ok := dataMap[av]
  24. // 如果找不到当前日期的数据,那么终止当前循环,进入下一循环
  25. if !ok {
  26. continue
  27. }
  28. tmpItem := *currentItem
  29. var isOk bool //是否计算出来结果
  30. //当前日期
  31. currentDate, tmpErr := time.ParseInLocation(utils.FormatDate, av, time.Local)
  32. if tmpErr != nil {
  33. err = tmpErr
  34. return
  35. }
  36. // 如果存在开始日期,同时,当前日期早于开始日期,那么终止当前循环,进入下一循环
  37. if !startDateTime.IsZero() && currentDate.Before(startDateTime) {
  38. continue
  39. }
  40. //上一年的日期
  41. preDate := currentDate.AddDate(-1, 0, 0)
  42. preDateStr := preDate.Format(utils.FormatDate)
  43. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
  44. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  45. isOk = true
  46. } else {
  47. if edbInfo.Frequency == "月度" { //向上和向下,各找一个月
  48. for i := 0; i <= 35; i++ {
  49. nextDateDay := preDate.AddDate(0, 0, i)
  50. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  51. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  52. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  53. isOk = true
  54. break
  55. } else {
  56. preDateDay := preDate.AddDate(0, 0, -i)
  57. preDateDayStr := preDateDay.Format(utils.FormatDate)
  58. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  59. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  60. isOk = true
  61. break
  62. }
  63. }
  64. }
  65. } else if edbInfo.Frequency == "季度" || edbInfo.Frequency == "年度" {
  66. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
  67. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  68. isOk = true
  69. break
  70. }
  71. } else {
  72. nextDateDay := preDate.AddDate(0, 0, 1)
  73. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  74. preDateDay := preDate.AddDate(0, 0, -1)
  75. preDateDayStr := preDateDay.Format(utils.FormatDate)
  76. for i := 0; i < 35; i++ {
  77. if i >= 1 {
  78. nextDateDay = nextDateDay.AddDate(0, 0, i)
  79. nextDateDayStr = nextDateDay.Format(utils.FormatDate)
  80. }
  81. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  82. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  83. isOk = true
  84. break
  85. } else {
  86. if i >= 1 {
  87. preDateDay = preDate.AddDate(0, 0, -i)
  88. preDateDayStr = nextDateDay.Format(utils.FormatDate)
  89. }
  90. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  91. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  92. isOk = true
  93. break
  94. }
  95. }
  96. }
  97. }
  98. }
  99. if isOk {
  100. if tmpItem.Value > maxValue {
  101. maxValue = tmpItem.Value
  102. }
  103. if tmpItem.Value < minValue {
  104. minValue = tmpItem.Value
  105. }
  106. dataList = append(dataList, &tmpItem)
  107. }
  108. }
  109. return
  110. }
  111. // GetChartEdbSeasonalData 获取指标的季节性数据
  112. func GetChartEdbSeasonalData(calendar, startDate string, edbInfo *data_manage.EdbInfo) (resultData interface{}, err error) {
  113. var startDateReal string
  114. startDateReal = startDate
  115. calendarPreYear := 0
  116. if calendar == "农历" {
  117. newStartDateReal, tmpErr := time.Parse(utils.FormatDate, startDateReal)
  118. if tmpErr != nil {
  119. err = tmpErr
  120. fmt.Println("time.Parse:" + err.Error())
  121. return
  122. }
  123. calendarPreYear = newStartDateReal.Year() - 1
  124. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  125. startDateReal = newStartDateReal.Format(utils.FormatDate)
  126. }
  127. dataList, err := GetEdbDataList(edbInfo, startDateReal)
  128. if err != nil {
  129. err = fmt.Errorf("获取指标数据出错 Err:%s", err.Error())
  130. return
  131. }
  132. latestDateStr := edbInfo.LatestDate //实际数据的截止日期
  133. latestDate, tmpErr := time.Parse(utils.FormatDate, edbInfo.LatestDate)
  134. if tmpErr != nil {
  135. err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + edbInfo.LatestDate))
  136. return
  137. }
  138. latestDateYear := latestDate.Year() //实际数据截止年份
  139. if calendar == "农历" {
  140. if len(dataList) <= 0 {
  141. resultData = new(data_manage.EdbDataResult)
  142. } else {
  143. result, tmpErr := data_manage.AddCalculateQuarterV4(dataList)
  144. if tmpErr != nil {
  145. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  146. return
  147. }
  148. // 处理季节图的截止日期
  149. for k, edbDataItems := range result.List {
  150. var cuttingDataTimestamp int64
  151. // 切割的日期时间字符串
  152. cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
  153. //如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
  154. if edbDataItems.Year >= latestDateYear {
  155. for _, tmpData := range edbDataItems.Items {
  156. if tmpData.DataTime == cuttingDataTimeStr {
  157. cuttingDataTimestamp = tmpData.DataTimestamp
  158. break
  159. }
  160. }
  161. }
  162. edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
  163. result.List[k] = edbDataItems
  164. }
  165. //fmt.Println("result", result.List[0].Items[0].DataTime)
  166. //fmt.Println("calendarPreYear:", calendarPreYear)
  167. //fmt.Println("result.List[0].Year", result.List[0].Year)
  168. if result.List[0].Year != calendarPreYear {
  169. itemList := make([]*data_manage.EdbDataList, 0)
  170. items := new(data_manage.EdbDataItems)
  171. //items.Year = calendarPreYear
  172. items.Items = itemList
  173. newResult := new(data_manage.EdbDataResult)
  174. newResult.List = append(newResult.List, items)
  175. newResult.List = append(newResult.List, result.List...)
  176. resultData = newResult
  177. } else {
  178. resultData = result
  179. }
  180. }
  181. } else {
  182. currentYear := time.Now().Year()
  183. quarterDataList := make([]*data_manage.QuarterData, 0)
  184. quarterMap := make(map[int][]*data_manage.EdbDataList)
  185. var quarterArr []int
  186. for _, v := range dataList {
  187. itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
  188. if tmpErr != nil {
  189. err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
  190. return
  191. }
  192. year := itemDate.Year()
  193. newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
  194. timestamp := newItemDate.UnixNano() / 1e6
  195. v.DataTimestamp = timestamp
  196. if findVal, ok := quarterMap[year]; !ok {
  197. quarterArr = append(quarterArr, year)
  198. findVal = append(findVal, v)
  199. quarterMap[year] = findVal
  200. } else {
  201. findVal = append(findVal, v)
  202. quarterMap[year] = findVal
  203. }
  204. }
  205. for _, v := range quarterArr {
  206. itemList := quarterMap[v]
  207. quarterItem := new(data_manage.QuarterData)
  208. quarterItem.Year = v
  209. quarterItem.DataList = itemList
  210. //如果等于最后的实际日期,那么将切割时间戳记录
  211. if v == latestDateYear {
  212. var cuttingDataTimestamp int64
  213. for _, tmpData := range itemList {
  214. if tmpData.DataTime == latestDateStr {
  215. cuttingDataTimestamp = tmpData.DataTimestamp
  216. break
  217. }
  218. }
  219. quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
  220. } else if v > latestDateYear {
  221. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  222. if len(itemList) > 0 {
  223. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  224. }
  225. }
  226. quarterDataList = append(quarterDataList, quarterItem)
  227. }
  228. resultData = quarterDataList
  229. }
  230. return
  231. }
  232. // TbzDiv 同比值计算
  233. func TbzDiv(a, b float64) float64 {
  234. var valFloat float64
  235. if b != 0 {
  236. af := decimal.NewFromFloat(a)
  237. bf := decimal.NewFromFloat(b)
  238. val, _ := af.Div(bf).Float64()
  239. val = val - 1
  240. valFloat, _ = decimal.NewFromFloat(val).Round(4).Float64()
  241. } else {
  242. valFloat = 0
  243. }
  244. return valFloat
  245. }
  246. // GetEdbDataList 获取指标数据
  247. func GetEdbDataList(edbInfo *data_manage.EdbInfo, startDate string) (dataList []*data_manage.EdbDataList, err error) {
  248. var list []*data_manage.EdbData
  249. switch edbInfo.EdbInfoType {
  250. case 0:
  251. dataOb := new(data_manage.EdbData)
  252. list, err = dataOb.GetItemsBySourceAndCode(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, startDate, []string{}, "data_time ASC")
  253. //case 1:
  254. //_, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, startDate, endDate, false)
  255. default:
  256. err = errors.New(fmt.Sprint("获取失败,不支持预测指标", edbInfo.EdbInfoType))
  257. }
  258. if err != nil {
  259. return
  260. }
  261. if len(list) <= 0 {
  262. return
  263. }
  264. for _, v := range list {
  265. dataList = append(dataList, data_manage.FormatEdbData2List(v))
  266. }
  267. return
  268. }
  269. // GetPageBaseBusinessIndexData
  270. // @Description: 获取自有数据的分页数据
  271. // @author: Roc
  272. // @datetime 2024-05-07 11:02:51
  273. // @param indexCode int
  274. // @param startSize int
  275. // @param pageSize int
  276. // @return dataCount int
  277. // @return dataList []*data_manage.BaseFromBusinessIndexDataItem
  278. // @return err error
  279. func GetPageBaseBusinessIndexData(indexCode string, startSize, pageSize int) (dataCount int, dataList []*data_manage.BaseFromBusinessIndexDataItem, err error) {
  280. if utils.UseMongo {
  281. dataCount, dataList, err = getPageBaseBusinessIndexDataByMongo(indexCode, startSize, pageSize)
  282. } else {
  283. dataCount, dataList, err = getPageBaseBusinessIndexDataByMysql(indexCode, startSize, pageSize)
  284. }
  285. return
  286. }
  287. // getPageBaseBusinessIndexDataByMongo
  288. // @Description: 获取自有数据的分页数据(从mongo中获取)
  289. // @author: Roc
  290. // @datetime 2024-07-01 14:01:04
  291. // @param indexCode string
  292. // @param startSize int
  293. // @param pageSize int
  294. // @return dataCount int
  295. // @return dataList []*data_manage.BaseFromBusinessIndexDataItem
  296. // @return err error
  297. func getPageBaseBusinessIndexDataByMongo(indexCode string, startSize, pageSize int) (dataCount int, dataList []*data_manage.BaseFromBusinessIndexDataItem, err error) {
  298. dataList = make([]*data_manage.BaseFromBusinessIndexDataItem, 0)
  299. mogDataObj := mgo.BaseFromBusinessData{}
  300. // 构建查询条件
  301. queryConditions := bson.M{
  302. "index_code": indexCode,
  303. }
  304. // 获取数据总量
  305. tmpCount, tmpErr := mogDataObj.GetCountDataList(queryConditions)
  306. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  307. err = tmpErr
  308. return
  309. }
  310. dataCount = int(tmpCount)
  311. // 获取列表数据
  312. tmpDataList, tmpErr := mogDataObj.GetPageDataList(queryConditions, int64(startSize), int64(pageSize), []string{"-data_time"})
  313. if tmpErr != nil {
  314. err = tmpErr
  315. return
  316. }
  317. for _, v := range tmpDataList {
  318. dataList = append(dataList, &data_manage.BaseFromBusinessIndexDataItem{
  319. ID: v.ID.String(),
  320. IndexCode: v.IndexCode,
  321. DataTime: v.DataTime.Format(utils.FormatDate),
  322. Value: v.Value,
  323. })
  324. }
  325. return
  326. }
  327. // getPageBaseBusinessIndexDataByMysql
  328. // @Description: 获取自有数据的分页数据(从mysql中获取)
  329. // @author: Roc
  330. // @datetime 2024-07-01 14:00:41
  331. // @param indexCode string
  332. // @param startSize int
  333. // @param pageSize int
  334. // @return dataCount int
  335. // @return dataList []*data_manage.BaseFromBusinessIndexDataItem
  336. // @return err error
  337. func getPageBaseBusinessIndexDataByMysql(indexCode string, startSize, pageSize int) (dataCount int, dataList []*data_manage.BaseFromBusinessIndexDataItem, err error) {
  338. dataList = make([]*data_manage.BaseFromBusinessIndexDataItem, 0)
  339. businessDataObj := data_manage.BaseFromBusinessData{}
  340. var condition []string
  341. var pars []interface{}
  342. condition = append(condition, "index_code = ?")
  343. pars = append(pars, indexCode)
  344. // 获取数据总量
  345. tmpCount, tmpErr := businessDataObj.GetCountDataList(condition, pars)
  346. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  347. err = tmpErr
  348. return
  349. }
  350. dataCount = int(tmpCount)
  351. // 获取列表数据
  352. tmpDataList, tmpErr := businessDataObj.GetPageDataList(condition, pars, " data_time desc", int64(startSize), int64(pageSize))
  353. if tmpErr != nil {
  354. err = tmpErr
  355. return
  356. }
  357. for _, v := range tmpDataList {
  358. dataList = append(dataList, &data_manage.BaseFromBusinessIndexDataItem{
  359. ID: fmt.Sprint(v.BusinessDataId),
  360. IndexCode: v.IndexCode,
  361. DataTime: v.DataTime.Format(utils.FormatDate),
  362. Value: v.Value,
  363. })
  364. }
  365. return
  366. }