edb_info_calculate.go 24 KB

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