edb_data.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. package data
  2. import (
  3. "errors"
  4. "eta/eta_api/models"
  5. "eta/eta_api/models/data_manage"
  6. "eta/eta_api/models/mgo"
  7. "eta/eta_api/utils"
  8. "eta/eta_api/utils/mgodb"
  9. "fmt"
  10. "github.com/shopspring/decimal"
  11. "go.mongodb.org/mongo-driver/bson"
  12. "time"
  13. )
  14. // EdbDataEdit 指标数据修改
  15. type EdbDataEdit struct {
  16. OldCreateDate string `description:"旧的录入日期"`
  17. CreateDate string `description:"新的录入日期"`
  18. TradeCode string `description:"指标唯一编码"`
  19. Close string `description:"录入值"`
  20. }
  21. // BatchEdbData 批量修改指标数据
  22. func BatchEdbData(oldCreateDate, createDate string, list []EdbDataEdit, opUserId int) (failEdbDataList []EdbDataEdit, err error) {
  23. if oldCreateDate == createDate { //修改
  24. err = errors.New("开始日期与结束日期一致!")
  25. return
  26. }
  27. for _, newEdbData := range list {
  28. edbdata := new(models.Edbdata)
  29. edbdata.TradeCode = newEdbData.TradeCode
  30. edbdata.Dt = newEdbData.CreateDate
  31. edbdata.Close = newEdbData.Close
  32. edbdata.ModifyTime = time.Now()
  33. item, err := models.GetDataInfo(newEdbData.TradeCode, createDate)
  34. if err != nil && err.Error() != utils.ErrNoRow() {
  35. failEdbDataList = append(failEdbDataList, newEdbData)
  36. continue
  37. }
  38. if item == nil {
  39. _, err = models.AddEdbdata(edbdata)
  40. if err != nil {
  41. failEdbDataList = append(failEdbDataList, newEdbData)
  42. continue
  43. }
  44. } else {
  45. err = models.EditEdbdata(edbdata)
  46. if err != nil {
  47. failEdbDataList = append(failEdbDataList, newEdbData)
  48. continue
  49. }
  50. }
  51. oldItem, err := models.GetDataInfo(newEdbData.TradeCode, oldCreateDate)
  52. if err != nil && err.Error() != utils.ErrNoRow() {
  53. failEdbDataList = append(failEdbDataList, newEdbData)
  54. continue
  55. }
  56. if oldItem != nil {
  57. record := new(models.EdbdataDeleteRecord)
  58. record.TradeCode = oldItem.TradeCode
  59. record.Dt = oldItem.Dt
  60. record.Close = oldItem.Close
  61. record.ModifyTime = oldItem.ModifyTime
  62. record.CreateTime = time.Now()
  63. record.SysUserId = opUserId
  64. _, err = models.AddEdbdataDeleteRecord(record)
  65. if err != nil {
  66. failEdbDataList = append(failEdbDataList, newEdbData)
  67. continue
  68. }
  69. //删除数据
  70. models.DeleteEdbData(newEdbData.TradeCode, newEdbData.OldCreateDate)
  71. }
  72. }
  73. return
  74. }
  75. // GetEdbDataTbz 获取指标的同比值数据
  76. func GetEdbDataTbz(edbInfo *data_manage.EdbInfo, tmpDataList []*data_manage.EdbDataList, startDateTime time.Time) (dataList []*data_manage.EdbDataList, minValue, maxValue float64, err error) {
  77. dataList = make([]*data_manage.EdbDataList, 0)
  78. // 数据处理
  79. var dateArr []string
  80. dataMap := make(map[string]*data_manage.EdbDataList)
  81. for _, v := range tmpDataList {
  82. dateArr = append(dateArr, v.DataTime)
  83. dataMap[v.DataTime] = v
  84. }
  85. for _, av := range dateArr {
  86. currentItem, ok := dataMap[av]
  87. // 如果找不到当前日期的数据,那么终止当前循环,进入下一循环
  88. if !ok {
  89. continue
  90. }
  91. tmpItem := *currentItem
  92. var isOk bool //是否计算出来结果
  93. //当前日期
  94. currentDate, tmpErr := time.ParseInLocation(utils.FormatDate, av, time.Local)
  95. if tmpErr != nil {
  96. err = tmpErr
  97. return
  98. }
  99. // 如果存在开始日期,同时,当前日期早于开始日期,那么终止当前循环,进入下一循环
  100. if !startDateTime.IsZero() && currentDate.Before(startDateTime) {
  101. continue
  102. }
  103. //上一年的日期
  104. preDate := currentDate.AddDate(-1, 0, 0)
  105. preDateStr := preDate.Format(utils.FormatDate)
  106. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
  107. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  108. isOk = true
  109. } else {
  110. if edbInfo.Frequency == "月度" { //向上和向下,各找一个月
  111. for i := 0; i <= 35; i++ {
  112. nextDateDay := preDate.AddDate(0, 0, i)
  113. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  114. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  115. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  116. isOk = true
  117. break
  118. } else {
  119. preDateDay := preDate.AddDate(0, 0, -i)
  120. preDateDayStr := preDateDay.Format(utils.FormatDate)
  121. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  122. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  123. isOk = true
  124. break
  125. }
  126. }
  127. }
  128. } else if edbInfo.Frequency == "季度" || edbInfo.Frequency == "年度" {
  129. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
  130. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  131. isOk = true
  132. break
  133. }
  134. } else {
  135. nextDateDay := preDate.AddDate(0, 0, 1)
  136. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  137. preDateDay := preDate.AddDate(0, 0, -1)
  138. preDateDayStr := preDateDay.Format(utils.FormatDate)
  139. for i := 0; i < 35; i++ {
  140. if i >= 1 {
  141. nextDateDay = nextDateDay.AddDate(0, 0, i)
  142. nextDateDayStr = nextDateDay.Format(utils.FormatDate)
  143. }
  144. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  145. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  146. isOk = true
  147. break
  148. } else {
  149. if i >= 1 {
  150. preDateDay = preDate.AddDate(0, 0, -i)
  151. preDateDayStr = nextDateDay.Format(utils.FormatDate)
  152. }
  153. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  154. tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
  155. isOk = true
  156. break
  157. }
  158. }
  159. }
  160. }
  161. }
  162. if isOk {
  163. if tmpItem.Value > maxValue {
  164. maxValue = tmpItem.Value
  165. }
  166. if tmpItem.Value < minValue {
  167. minValue = tmpItem.Value
  168. }
  169. dataList = append(dataList, &tmpItem)
  170. }
  171. }
  172. return
  173. }
  174. // GetChartEdbSeasonalData 获取指标的季节性数据
  175. func GetChartEdbSeasonalData(calendar, startDate, endDate string, edbInfo *data_manage.EdbInfo) (resultData interface{}, err error) {
  176. var startDateReal string
  177. startDateReal = startDate
  178. calendarPreYear := 0
  179. if calendar == "农历" {
  180. newStartDateReal, tmpErr := time.Parse(utils.FormatDate, startDateReal)
  181. if tmpErr != nil {
  182. err = tmpErr
  183. fmt.Println("time.Parse:" + err.Error())
  184. return
  185. }
  186. calendarPreYear = newStartDateReal.Year() - 1
  187. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  188. startDateReal = newStartDateReal.Format(utils.FormatDate)
  189. }
  190. dataList := make([]*data_manage.EdbDataList, 0)
  191. switch edbInfo.EdbInfoType {
  192. case 0:
  193. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDateReal, endDate)
  194. case 1:
  195. _, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, startDateReal, endDate, false)
  196. default:
  197. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  198. }
  199. if err != nil {
  200. return
  201. }
  202. latestDateStr := edbInfo.LatestDate //实际数据的截止日期
  203. latestDate, tmpErr := time.Parse(utils.FormatDate, edbInfo.LatestDate)
  204. if tmpErr != nil {
  205. err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + edbInfo.LatestDate))
  206. return
  207. }
  208. latestDateYear := latestDate.Year() //实际数据截止年份
  209. if calendar == "农历" {
  210. if len(dataList) <= 0 {
  211. resultData = new(data_manage.EdbDataResult)
  212. } else {
  213. result, tmpErr := data_manage.AddCalculateQuarterV4(dataList)
  214. if tmpErr != nil {
  215. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  216. return
  217. }
  218. // 处理季节图的截止日期
  219. for k, edbDataItems := range result.List {
  220. var cuttingDataTimestamp int64
  221. // 切割的日期时间字符串
  222. cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
  223. //如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
  224. if edbDataItems.Year >= latestDateYear {
  225. for _, tmpData := range edbDataItems.Items {
  226. if tmpData.DataTime == cuttingDataTimeStr {
  227. cuttingDataTimestamp = tmpData.DataTimestamp
  228. break
  229. }
  230. }
  231. }
  232. edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
  233. result.List[k] = edbDataItems
  234. }
  235. if result.List[0].Year != calendarPreYear {
  236. itemList := make([]*data_manage.EdbDataList, 0)
  237. items := new(data_manage.EdbDataItems)
  238. //items.Year = calendarPreYear
  239. items.Items = itemList
  240. newResult := new(data_manage.EdbDataResult)
  241. newResult.List = append(newResult.List, items)
  242. newResult.List = append(newResult.List, result.List...)
  243. resultData = newResult
  244. } else {
  245. resultData = result
  246. }
  247. }
  248. } else {
  249. currentYear := time.Now().Year()
  250. quarterDataList := make([]*data_manage.QuarterData, 0)
  251. quarterMap := make(map[int][]*data_manage.EdbDataList)
  252. var quarterArr []int
  253. for _, v := range dataList {
  254. itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
  255. if tmpErr != nil {
  256. err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
  257. return
  258. }
  259. year := itemDate.Year()
  260. newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
  261. timestamp := newItemDate.UnixNano() / 1e6
  262. v.DataTimestamp = timestamp
  263. if findVal, ok := quarterMap[year]; !ok {
  264. quarterArr = append(quarterArr, year)
  265. findVal = append(findVal, v)
  266. quarterMap[year] = findVal
  267. } else {
  268. findVal = append(findVal, v)
  269. quarterMap[year] = findVal
  270. }
  271. }
  272. for _, v := range quarterArr {
  273. itemList := quarterMap[v]
  274. quarterItem := new(data_manage.QuarterData)
  275. quarterItem.Year = v
  276. quarterItem.DataList = itemList
  277. //如果等于最后的实际日期,那么将切割时间戳记录
  278. if v == latestDateYear {
  279. var cuttingDataTimestamp int64
  280. for _, tmpData := range itemList {
  281. if tmpData.DataTime == latestDateStr {
  282. cuttingDataTimestamp = tmpData.DataTimestamp
  283. break
  284. }
  285. }
  286. quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
  287. } else if v > latestDateYear {
  288. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  289. if len(itemList) > 0 {
  290. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  291. }
  292. }
  293. quarterDataList = append(quarterDataList, quarterItem)
  294. }
  295. resultData = quarterDataList
  296. }
  297. return
  298. }
  299. // TbzDiv 同比值计算
  300. func TbzDiv(a, b float64) float64 {
  301. var valFloat float64
  302. if b != 0 {
  303. af := decimal.NewFromFloat(a)
  304. bf := decimal.NewFromFloat(b)
  305. val, _ := af.Div(bf).Float64()
  306. val = val - 1
  307. valFloat, _ = decimal.NewFromFloat(val).RoundCeil(4).Float64()
  308. } else {
  309. valFloat = 0
  310. }
  311. return valFloat
  312. }
  313. // GetDateData 获取指标的单个日期的值
  314. func GetDateData(edbInfo *data_manage.EdbInfo, startDate, endDate string) (item *data_manage.EdbDataList, err error) {
  315. var dataList []*data_manage.EdbDataList
  316. switch edbInfo.EdbInfoType {
  317. case 0:
  318. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDate, endDate)
  319. case 1:
  320. _, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, startDate, endDate, false)
  321. default:
  322. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  323. }
  324. if err != nil {
  325. return
  326. }
  327. if len(dataList) <= 0 {
  328. return
  329. }
  330. item = dataList[0]
  331. return
  332. }
  333. // GetEdbBeforeAndAfterDateData 获取指标的单个日期的值
  334. func GetEdbBeforeAndAfterDateData(targetDate string, dataList []*data_manage.EdbDataList) (list []*data_manage.EdbDataList, err error) {
  335. lenDataList := len(dataList)
  336. if lenDataList <= 0 {
  337. return
  338. }
  339. // 数组按照日期从小到大排序
  340. maxIndex := lenDataList - 1
  341. startIndex := 0
  342. endIndex := 0
  343. for index, v := range dataList {
  344. if v.DataTime == targetDate {
  345. if index+2 > maxIndex {
  346. endIndex = maxIndex
  347. } else if index+1 > maxIndex {
  348. endIndex = maxIndex
  349. } else {
  350. endIndex = index + 2
  351. }
  352. startIndex = endIndex - 4
  353. if startIndex < 0 {
  354. startIndex = 0
  355. }
  356. if endIndex == maxIndex {
  357. list = dataList[startIndex:]
  358. } else {
  359. list = dataList[startIndex : endIndex+1]
  360. }
  361. break
  362. }
  363. }
  364. return
  365. }
  366. // GetPageData
  367. // @Description: 获取指标的分页数据
  368. // @author: Roc
  369. // @datetime 2024-05-07 10:33:02
  370. // @param edbInfoId int
  371. // @param source int
  372. // @param subSource int
  373. // @param startSize int
  374. // @param pageSize int
  375. // @return dataCount int
  376. // @return dataList []*data_manage.EdbData
  377. // @return err error
  378. func GetPageData(edbInfoId, source, subSource int, endDataTime string, startSize, pageSize int) (dataCount int, dataList []*data_manage.EdbData, err error) {
  379. dataList = make([]*data_manage.EdbData, 0)
  380. // 自有数据需要额外处理(从mongo获取)
  381. if source == utils.DATA_SOURCE_BUSINESS {
  382. return getPageDataByMongo(edbInfoId, source, subSource, endDataTime, startSize, pageSize)
  383. }
  384. // 默认走mysql
  385. return getPageDataByMysql(edbInfoId, source, subSource, endDataTime, startSize, pageSize)
  386. }
  387. // getPageDataByMysql
  388. // @Description: 从Mysql获取数据
  389. // @author: Roc
  390. // @datetime 2024-05-07 15:08:41
  391. // @param edbInfoId int
  392. // @param source int
  393. // @param subSource int
  394. // @param endDataTime string
  395. // @param startSize int
  396. // @param pageSize int
  397. // @return dataCount int
  398. // @return dataList []*data_manage.EdbData
  399. // @return err error
  400. func getPageDataByMysql(edbInfoId, source, subSource int, endDataTime string, startSize, pageSize int) (dataCount int, dataList []*data_manage.EdbData, err error) {
  401. dataList = make([]*data_manage.EdbData, 0)
  402. var dataCondition string
  403. var dataPars []interface{}
  404. dataCondition += ` AND edb_info_id=? `
  405. dataPars = append(dataPars, edbInfoId)
  406. // 结束日期
  407. if endDataTime != "" {
  408. dataCondition += ` AND data_time <= ? `
  409. dataPars = append(dataPars, endDataTime)
  410. }
  411. // 获取数据总量
  412. dataCount, err = data_manage.GetEdbDataCountByCondition(dataCondition, dataPars, source, subSource)
  413. if err != nil && err.Error() != utils.ErrNoRow() {
  414. return
  415. }
  416. // 获取列表数据
  417. dataList, err = data_manage.GetEdbDataListByCondition(dataCondition, dataPars, source, subSource, pageSize, startSize)
  418. if err != nil {
  419. return
  420. }
  421. return
  422. }
  423. // getPageDataByMongo
  424. // @Description: 从MongoDB获取数据
  425. // @author: Roc
  426. // @datetime 2024-05-07 15:06:42
  427. // @param edbInfoId int
  428. // @param source int
  429. // @param subSource int
  430. // @param endDataTime string
  431. // @param startSize int
  432. // @param pageSize int
  433. // @return dataCount int
  434. // @return dataList []*data_manage.EdbData
  435. // @return err error
  436. func getPageDataByMongo(edbInfoId, source, subSource int, endDataTime string, startSize, pageSize int) (dataCount int, dataList []*data_manage.EdbData, err error) {
  437. dataList = make([]*data_manage.EdbData, 0)
  438. mogDataObj := mgo.EdbDataBusiness{}
  439. // 构建查询条件
  440. queryConditions := bson.M{
  441. "edb_info_id": edbInfoId,
  442. }
  443. // 结束日期
  444. dateCondition, err := mgodb.BuildDateCondition("", endDataTime)
  445. if err != nil {
  446. return
  447. }
  448. if len(dateCondition) > 0 {
  449. queryConditions["data_time"] = dateCondition
  450. }
  451. // 获取数据总量
  452. tmpCount, tmpErr := mogDataObj.GetCountDataList(queryConditions)
  453. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  454. err = tmpErr
  455. return
  456. }
  457. dataCount = int(tmpCount)
  458. // 获取列表数据
  459. tmpDataList, tmpErr := mogDataObj.GetPageDataList(queryConditions, int64(startSize), int64(pageSize), []string{"-data_time"})
  460. if tmpErr != nil {
  461. err = tmpErr
  462. return
  463. }
  464. for k, v := range tmpDataList {
  465. dataList = append(dataList, &data_manage.EdbData{
  466. EdbDataId: k + 1,
  467. EdbInfoId: v.EdbInfoId,
  468. DataTime: v.DataTime.Format(utils.FormatDate),
  469. Value: v.Value,
  470. })
  471. }
  472. return
  473. }