edb_data_calculate_tbz.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package models
  2. import (
  3. "fmt"
  4. "github.com/beego/beego/v2/client/orm"
  5. "github.com/shopspring/decimal"
  6. "hongze/hongze_edb_lib/utils"
  7. "strconv"
  8. "strings"
  9. "time"
  10. )
  11. // AddCalculateTbz 同比值
  12. func AddCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfoId int, err error) {
  13. fmt.Println("AddCalculateTbz")
  14. o := orm.NewOrm()
  15. to, err := o.Begin()
  16. if err != nil {
  17. return
  18. }
  19. defer func() {
  20. if err != nil {
  21. _ = to.Rollback()
  22. } else {
  23. _ = to.Commit()
  24. }
  25. }()
  26. if req.EdbInfoId <= 0 {
  27. edbInfo := new(EdbInfo)
  28. edbInfo.Source = utils.DATA_SOURCE_CALCULATE_TBZ
  29. edbInfo.SourceName = "同比值"
  30. edbInfo.EdbCode = edbCode
  31. edbInfo.EdbName = req.EdbName
  32. edbInfo.EdbNameSource = req.EdbName
  33. edbInfo.Frequency = req.Frequency
  34. edbInfo.Unit = req.Unit
  35. edbInfo.ClassifyId = req.ClassifyId
  36. edbInfo.SysUserId = sysUserId
  37. edbInfo.SysUserRealName = sysUserRealName
  38. edbInfo.CreateTime = time.Now()
  39. edbInfo.ModifyTime = time.Now()
  40. edbInfo.UniqueCode = uniqueCode
  41. edbInfo.CalculateFormula = req.Formula
  42. edbInfo.EdbType = 2
  43. newEdbInfoId, tmpErr := to.Insert(edbInfo)
  44. if tmpErr != nil {
  45. return edbInfoId, tmpErr
  46. }
  47. edbInfoId = int(newEdbInfoId)
  48. //关联关系
  49. {
  50. calculateMappingItem := new(EdbInfoCalculateMapping)
  51. calculateMappingItem.CreateTime = time.Now()
  52. calculateMappingItem.ModifyTime = time.Now()
  53. calculateMappingItem.Sort = 1
  54. calculateMappingItem.EdbCode = edbCode
  55. calculateMappingItem.EdbInfoId = edbInfoId
  56. calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
  57. calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
  58. calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
  59. calculateMappingItem.FromSource = fromEdbInfo.Source
  60. calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
  61. calculateMappingItem.FromTag = ""
  62. calculateMappingItem.Source = edbInfo.Source
  63. calculateMappingItem.SourceName = edbInfo.SourceName
  64. _, err = to.Insert(calculateMappingItem)
  65. if err != nil {
  66. return
  67. }
  68. }
  69. } else {
  70. edbInfoId = req.EdbInfoId
  71. dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_TBZ)
  72. deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
  73. deleteSql = fmt.Sprintf(deleteSql, dataTableName)
  74. _, err = to.Raw(deleteSql, req.EdbInfoId).Exec()
  75. if err != nil {
  76. return
  77. }
  78. }
  79. edbInfoIdStr := strconv.Itoa(edbInfoId)
  80. //计算数据
  81. var condition string
  82. var pars []interface{}
  83. condition += " AND edb_info_id=? "
  84. if req.EdbInfoId <= 0 {
  85. pars = append(pars, req.FromEdbInfoId)
  86. } else {
  87. pars = append(pars, fromEdbInfo.EdbInfoId)
  88. }
  89. dataList, err := GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
  90. if err != nil {
  91. return edbInfoId, err
  92. }
  93. var dateArr []string
  94. dataMap := make(map[string]*EdbInfoSearchData)
  95. for _, v := range dataList {
  96. dateArr = append(dateArr, v.DataTime)
  97. dataMap[v.DataTime] = v
  98. }
  99. addSql := ` INSERT INTO edb_data_calculate_tbz(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
  100. var isAdd bool
  101. existMap := make(map[string]string)
  102. for _, av := range dateArr {
  103. //fmt.Println(ak, av)
  104. currentItem := dataMap[av]
  105. if currentItem != nil {
  106. //当前日期
  107. currentDate, err := time.Parse(utils.FormatDate, av)
  108. if err != nil {
  109. return edbInfoId, err
  110. }
  111. //上一年的日期
  112. preDate := currentDate.AddDate(-1, 0, 0)
  113. preDateStr := preDate.Format(utils.FormatDate)
  114. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
  115. //dataTime, _ := time.Parse(utils.FormatDate, date)
  116. if _, ok := existMap[edbCode+av]; !ok {
  117. timestamp := currentDate.UnixNano() / 1e6
  118. timestampStr := fmt.Sprintf("%d", timestamp)
  119. val := TbzDiv(currentItem.Value, findItem.Value)
  120. addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
  121. isAdd = true
  122. utils.FileLog.Info("同期找到:" + av + ";" + preDateStr)
  123. }
  124. existMap[edbCode+av] = av
  125. } else {
  126. if fromEdbInfo.Frequency == "月度" { //向上和向下,各找一个月
  127. nextDateDay := preDate
  128. preDateDay := preDate
  129. for i := 0; i <= 35; i++ {
  130. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  131. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  132. if _, ok := existMap[edbCode+av]; !ok {
  133. timestamp := currentDate.UnixNano() / 1e6
  134. timestampStr := fmt.Sprintf("%d", timestamp)
  135. val := TbzDiv(currentItem.Value, findItem.Value)
  136. addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
  137. isAdd = true
  138. }
  139. existMap[edbCode+av] = av
  140. break
  141. } else {
  142. preDateDayStr := preDateDay.Format(utils.FormatDate)
  143. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  144. if _, ok := existMap[edbCode+av]; !ok {
  145. timestamp := currentDate.UnixNano() / 1e6
  146. timestampStr := fmt.Sprintf("%d", timestamp)
  147. val := TbzDiv(currentItem.Value, findItem.Value)
  148. addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
  149. isAdd = true
  150. }
  151. existMap[edbCode+av] = av
  152. break
  153. }
  154. }
  155. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  156. preDateDay = preDateDay.AddDate(0, 0, -1)
  157. }
  158. } else if fromEdbInfo.Frequency == "季度" || fromEdbInfo.Frequency == "年度" {
  159. if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
  160. if _, ok := existMap[edbCode+av]; !ok {
  161. timestamp := currentDate.UnixNano() / 1e6
  162. timestampStr := fmt.Sprintf("%d", timestamp)
  163. val := TbzDiv(currentItem.Value, findItem.Value)
  164. addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
  165. isAdd = true
  166. }
  167. existMap[edbCode+av] = av
  168. break
  169. }
  170. } else {
  171. nextDateDay := preDate
  172. preDateDay := preDate
  173. for i := 0; i < 35; i++ {
  174. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  175. if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  176. if _, ok := existMap[edbCode+av]; !ok {
  177. timestamp := currentDate.UnixNano() / 1e6
  178. timestampStr := fmt.Sprintf("%d", timestamp)
  179. val := TbzDiv(currentItem.Value, findItem.Value)
  180. addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
  181. isAdd = true
  182. }
  183. existMap[edbCode+av] = av
  184. break
  185. } else {
  186. preDateDayStr := preDateDay.Format(utils.FormatDate)
  187. if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  188. if _, ok := existMap[edbCode+av]; !ok {
  189. timestamp := currentDate.UnixNano() / 1e6
  190. timestampStr := fmt.Sprintf("%d", timestamp)
  191. val := TbzDiv(currentItem.Value, findItem.Value)
  192. addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
  193. isAdd = true
  194. }
  195. existMap[edbCode+av] = av
  196. break
  197. } else {
  198. //fmt.Println("pre not find:", preDateStr, "i:", i)
  199. }
  200. }
  201. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  202. preDateDay = preDateDay.AddDate(0, 0, -1)
  203. }
  204. }
  205. }
  206. }
  207. }
  208. if isAdd {
  209. addSql = strings.TrimRight(addSql, ",")
  210. _, err = to.Raw(addSql).Exec()
  211. if err != nil {
  212. return edbInfoId, err
  213. }
  214. }
  215. return
  216. }
  217. func TbzDiv(a, b float64) string {
  218. var valStr string
  219. if b != 0 {
  220. af := decimal.NewFromFloat(float64(a))
  221. bf := decimal.NewFromFloat(float64(b))
  222. val, _ := af.Div(bf).Float64()
  223. val = val - 1
  224. valStr = utils.SubFloatToString(val, 4)
  225. } else {
  226. valStr = "0"
  227. }
  228. return valStr
  229. }