edb_info_calculate.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. package data
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models/data_manage"
  6. "eta/eta_api/utils"
  7. "fmt"
  8. "github.com/shopspring/decimal"
  9. "github.com/yidane/formula"
  10. "math"
  11. "regexp"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. func CheckFormula(formula string) map[string]string {
  17. mathFormula := []string{"MAX", "MIN", "ABS", "ACOS", "ASIN", "CEIL", "MOD", "POW", "ROUND", "SIGN", "SIN", "TAN", "LOG10", "LOG2", "LOG", "LN", "EXP"}
  18. str := strings.ToUpper(formula)
  19. for _, v := range mathFormula {
  20. str = strings.Replace(str, v, "", -1)
  21. }
  22. str = strings.Replace(str, "(", "", -1)
  23. str = strings.Replace(str, ")", "", -1)
  24. byteMap := make(map[string]string)
  25. for i := 0; i < len(str); i++ {
  26. byteInt := str[i]
  27. if byteInt >= 65 && byteInt <= 90 {
  28. byteStr := string(byteInt)
  29. if _, ok := byteMap[byteStr]; !ok {
  30. byteMap[byteStr] = byteStr
  31. }
  32. }
  33. }
  34. return byteMap
  35. }
  36. type FormulaListItem struct {
  37. Formula string `json:"f"`
  38. Date string `json:"d"`
  39. }
  40. // CheckFormulaJson 检测计算公式json串是否异常
  41. func CheckFormulaJson(formula string) (formulaSlice []string, err error) {
  42. list := make([]FormulaListItem, 0)
  43. err = json.Unmarshal([]byte(formula), &list)
  44. if err != nil {
  45. err = fmt.Errorf("公式串解析失败: json.Unmarshal Err: %v", err)
  46. return
  47. }
  48. formulaSlice = make([]string, 0)
  49. // 日期排序
  50. for _, v := range list {
  51. formulaSlice = append(formulaSlice, v.Formula)
  52. }
  53. return
  54. }
  55. type CalculateItems struct {
  56. EdbInfoId int
  57. DataMap map[string]float64
  58. }
  59. func Calculate(edbInfoIdArr []*data_manage.EdbInfo, edbInfoId int, edbCode, formulaStr string, edbInfoIdBytes []string) (err error) {
  60. defer func() {
  61. if err != nil {
  62. utils.FileLog.Info("Calculate Err:%s" + err.Error())
  63. }
  64. }()
  65. saveDataMap := make(map[string]map[int]float64)
  66. for _, v := range edbInfoIdArr {
  67. var condition string
  68. var pars []interface{}
  69. condition += " AND edb_info_id=? "
  70. pars = append(pars, v.EdbInfoId)
  71. dataList, err := data_manage.GetEdbDataListAll(condition, pars, v.Source, v.SubSource, 1)
  72. if err != nil {
  73. return err
  74. }
  75. dataMap := make(map[string]float64)
  76. for _, dv := range dataList {
  77. if val, ok := saveDataMap[dv.DataTime]; ok {
  78. if _, ok := val[v.EdbInfoId]; !ok {
  79. val[v.EdbInfoId] = dv.Value
  80. }
  81. } else {
  82. temp := make(map[int]float64)
  83. temp[v.EdbInfoId] = dv.Value
  84. saveDataMap[dv.DataTime] = temp
  85. }
  86. }
  87. item := new(CalculateItems)
  88. item.EdbInfoId = v.EdbInfoId
  89. item.DataMap = dataMap
  90. }
  91. formulaMap := CheckFormula(formulaStr)
  92. addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
  93. nowStr := time.Now().Format(utils.FormatDateTime)
  94. var isAdd bool
  95. for sk, sv := range saveDataMap {
  96. formulaStr = strings.ToUpper(formulaStr)
  97. formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
  98. if formulaStr == "" {
  99. return
  100. }
  101. if formulaFormStr != "" {
  102. expression := formula.NewExpression(formulaFormStr)
  103. calResult, err := expression.Evaluate()
  104. if err != nil {
  105. err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  106. fmt.Println(err)
  107. return err
  108. }
  109. calVal, err := calResult.Float64()
  110. if err != nil {
  111. err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  112. fmt.Println(err)
  113. return err
  114. }
  115. //需要存入的数据
  116. {
  117. dataTime, _ := time.Parse(utils.FormatDate, sk)
  118. timestamp := dataTime.UnixNano() / 1e6
  119. timeStr := fmt.Sprintf("%d", timestamp)
  120. addSql += "("
  121. addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
  122. "," + "'" + nowStr + "'" + "," + "1"
  123. addSql += "," + "'" + timeStr + "'"
  124. addSql += "),"
  125. isAdd = true
  126. }
  127. } else {
  128. fmt.Println("formulaFormStr is empty")
  129. }
  130. }
  131. if isAdd {
  132. addSql = strings.TrimRight(addSql, ",")
  133. data_manage.AddEdbDataCalculateBySql(addSql)
  134. if err != nil {
  135. fmt.Println("AddEdbDataCalculate Err:" + err.Error())
  136. return err
  137. }
  138. }
  139. return
  140. }
  141. func ReplaceFormula(edbInfoIdArr []*data_manage.EdbInfo, valArr map[int]float64, formulaMap map[string]string, formulaStr string, edbInfoIdBytes []string) string {
  142. // todo 处理min和max
  143. funMap := GetFormulaMap()
  144. for k, v := range funMap {
  145. formulaStr = strings.Replace(formulaStr, k, v, -1)
  146. }
  147. replaceCount := 0
  148. for dk, dv := range edbInfoIdArr {
  149. if dk == 0 {
  150. dKey := edbInfoIdBytes[dk]
  151. if _, ok := formulaMap[dKey]; ok { //公式中存在
  152. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  153. dvStr := fmt.Sprintf("%v", val)
  154. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  155. replaceCount++
  156. } else {
  157. fmt.Println("valArr not found:", valArr, valOk)
  158. }
  159. } else {
  160. fmt.Println("formulaMap not found:", dKey, dk)
  161. }
  162. }
  163. if dk == 1 {
  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. } else {
  171. fmt.Println("valArr not found:", valArr, valOk)
  172. }
  173. } else {
  174. fmt.Println("formulaMap not found:", dKey, dk)
  175. }
  176. }
  177. if dk == 2 {
  178. dKey := edbInfoIdBytes[dk]
  179. if _, ok := formulaMap[dKey]; ok { //公式中存在
  180. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  181. dvStr := fmt.Sprintf("%v", val)
  182. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  183. replaceCount++
  184. }
  185. }
  186. }
  187. if dk == 3 {
  188. dKey := edbInfoIdBytes[dk]
  189. if _, ok := formulaMap[dKey]; ok { //公式中存在
  190. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  191. dvStr := fmt.Sprintf("%v", val)
  192. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  193. replaceCount++
  194. }
  195. }
  196. }
  197. if dk == 4 {
  198. dKey := edbInfoIdBytes[dk]
  199. if _, ok := formulaMap[dKey]; ok { //公式中存在
  200. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  201. dvStr := fmt.Sprintf("%v", val)
  202. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  203. replaceCount++
  204. }
  205. }
  206. }
  207. if dk == 5 {
  208. dKey := edbInfoIdBytes[dk]
  209. if _, ok := formulaMap[dKey]; ok { //公式中存在
  210. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  211. dvStr := fmt.Sprintf("%v", val)
  212. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  213. replaceCount++
  214. }
  215. }
  216. }
  217. if dk == 6 {
  218. dKey := edbInfoIdBytes[dk]
  219. if _, ok := formulaMap[dKey]; ok { //公式中存在
  220. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  221. dvStr := fmt.Sprintf("%v", val)
  222. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  223. replaceCount++
  224. }
  225. }
  226. }
  227. if dk == 7 {
  228. dKey := edbInfoIdBytes[dk]
  229. if _, ok := formulaMap[dKey]; ok { //公式中存在
  230. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  231. dvStr := fmt.Sprintf("%v", val)
  232. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  233. replaceCount++
  234. }
  235. }
  236. }
  237. if dk == 8 {
  238. dKey := edbInfoIdBytes[dk]
  239. if _, ok := formulaMap[dKey]; ok { //公式中存在
  240. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  241. dvStr := fmt.Sprintf("%v", val)
  242. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  243. replaceCount++
  244. }
  245. }
  246. }
  247. if dk == 9 {
  248. dKey := edbInfoIdBytes[dk]
  249. if _, ok := formulaMap[dKey]; ok { //公式中存在
  250. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  251. dvStr := fmt.Sprintf("%v", val)
  252. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  253. replaceCount++
  254. }
  255. }
  256. }
  257. if dk == 10 {
  258. dKey := edbInfoIdBytes[dk]
  259. if _, ok := formulaMap[dKey]; ok { //公式中存在
  260. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  261. dvStr := fmt.Sprintf("%v", val)
  262. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  263. replaceCount++
  264. }
  265. }
  266. }
  267. if dk == 11 {
  268. dKey := edbInfoIdBytes[dk]
  269. if _, ok := formulaMap[dKey]; ok { //公式中存在
  270. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  271. dvStr := fmt.Sprintf("%v", val)
  272. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  273. replaceCount++
  274. }
  275. }
  276. }
  277. if dk == 12 {
  278. dKey := edbInfoIdBytes[dk]
  279. if _, ok := formulaMap[dKey]; ok { //公式中存在
  280. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  281. dvStr := fmt.Sprintf("%v", val)
  282. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  283. replaceCount++
  284. }
  285. }
  286. }
  287. if dk == 13 {
  288. dKey := edbInfoIdBytes[dk]
  289. if _, ok := formulaMap[dKey]; ok { //公式中存在
  290. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  291. dvStr := fmt.Sprintf("%v", val)
  292. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  293. replaceCount++
  294. }
  295. }
  296. }
  297. if dk == 14 {
  298. dKey := edbInfoIdBytes[dk]
  299. if _, ok := formulaMap[dKey]; ok { //公式中存在
  300. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  301. dvStr := fmt.Sprintf("%v", val)
  302. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  303. replaceCount++
  304. }
  305. }
  306. }
  307. if dk == 15 {
  308. dKey := edbInfoIdBytes[dk]
  309. if _, ok := formulaMap[dKey]; ok { //公式中存在
  310. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  311. dvStr := fmt.Sprintf("%v", val)
  312. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  313. replaceCount++
  314. }
  315. }
  316. }
  317. if dk == 16 {
  318. dKey := edbInfoIdBytes[dk]
  319. if _, ok := formulaMap[dKey]; ok { //公式中存在
  320. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  321. dvStr := fmt.Sprintf("%v", val)
  322. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  323. replaceCount++
  324. }
  325. }
  326. }
  327. if dk == 17 {
  328. dKey := edbInfoIdBytes[dk]
  329. if _, ok := formulaMap[dKey]; ok { //公式中存在
  330. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  331. dvStr := fmt.Sprintf("%v", val)
  332. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  333. replaceCount++
  334. }
  335. }
  336. }
  337. if dk == 18 {
  338. dKey := edbInfoIdBytes[dk]
  339. if _, ok := formulaMap[dKey]; ok { //公式中存在
  340. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  341. dvStr := fmt.Sprintf("%v", val)
  342. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  343. replaceCount++
  344. }
  345. }
  346. }
  347. if dk == 19 {
  348. dKey := edbInfoIdBytes[dk]
  349. if _, ok := formulaMap[dKey]; ok { //公式中存在
  350. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  351. dvStr := fmt.Sprintf("%v", val)
  352. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  353. replaceCount++
  354. }
  355. }
  356. }
  357. if dk == 20 {
  358. dKey := edbInfoIdBytes[dk]
  359. if _, ok := formulaMap[dKey]; ok { //公式中存在
  360. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  361. dvStr := fmt.Sprintf("%v", val)
  362. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  363. replaceCount++
  364. }
  365. }
  366. }
  367. if dk == 21 {
  368. dKey := edbInfoIdBytes[dk]
  369. if _, ok := formulaMap[dKey]; ok { //公式中存在
  370. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  371. dvStr := fmt.Sprintf("%v", val)
  372. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  373. replaceCount++
  374. }
  375. }
  376. }
  377. if dk == 22 {
  378. dKey := edbInfoIdBytes[dk]
  379. if _, ok := formulaMap[dKey]; ok { //公式中存在
  380. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  381. dvStr := fmt.Sprintf("%v", val)
  382. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  383. replaceCount++
  384. }
  385. }
  386. }
  387. if dk == 23 {
  388. dKey := edbInfoIdBytes[dk]
  389. if _, ok := formulaMap[dKey]; ok { //公式中存在
  390. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  391. dvStr := fmt.Sprintf("%v", val)
  392. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  393. replaceCount++
  394. }
  395. }
  396. }
  397. if dk == 24 {
  398. dKey := edbInfoIdBytes[dk]
  399. if _, ok := formulaMap[dKey]; ok { //公式中存在
  400. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  401. dvStr := fmt.Sprintf("%v", val)
  402. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  403. replaceCount++
  404. }
  405. }
  406. }
  407. if dk == 25 {
  408. dKey := edbInfoIdBytes[dk]
  409. if _, ok := formulaMap[dKey]; ok { //公式中存在
  410. if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
  411. dvStr := fmt.Sprintf("%v", val)
  412. formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
  413. replaceCount++
  414. }
  415. }
  416. }
  417. }
  418. for k, v := range funMap {
  419. formulaStr = strings.Replace(formulaStr, v, k, -1)
  420. }
  421. if replaceCount == len(formulaMap) {
  422. return formulaStr
  423. } else {
  424. return ""
  425. }
  426. }
  427. func GetFormulaMap() map[string]string {
  428. funMap := make(map[string]string)
  429. funMap["MAX"] = "[@@]"
  430. funMap["MIN"] = "[@!]"
  431. funMap["ABS"] = "[@#]"
  432. funMap["CEIL"] = "[@$]"
  433. funMap["COS"] = "[@%]"
  434. funMap["FLOOR"] = "[@^]"
  435. funMap["MOD"] = "[@&]"
  436. funMap["POW"] = "[@*]"
  437. funMap["ROUND"] = "[@(]"
  438. return funMap
  439. }
  440. // 刷新数据
  441. func RefreshCalculate(edbInfoIdArr []*data_manage.EdbInfo, edbInfoId int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string) (err error) {
  442. defer func() {
  443. if err != nil {
  444. fmt.Println("RefreshCalculate:Err " + err.Error())
  445. utils.FileLog.Info("Calculate Err:%s" + err.Error())
  446. }
  447. }()
  448. saveDataMap := make(map[string]map[int]float64)
  449. for _, v := range edbInfoIdArr {
  450. var condition string
  451. var pars []interface{}
  452. condition += " AND edb_info_id=? "
  453. pars = append(pars, v.EdbInfoId)
  454. if startDate != "" {
  455. condition += " AND data_time>=? "
  456. pars = append(pars, startDate)
  457. }
  458. if endDate != "" {
  459. condition += " AND data_time<=? "
  460. pars = append(pars, endDate)
  461. }
  462. dataList, err := data_manage.GetEdbDataListAll(condition, pars, v.Source, v.SubSource, 1)
  463. if err != nil {
  464. return err
  465. }
  466. dataMap := make(map[string]float64)
  467. for _, dv := range dataList {
  468. if val, ok := saveDataMap[dv.DataTime]; ok {
  469. if _, ok := val[v.EdbInfoId]; !ok {
  470. val[v.EdbInfoId] = dv.Value
  471. }
  472. } else {
  473. temp := make(map[int]float64)
  474. temp[v.EdbInfoId] = dv.Value
  475. saveDataMap[dv.DataTime] = temp
  476. }
  477. }
  478. item := new(CalculateItems)
  479. item.EdbInfoId = v.EdbInfoId
  480. item.DataMap = dataMap
  481. }
  482. formulaMap := CheckFormula(formulaStr)
  483. addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
  484. nowStr := time.Now().Format(utils.FormatDateTime)
  485. var isAdd bool
  486. for sk, sv := range saveDataMap {
  487. formulaStr = strings.ToUpper(formulaStr)
  488. formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
  489. if formulaFormStr != "" {
  490. utils.FileLog.Info("formulaFormStr:%s", formulaFormStr)
  491. expression := formula.NewExpression(formulaFormStr)
  492. calResult, err := expression.Evaluate()
  493. if err != nil {
  494. err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  495. fmt.Println(err)
  496. return err
  497. }
  498. calVal, err := calResult.Float64()
  499. if err != nil {
  500. err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  501. fmt.Println(err)
  502. return err
  503. }
  504. count, err := data_manage.GetEdbDataCalculateByCodeAndDate(edbCode, sk)
  505. if err != nil && err.Error() != utils.ErrNoRow() {
  506. return err
  507. }
  508. if count <= 0 { //需要存入的数据
  509. dataTime, _ := time.Parse(utils.FormatDate, sk)
  510. timestamp := dataTime.UnixNano() / 1e6
  511. timeStr := fmt.Sprintf("%d", timestamp)
  512. addSql += "("
  513. addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
  514. "," + "'" + nowStr + "'" + "," + "1"
  515. addSql += "," + "'" + timeStr + "'"
  516. addSql += "),"
  517. isAdd = true
  518. } else {
  519. calVal = utils.FixFloat(calVal, 4)
  520. err = data_manage.ModifyEdbDataCalculate(int64(edbInfoId), sk, calVal)
  521. if err != nil {
  522. return err
  523. }
  524. }
  525. }
  526. }
  527. if isAdd {
  528. addSql = strings.TrimRight(addSql, ",")
  529. data_manage.AddEdbDataCalculateBySql(addSql)
  530. if err != nil {
  531. fmt.Println("AddEdbDataCalculate Err:" + err.Error())
  532. return err
  533. }
  534. }
  535. return
  536. }
  537. // 处理整个数据
  538. func handleDateSaveDataMap(dateList []string, realSaveDataMap, saveDataMap map[string]map[int]float64, edbInfoIdArr []*data_manage.EdbInfo, emptyType int) {
  539. var startDate, endDate string
  540. var startDateT, endDateT time.Time
  541. if emptyType == 2 || emptyType == 3 {
  542. for k, _ := range realSaveDataMap {
  543. if k > endDate {
  544. endDate = k
  545. }
  546. if k < startDate || startDate == "" {
  547. startDate = k
  548. }
  549. }
  550. startDateT, _ = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  551. endDateT, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  552. }
  553. for _, date := range dateList {
  554. tmpDataMap := realSaveDataMap[date]
  555. for _, edbInfo := range edbInfoIdArr {
  556. tmpEdbInfoId := edbInfo.EdbInfoId // 当前指标id
  557. // 如果该日期不存在该指标数据,那么需要找寻前后日期的数据,进行填补
  558. if _, ok := tmpDataMap[tmpEdbInfoId]; !ok {
  559. //day := 0
  560. //switch edbInfo.Frequency {
  561. //case "周度":
  562. // day = 7
  563. //case "旬度":
  564. // day = 15
  565. //case "月度":
  566. // day = 30
  567. //case "季度":
  568. // day = 90
  569. //case "年度":
  570. // day = 365
  571. //}
  572. // 需求池 255 指标运算文案修改,补数据遍历区间修改(2023-3-7 09:37:23修改)
  573. switch emptyType {
  574. case 0:
  575. handleDateDataMap(realSaveDataMap, saveDataMap, date, tmpEdbInfoId, 35)
  576. case 2:
  577. handleDateDataMapBefore(realSaveDataMap, saveDataMap, date, tmpEdbInfoId, startDateT, endDateT)
  578. case 3:
  579. handleDateDataMapAfter(realSaveDataMap, saveDataMap, date, tmpEdbInfoId, startDateT, endDateT)
  580. case 4:
  581. handleDateDataMapZero(saveDataMap, date, tmpEdbInfoId)
  582. }
  583. }
  584. }
  585. }
  586. }
  587. // handleDataMap 处理单个日期的数据
  588. func handleDateDataMap(realSaveDataMap, saveDataMap map[string]map[int]float64, date string, edbInfoId, day int) {
  589. currDate, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
  590. // 后一天
  591. nextDateDayStr := currDate.AddDate(0, 0, 1).Format(utils.FormatDate)
  592. // 前一天
  593. preDateDayStr := currDate.AddDate(0, 0, -1).Format(utils.FormatDate)
  594. for i := 1; i <= day; i++ {
  595. // 下个日期的数据
  596. {
  597. if i >= 1 {
  598. nextDateDayStr = currDate.AddDate(0, 0, i).Format(utils.FormatDate)
  599. }
  600. if findDataMap, hasFindDataMap := realSaveDataMap[nextDateDayStr]; hasFindDataMap { // 下一个日期有数据
  601. if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
  602. saveDataMap[date][edbInfoId] = val
  603. return
  604. }
  605. }
  606. }
  607. // 上个日期的数据
  608. {
  609. if i >= 1 {
  610. preDateDayStr = currDate.AddDate(0, 0, -i).Format(utils.FormatDate)
  611. }
  612. if findDataMap, hasFindDataMap := realSaveDataMap[preDateDayStr]; hasFindDataMap { // 下一个日期有数据
  613. if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
  614. saveDataMap[date][edbInfoId] = val
  615. return
  616. }
  617. }
  618. }
  619. }
  620. }
  621. // handleDataByLinearRegression 插值法补充数据(线性方程式)
  622. func handleDataByLinearRegression(edbInfoDataList []*data_manage.EdbDataList, handleDataMap map[string]float64) (err error) {
  623. if len(edbInfoDataList) < 2 {
  624. return
  625. }
  626. var startEdbInfoData *data_manage.EdbDataList
  627. for _, v := range edbInfoDataList {
  628. handleDataMap[v.DataTime] = v.Value
  629. // 第一个数据就给过滤了,给后面的试用
  630. if startEdbInfoData == nil {
  631. startEdbInfoData = v
  632. continue
  633. }
  634. // 获取两条数据之间相差的天数
  635. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  636. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  637. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  638. betweenDay := betweenHour / 24
  639. // 如果相差一天,那么过滤
  640. if betweenDay <= 1 {
  641. startEdbInfoData = v
  642. continue
  643. }
  644. // 生成线性方程式
  645. var a, b float64
  646. {
  647. coordinateData := make([]utils.Coordinate, 0)
  648. tmpCoordinate1 := utils.Coordinate{
  649. X: 1,
  650. Y: startEdbInfoData.Value,
  651. }
  652. coordinateData = append(coordinateData, tmpCoordinate1)
  653. tmpCoordinate2 := utils.Coordinate{
  654. X: float64(betweenDay) + 1,
  655. Y: v.Value,
  656. }
  657. coordinateData = append(coordinateData, tmpCoordinate2)
  658. a, b = utils.GetLinearResult(coordinateData)
  659. if math.IsNaN(a) || math.IsNaN(b) {
  660. err = errors.New("线性方程公式生成失败")
  661. return
  662. }
  663. }
  664. // 生成对应的值
  665. {
  666. for i := 1; i < betweenDay; i++ {
  667. tmpDataTime := startDataTime.AddDate(0, 0, i)
  668. aDecimal := decimal.NewFromFloat(a)
  669. xDecimal := decimal.NewFromInt(int64(i) + 1)
  670. bDecimal := decimal.NewFromFloat(b)
  671. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  672. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  673. }
  674. }
  675. startEdbInfoData = v
  676. }
  677. return
  678. }
  679. // HandleDataByLinearRegression 插值法补充数据(线性方程式)
  680. func HandleDataByLinearRegression(edbInfoDataList []*data_manage.EdbDataList, handleDataMap map[string]float64) (err error) {
  681. return handleDataByLinearRegression(edbInfoDataList, handleDataMap)
  682. }
  683. // CallCalculateComputeCorrelation 调用计算拟合残差的相关系数
  684. func CallCalculateComputeCorrelation(data *data_manage.EdbInfoCalculateBatchSaveReqByEdbLib) (val string, err error, errMsg string) {
  685. errMsg = "计算失败"
  686. // 调用指标库去更新
  687. reqJson, err := json.Marshal(data)
  688. if err != nil {
  689. errMsg = "计算相关系数参数解析异常!"
  690. err = errors.New("参数解析失败,Err:" + err.Error())
  691. return
  692. }
  693. respItem, err := CalculateComputeCorrelation(string(reqJson))
  694. if err != nil {
  695. return
  696. }
  697. if respItem.Ret == 200 {
  698. val = respItem.Data
  699. }
  700. return
  701. }
  702. // handleDateDataMapBefore 前值填充:空值优先以最近的前值填充,没有前值时,用后值填充
  703. func handleDateDataMapBefore(realSaveDataMap, saveDataMap map[string]map[int]float64, date string, edbInfoId int, startDateT, endDateT time.Time) {
  704. currDate, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
  705. // 后一天
  706. nextDateDay := currDate
  707. // 前一天
  708. preDateDay := currDate
  709. for i := 1; preDateDay.After(startDateT) || preDateDay == startDateT; i++ {
  710. // 上个日期的数据
  711. {
  712. preDateDay = currDate.AddDate(0, 0, -i)
  713. preDateDayStr := preDateDay.Format(utils.FormatDate)
  714. if findDataMap, hasFindDataMap := realSaveDataMap[preDateDayStr]; hasFindDataMap { // 下一个日期有数据
  715. if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
  716. fmt.Println(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, preDateDayStr, val))
  717. saveDataMap[date][edbInfoId] = val
  718. return
  719. }
  720. }
  721. }
  722. }
  723. for i := 1; nextDateDay.Before(endDateT) || nextDateDay == endDateT; i++ {
  724. // 下个日期的数据
  725. {
  726. nextDateDay = currDate.AddDate(0, 0, i)
  727. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  728. if findDataMap, hasFindDataMap := realSaveDataMap[nextDateDayStr]; hasFindDataMap { // 下一个日期有数据
  729. if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
  730. fmt.Println(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, nextDateDayStr, val))
  731. saveDataMap[date][edbInfoId] = val
  732. return
  733. }
  734. }
  735. }
  736. }
  737. return
  738. }
  739. // handleDateDataMapAfter 后值填充:空值优先以最近的后值填充,没有后值时,用前值填充
  740. func handleDateDataMapAfter(realSaveDataMap, saveDataMap map[string]map[int]float64, date string, edbInfoId int, startDateT, endDateT time.Time) {
  741. currDate, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
  742. // 后一天
  743. nextDateDay := currDate
  744. // 前一天
  745. preDateDay := currDate
  746. for i := 1; nextDateDay.Before(endDateT) || nextDateDay == endDateT; i++ {
  747. // 下个日期的数据
  748. {
  749. nextDateDay = currDate.AddDate(0, 0, i)
  750. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  751. if findDataMap, hasFindDataMap := realSaveDataMap[nextDateDayStr]; hasFindDataMap { // 下一个日期有数据
  752. if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
  753. fmt.Println(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, nextDateDayStr, val))
  754. saveDataMap[date][edbInfoId] = val
  755. return
  756. }
  757. }
  758. }
  759. }
  760. for i := 1; preDateDay.After(startDateT) || preDateDay == startDateT; i++ {
  761. // 上个日期的数据
  762. {
  763. preDateDay = currDate.AddDate(0, 0, -i)
  764. preDateDayStr := preDateDay.Format(utils.FormatDate)
  765. if findDataMap, hasFindDataMap := realSaveDataMap[preDateDayStr]; hasFindDataMap { // 下一个日期有数据
  766. if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
  767. fmt.Println(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, preDateDayStr, val))
  768. saveDataMap[date][edbInfoId] = val
  769. return
  770. }
  771. }
  772. }
  773. }
  774. return
  775. }
  776. // handleDateDataMapZero 等于0
  777. func handleDateDataMapZero(saveDataMap map[string]map[int]float64, date string, edbInfoId int) {
  778. saveDataMap[date][edbInfoId] = 0
  779. return
  780. }
  781. func GetMaxMinEdbInfo(formula string) string {
  782. //formula := "A+min(A,B,max(A,C))"
  783. // todo 无法处理max里嵌套max或者min的情况
  784. // 使用正则表达式匹配MAX和MIN函数及其参数
  785. regex := regexp.MustCompile(`(?i)(MAX|MIN)\((.*?)\)`)
  786. matches := regex.FindAllStringSubmatch(formula, -1)
  787. // 遍历匹配结果,输出MAX和MIN函数及其参数
  788. for _, match := range matches {
  789. if len(match) == 3 {
  790. parameter := strings.ToLower(match[0]) // 参数
  791. formula = strings.ReplaceAll(formula, match[0], parameter)
  792. fmt.Printf("formula: %s\n", formula)
  793. }
  794. }
  795. formula = strings.ReplaceAll(formula, "max", "MAX")
  796. formula = strings.ReplaceAll(formula, "min", "MIN")
  797. return formula
  798. }