edb_info_calculate.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. package data
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/yidane/formula"
  6. "hongze/hongze_chart_lib/models/data_manage"
  7. "hongze/hongze_chart_lib/utils"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. func CheckFormula(formula string) map[string]string {
  13. mathFormula := []string{"MAX", "MIN", "ABS", "ACOS", "ASIN", "CEIL", "MOD", "POW", "ROUND", "SIGN", "SIN", "TAN", "LOG10", "LOG2", "LOG"}
  14. str := strings.ToUpper(formula)
  15. for _, v := range mathFormula {
  16. str = strings.Replace(str, v, "", -1)
  17. }
  18. str = strings.Replace(str, "(", "", -1)
  19. str = strings.Replace(str, ")", "", -1)
  20. byteMap := make(map[string]string)
  21. for i := 0; i < len(str); i++ {
  22. byteInt := str[i]
  23. if byteInt >= 65 && byteInt <= 90 {
  24. byteStr := string(byteInt)
  25. if _, ok := byteMap[byteStr]; !ok {
  26. byteMap[byteStr] = byteStr
  27. }
  28. }
  29. }
  30. return byteMap
  31. }
  32. type CalculateItems struct {
  33. EdbInfoId int
  34. DataMap map[string]float64
  35. }
  36. func Calculate(edbInfoIdArr []*data_manage.EdbInfo, edbInfoId int, edbCode, formulaStr string, edbInfoIdBytes []string) (err error) {
  37. defer func() {
  38. if err != nil {
  39. utils.FileLog.Info("Calculate Err:%s" + err.Error())
  40. }
  41. }()
  42. saveDataMap := make(map[string]map[int]float64)
  43. for _, v := range edbInfoIdArr {
  44. var condition string
  45. var pars []interface{}
  46. condition += " AND edb_info_id=? "
  47. pars = append(pars, v.EdbInfoId)
  48. dataList, err := data_manage.GetEdbDataListAll(condition, pars, v.Source, 1)
  49. if err != nil {
  50. return err
  51. }
  52. dataMap := make(map[string]float64)
  53. for _, dv := range dataList {
  54. if val, ok := saveDataMap[dv.DataTime]; ok {
  55. if _, ok := val[v.EdbInfoId]; !ok {
  56. val[v.EdbInfoId] = dv.Value
  57. }
  58. } else {
  59. temp := make(map[int]float64)
  60. temp[v.EdbInfoId] = dv.Value
  61. saveDataMap[dv.DataTime] = temp
  62. }
  63. }
  64. item := new(CalculateItems)
  65. item.EdbInfoId = v.EdbInfoId
  66. item.DataMap = dataMap
  67. }
  68. formulaMap := CheckFormula(formulaStr)
  69. addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
  70. nowStr := time.Now().Format(utils.FormatDateTime)
  71. var isAdd bool
  72. for sk, sv := range saveDataMap {
  73. formulaStr = strings.ToUpper(formulaStr)
  74. formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
  75. if formulaStr == "" {
  76. return
  77. }
  78. if formulaFormStr != "" {
  79. expression := formula.NewExpression(formulaFormStr)
  80. calResult, err := expression.Evaluate()
  81. if err != nil {
  82. err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  83. fmt.Println(err)
  84. return err
  85. }
  86. calVal, err := calResult.Float64()
  87. if err != nil {
  88. err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  89. fmt.Println(err)
  90. return err
  91. }
  92. //需要存入的数据
  93. {
  94. dataTime, _ := time.Parse(utils.FormatDate, sk)
  95. timestamp := dataTime.UnixNano() / 1e6
  96. timeStr := fmt.Sprintf("%d", timestamp)
  97. addSql += "("
  98. addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
  99. "," + "'" + nowStr + "'" + "," + "1"
  100. addSql += "," + "'" + timeStr + "'"
  101. addSql += "),"
  102. isAdd = true
  103. }
  104. } else {
  105. fmt.Println("formulaFormStr is empty")
  106. }
  107. }
  108. if isAdd {
  109. addSql = strings.TrimRight(addSql, ",")
  110. data_manage.AddEdbDataCalculateBySql(addSql)
  111. if err != nil {
  112. fmt.Println("AddEdbDataCalculate Err:" + err.Error())
  113. return err
  114. }
  115. }
  116. return
  117. }
  118. func ReplaceFormula(edbInfoIdArr []*data_manage.EdbInfo, valArr map[int]float64, formulaMap map[string]string, formulaStr string, edbInfoIdBytes []string) string {
  119. funMap := GetFormulaMap()
  120. for k, v := range funMap {
  121. formulaStr = strings.Replace(formulaStr, k, v, -1)
  122. }
  123. replaceCount := 0
  124. for dk, dv := range edbInfoIdArr {
  125. if dk == 0 {
  126. dKey := edbInfoIdBytes[dk]
  127. if _, ok := formulaMap[dKey]; ok { //公式中存在
  128. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  129. dvStr := fmt.Sprintf("%v", val)
  130. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  131. replaceCount++
  132. } else {
  133. fmt.Println("valArr not found:", valArr, valOk)
  134. }
  135. } else {
  136. fmt.Println("formulaMap not found:", dKey, dk)
  137. }
  138. }
  139. if dk == 1 {
  140. dKey := edbInfoIdBytes[dk]
  141. if _, ok := formulaMap[dKey]; ok { //公式中存在
  142. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  143. dvStr := fmt.Sprintf("%v", val)
  144. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  145. replaceCount++
  146. } else {
  147. fmt.Println("valArr not found:", valArr, valOk)
  148. }
  149. } else {
  150. fmt.Println("formulaMap not found:", dKey, dk)
  151. }
  152. }
  153. if dk == 2 {
  154. dKey := edbInfoIdBytes[dk]
  155. if _, ok := formulaMap[dKey]; ok { //公式中存在
  156. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  157. dvStr := fmt.Sprintf("%v", val)
  158. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  159. replaceCount++
  160. }
  161. }
  162. }
  163. if dk == 3 {
  164. dKey := edbInfoIdBytes[dk]
  165. if _, ok := formulaMap[dKey]; ok { //公式中存在
  166. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  167. dvStr := fmt.Sprintf("%v", val)
  168. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  169. replaceCount++
  170. }
  171. }
  172. }
  173. if dk == 4 {
  174. dKey := edbInfoIdBytes[dk]
  175. if _, ok := formulaMap[dKey]; ok { //公式中存在
  176. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  177. dvStr := fmt.Sprintf("%v", val)
  178. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  179. replaceCount++
  180. }
  181. }
  182. }
  183. if dk == 5 {
  184. dKey := edbInfoIdBytes[dk]
  185. if _, ok := formulaMap[dKey]; ok { //公式中存在
  186. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  187. dvStr := fmt.Sprintf("%v", val)
  188. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  189. replaceCount++
  190. }
  191. }
  192. }
  193. if dk == 6 {
  194. dKey := edbInfoIdBytes[dk]
  195. if _, ok := formulaMap[dKey]; ok { //公式中存在
  196. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  197. dvStr := fmt.Sprintf("%v", val)
  198. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  199. replaceCount++
  200. }
  201. }
  202. }
  203. if dk == 7 {
  204. dKey := edbInfoIdBytes[dk]
  205. if _, ok := formulaMap[dKey]; ok { //公式中存在
  206. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  207. dvStr := fmt.Sprintf("%v", val)
  208. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  209. replaceCount++
  210. }
  211. }
  212. }
  213. if dk == 8 {
  214. dKey := edbInfoIdBytes[dk]
  215. if _, ok := formulaMap[dKey]; ok { //公式中存在
  216. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  217. dvStr := fmt.Sprintf("%v", val)
  218. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  219. replaceCount++
  220. }
  221. }
  222. }
  223. }
  224. for k, v := range funMap {
  225. formulaStr = strings.Replace(formulaStr, v, k, -1)
  226. }
  227. if replaceCount == len(formulaMap) {
  228. return formulaStr
  229. } else {
  230. return ""
  231. }
  232. }
  233. func GetFormulaMap() map[string]string {
  234. funMap := make(map[string]string)
  235. funMap["MAX"] = "[@@]"
  236. funMap["MIN"] = "[@!]"
  237. funMap["ABS"] = "[@#]"
  238. funMap["CEIL"] = "[@$]"
  239. funMap["COS"] = "[@%]"
  240. funMap["FLOOR"] = "[@^]"
  241. funMap["MOD"] = "[@&]"
  242. funMap["POW"] = "[@*]"
  243. funMap["ROUND"] = "[@(]"
  244. return funMap
  245. }
  246. //刷新数据
  247. func RefreshCalculate(edbInfoIdArr []*data_manage.EdbInfo, edbInfoId int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string) (err error) {
  248. defer func() {
  249. if err != nil {
  250. fmt.Println("RefreshCalculate:Err " + err.Error())
  251. utils.FileLog.Info("Calculate Err:%s" + err.Error())
  252. }
  253. }()
  254. saveDataMap := make(map[string]map[int]float64)
  255. for _, v := range edbInfoIdArr {
  256. var condition string
  257. var pars []interface{}
  258. condition += " AND edb_info_id=? "
  259. pars = append(pars, v.EdbInfoId)
  260. if startDate != "" {
  261. condition += " AND data_time>=? "
  262. pars = append(pars, startDate)
  263. }
  264. if endDate != "" {
  265. condition += " AND data_time<=? "
  266. pars = append(pars, endDate)
  267. }
  268. dataList, err := data_manage.GetEdbDataListAll(condition, pars, v.Source, 1)
  269. if err != nil {
  270. return err
  271. }
  272. dataMap := make(map[string]float64)
  273. for _, dv := range dataList {
  274. if val, ok := saveDataMap[dv.DataTime]; ok {
  275. if _, ok := val[v.EdbInfoId]; !ok {
  276. val[v.EdbInfoId] = dv.Value
  277. }
  278. } else {
  279. temp := make(map[int]float64)
  280. temp[v.EdbInfoId] = dv.Value
  281. saveDataMap[dv.DataTime] = temp
  282. }
  283. }
  284. item := new(CalculateItems)
  285. item.EdbInfoId = v.EdbInfoId
  286. item.DataMap = dataMap
  287. }
  288. formulaMap := CheckFormula(formulaStr)
  289. addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
  290. nowStr := time.Now().Format(utils.FormatDateTime)
  291. var isAdd bool
  292. for sk, sv := range saveDataMap {
  293. formulaStr = strings.ToUpper(formulaStr)
  294. formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
  295. if formulaFormStr != "" {
  296. utils.FileLog.Info("formulaFormStr:%s", formulaFormStr)
  297. expression := formula.NewExpression(formulaFormStr)
  298. calResult, err := expression.Evaluate()
  299. if err != nil {
  300. err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  301. fmt.Println(err)
  302. return err
  303. }
  304. calVal, err := calResult.Float64()
  305. if err != nil {
  306. err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  307. fmt.Println(err)
  308. return err
  309. }
  310. count, err := data_manage.GetEdbDataCalculateByCodeAndDate(edbCode, sk)
  311. if err != nil && err.Error() != utils.ErrNoRow() {
  312. return err
  313. }
  314. if count <= 0 { //需要存入的数据
  315. dataTime, _ := time.Parse(utils.FormatDate, sk)
  316. timestamp := dataTime.UnixNano() / 1e6
  317. timeStr := fmt.Sprintf("%d", timestamp)
  318. addSql += "("
  319. addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
  320. "," + "'" + nowStr + "'" + "," + "1"
  321. addSql += "," + "'" + timeStr + "'"
  322. addSql += "),"
  323. isAdd = true
  324. } else {
  325. calVal = utils.FixFloat(calVal, 4)
  326. err = data_manage.ModifyEdbDataCalculate(int64(edbInfoId), sk, calVal)
  327. if err != nil {
  328. return err
  329. }
  330. }
  331. }
  332. }
  333. if isAdd {
  334. addSql = strings.TrimRight(addSql, ",")
  335. data_manage.AddEdbDataCalculateBySql(addSql)
  336. if err != nil {
  337. fmt.Println("AddEdbDataCalculate Err:" + err.Error())
  338. return err
  339. }
  340. }
  341. return
  342. }