chart.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. package cross_variety
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models/data_manage"
  6. cross_varietyModel "eta/eta_api/models/data_manage/cross_variety"
  7. "eta/eta_api/models/data_manage/cross_variety/request"
  8. "eta/eta_api/models/system"
  9. "eta/eta_api/services/data"
  10. "eta/eta_api/utils"
  11. "fmt"
  12. "github.com/shopspring/decimal"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. type LineEquationDataResp struct {
  18. MaxData float64
  19. MinData float64
  20. LatestDate string `description:"真实数据的最后日期"`
  21. EdbInfoCategoryType int
  22. ChartColor string
  23. ChartStyle string
  24. PredictChartColor string
  25. ChartType int
  26. ChartWidth int
  27. EdbName string
  28. EdbNameEn string
  29. Unit string
  30. UnitEn string
  31. IsAxis int
  32. DataList []data_manage.EdbDataList
  33. }
  34. // ChartInfoResp 截面散点图数据
  35. type ChartInfoResp struct {
  36. XName string `description:"x轴名称"`
  37. XNameEn string `description:"x轴名称(英文)"`
  38. XUnitName string `description:"x轴单位名称"`
  39. XUnitNameEn string `description:"x轴单位名称(英文)"`
  40. YName string `description:"y轴名称"`
  41. YNameEn string `description:"y轴名称(英文)"`
  42. YUnitName string `description:"y轴单位名称"`
  43. YUnitNameEn string `description:"y轴单位名称(英文)"`
  44. XMinValue string `description:"X轴的最小值"`
  45. XMaxValue string `description:"X轴的最大值"`
  46. YMinValue string `description:"Y轴的最小值"`
  47. YMaxValue string `description:"Y轴的最大值"`
  48. DataList []SectionScatterSeriesItemResp `description:"数据列"`
  49. }
  50. // SectionScatterSeriesItemResp 系列的返回
  51. type SectionScatterSeriesItemResp struct {
  52. Name string `description:"系列名"`
  53. NameEn string `description:"系列名(英文)"`
  54. Color string `description:"颜色"`
  55. CoordinatePointData []CoordinatePoint `description:"趋势线的前后坐标点"`
  56. }
  57. // SectionScatterEdbItemResp 截面散点的返回参数
  58. type SectionScatterEdbItemResp struct {
  59. XEdbInfoId int `description:"X轴指标id"`
  60. XDate string `description:"X轴指标实际日期"`
  61. XName string `description:"X轴指标名称"`
  62. XNameEn string `description:"X轴指标英文名称"`
  63. XValue float64 `description:"X轴实际值"`
  64. YEdbInfoId int `description:"Y轴指标id"`
  65. YDate string `description:"Y轴指标实际日期"`
  66. YName string `description:"Y轴指标名称"`
  67. YNameEn string `description:"Y轴指标英文名称"`
  68. YValue float64 `description:"Y轴实际值"`
  69. IsShow bool `description:"是否展示"`
  70. Name string `description:"标签名称"`
  71. NameEn string `description:"英文标签名称"`
  72. }
  73. // CoordinatePoint 坐标点
  74. type CoordinatePoint struct {
  75. X float64
  76. Y float64
  77. XEdbInfoId int
  78. YEdbInfoId int
  79. XDate string
  80. YDate string
  81. }
  82. // GetChartData
  83. // @Description: 获取跨品种分析图表数据
  84. // @author: Roc
  85. // @datetime 2023-11-24 09:42:59
  86. // @param chartInfoId int
  87. // @param config request.ChartConfigReq
  88. // @return edbList []*data_manage.ChartEdbInfoMapping
  89. // @return dataResp ChartInfoResp
  90. // @return err error
  91. // @return errMsg string
  92. // @return isSendEmail bool
  93. func GetChartData(chartInfoId int, config request.ChartConfigReq) (edbList []*data_manage.ChartEdbInfoMapping, dataResp ChartInfoResp, err error, errMsg string, isSendEmail bool) {
  94. moveUnitDays, ok := utils.FrequencyDaysMap[config.CalculateUnit]
  95. if !ok {
  96. errMsg = "错误的分析周期"
  97. err = errors.New(errMsg)
  98. isSendEmail = false
  99. return
  100. }
  101. isSendEmail = true
  102. // 品种map
  103. varietyMap := make(map[int]*cross_varietyModel.ChartVariety)
  104. {
  105. varietyList, tmpErr := cross_varietyModel.GetVarietyListByIdList(config.VarietyList)
  106. if tmpErr != nil {
  107. err = tmpErr
  108. return
  109. }
  110. for _, v := range varietyList {
  111. varietyMap[v.ChartVarietyId] = v
  112. }
  113. }
  114. // 标签m
  115. var xTagInfo, yTagInfo *cross_varietyModel.ChartTag
  116. {
  117. tagList, tmpErr := cross_varietyModel.GetTagListByIdList([]int{config.TagX, config.TagY})
  118. if tmpErr != nil {
  119. err = tmpErr
  120. return
  121. }
  122. for _, v := range tagList {
  123. if v.ChartTagId == config.TagX {
  124. xTagInfo = v
  125. } else if v.ChartTagId == config.TagY {
  126. yTagInfo = v
  127. }
  128. }
  129. }
  130. if xTagInfo == nil {
  131. errMsg = "找不到对应的X轴标签"
  132. err = errors.New(errMsg)
  133. return
  134. }
  135. if yTagInfo == nil {
  136. errMsg = "找不到对应的Y轴标签"
  137. err = errors.New(errMsg)
  138. return
  139. }
  140. xVarietyEdbMap, yVarietyEdbMap, edbInfoIdList, err := GetXYEdbIdList(config.TagX, config.TagY, config.VarietyList)
  141. if err != nil {
  142. return
  143. }
  144. if len(edbInfoIdList) <= 0 {
  145. errMsg = "品种未配置指标"
  146. err = errors.New(errMsg)
  147. isSendEmail = false
  148. return
  149. }
  150. mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList(edbInfoIdList)
  151. if err != nil {
  152. errMsg = "获取指标信息失败"
  153. err = errors.New("获取指标信息失败,ERR:" + err.Error())
  154. return
  155. }
  156. // 指标对应的所有数据
  157. chartType := 1 //1:普通图,2:季节性图
  158. calendar := "公历"
  159. edbDataListMap, edbList, err := data.GetEdbDataMapList(chartInfoId, chartType, calendar, "", "", mappingList, "")
  160. if err != nil {
  161. return
  162. }
  163. currDay := time.Now()
  164. currDay = time.Date(currDay.Year(), currDay.Month(), currDay.Day(), 0, 0, 0, 0, time.Local)
  165. dataMap := make(map[string]float64)
  166. dateMap := make(map[string]string)
  167. for dateIndex, dateConfig := range config.DateConfigList {
  168. for _, edbInfoMapping := range mappingList {
  169. // 数据会是正序的
  170. dataList, ok := edbDataListMap[edbInfoMapping.EdbInfoId]
  171. if !ok {
  172. continue
  173. }
  174. lenData := len(dataList)
  175. if lenData <= 0 {
  176. continue
  177. }
  178. // 数据开始日期
  179. endDateStr := ``
  180. var endDate time.Time
  181. // 数据的开始索引
  182. k := lenData - 1
  183. var currVal float64
  184. switch dateConfig.DateType {
  185. case 1: // 1:最新日期;
  186. endDateStr = dataList[k].DataTime
  187. tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, endDateStr, time.Local)
  188. if tmpErr != nil {
  189. err = tmpErr
  190. return
  191. }
  192. endDate = tmpDate
  193. currVal = dataList[k].Value
  194. case 2: // 2:N天前
  195. tmpEndDate := currDay.AddDate(0, 0, -dateConfig.Num)
  196. tmpEndDateStr := tmpEndDate.Format(utils.FormatDate)
  197. for i := k; i >= 0; i-- {
  198. tmpDateStr := dataList[i].DataTime
  199. // 如果正好是这一天,那么就直接break了
  200. if tmpEndDateStr == tmpDateStr {
  201. k = i
  202. endDateStr = tmpDateStr
  203. currVal = dataList[i].Value
  204. break
  205. }
  206. tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
  207. if tmpErr != nil {
  208. err = tmpErr
  209. return
  210. }
  211. // 如果这期的日期晚于选择的日期,那么继续遍历
  212. if tmpDate.After(tmpEndDate) {
  213. continue
  214. }
  215. k = i
  216. endDateStr = tmpDateStr
  217. endDate = tmpDate
  218. currVal = dataList[i].Value
  219. break
  220. }
  221. }
  222. // 没有找到日期,那么就不处理
  223. if endDateStr == `` || endDate.IsZero() {
  224. continue
  225. }
  226. // 最早的日期
  227. earliestDate := endDate.AddDate(0, 0, -config.CalculateValue*moveUnitDays)
  228. earliestDateStr := earliestDate.Format(utils.FormatDate)
  229. var minVal, maxVal float64
  230. var isNotFirst bool // 是否是第一条数据
  231. for i := k; i >= 0; i-- {
  232. tmpData := dataList[i]
  233. if !isNotFirst {
  234. maxVal = tmpData.Value
  235. minVal = tmpData.Value
  236. isNotFirst = true
  237. continue
  238. }
  239. tmpDateStr := dataList[i].DataTime
  240. // 如果正好是这一天,那么就直接break了
  241. if earliestDateStr == tmpDateStr {
  242. break
  243. }
  244. tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
  245. if tmpErr != nil {
  246. err = tmpErr
  247. return
  248. }
  249. // 如果这期的日期早于选择的日期,那么继续停止遍历
  250. if tmpDate.Before(earliestDate) {
  251. continue
  252. }
  253. if tmpData.Value > maxVal {
  254. maxVal = tmpData.Value
  255. }
  256. if tmpData.Value < minVal {
  257. minVal = tmpData.Value
  258. }
  259. }
  260. // 最大值等于最小值,说明计算结果无效
  261. if maxVal == minVal {
  262. continue
  263. }
  264. //百分位=(现值-Min)/(Max-Min)
  265. tmpV := (currVal - minVal) / (maxVal - minVal) * 100
  266. tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
  267. // key的生成(日期配置下标+指标id)
  268. key := fmt.Sprint(dateIndex, "_", edbInfoMapping.EdbInfoId)
  269. dataMap[key] = tmpV
  270. dateMap[key] = endDateStr
  271. }
  272. }
  273. // 返回数据处理
  274. dataList := make([]SectionScatterSeriesItemResp, 0)
  275. var xMinVal, xMaxVal, yMinVal, yMaxVal float64
  276. var isNotFirst bool
  277. for _, varietyId := range config.VarietyList {
  278. xEdbInfoId, ok1 := xVarietyEdbMap[varietyId]
  279. if !ok1 {
  280. continue
  281. }
  282. yEdbInfoId, ok2 := yVarietyEdbMap[varietyId]
  283. if !ok2 {
  284. continue
  285. }
  286. variety, ok := varietyMap[varietyId]
  287. if !ok {
  288. continue
  289. }
  290. coordinatePointList := make([]CoordinatePoint, 0)
  291. for dateIndex, _ := range config.DateConfigList {
  292. key1 := fmt.Sprint(dateIndex, "_", xEdbInfoId)
  293. xVal, ok1 := dataMap[key1]
  294. if !ok1 {
  295. continue
  296. }
  297. key2 := fmt.Sprint(dateIndex, "_", yEdbInfoId)
  298. yVal, ok2 := dataMap[key2]
  299. if !ok2 {
  300. continue
  301. }
  302. if !isNotFirst {
  303. xMinVal = xVal
  304. xMaxVal = xVal
  305. yMinVal = yVal
  306. yMaxVal = yVal
  307. isNotFirst = true
  308. } else {
  309. if xVal < xMinVal {
  310. xMinVal = xVal
  311. }
  312. if xVal > xMaxVal {
  313. xMaxVal = xVal
  314. }
  315. if yVal < yMinVal {
  316. yMinVal = yVal
  317. }
  318. if yVal > yMaxVal {
  319. yMaxVal = yVal
  320. }
  321. }
  322. coordinatePointList = append(coordinatePointList, CoordinatePoint{
  323. X: xVal,
  324. Y: yVal,
  325. XEdbInfoId: xEdbInfoId,
  326. YEdbInfoId: yEdbInfoId,
  327. XDate: dateMap[key1],
  328. YDate: dateMap[key2],
  329. })
  330. }
  331. dataList = append(dataList, SectionScatterSeriesItemResp{
  332. Name: variety.ChartVarietyName,
  333. NameEn: "",
  334. Color: "",
  335. CoordinatePointData: coordinatePointList,
  336. })
  337. }
  338. dataResp = ChartInfoResp{
  339. XName: xTagInfo.ChartTagName,
  340. XNameEn: "",
  341. XUnitName: "%",
  342. XUnitNameEn: "%",
  343. YName: yTagInfo.ChartTagName,
  344. YNameEn: "",
  345. YUnitName: "%",
  346. YUnitNameEn: "%",
  347. XMinValue: fmt.Sprint(xMinVal),
  348. XMaxValue: fmt.Sprint(xMaxVal),
  349. YMinValue: fmt.Sprint(yMinVal),
  350. YMaxValue: fmt.Sprint(yMaxVal),
  351. DataList: dataList,
  352. }
  353. // 去除返回指标中的数据信息,避免没必要的数据传输
  354. for k, _ := range edbList {
  355. edbList[k].DataList = nil
  356. }
  357. return
  358. }
  359. // GetXYEdbIdList
  360. // @Description: 根据标签id和品种获取指标列表信息
  361. // @author: Roc
  362. // @datetime 2023-11-27 14:31:23
  363. // @param tagX int
  364. // @param tagY int
  365. // @param varietyList []int
  366. // @return xVarietyEdbMap map[int]int
  367. // @return yVarietyEdbMap map[int]int
  368. // @return edbInfoIdList []int
  369. // @return errMsg string
  370. // @return err error
  371. func GetXYEdbIdList(tagX, tagY int, varietyList []int) (xVarietyEdbMap, yVarietyEdbMap map[int]int, edbInfoIdList []int, err error) {
  372. edbInfoIdList = make([]int, 0)
  373. xVarietyEdbMap = make(map[int]int)
  374. yVarietyEdbMap = make(map[int]int)
  375. xList, err := cross_varietyModel.GetChartTagVarietyListByTagAndVariety(tagX, varietyList)
  376. if err != nil {
  377. err = errors.New("获取X轴的品种指标配置信息失败,Err:" + err.Error())
  378. return
  379. }
  380. yList, err := cross_varietyModel.GetChartTagVarietyListByTagAndVariety(tagY, varietyList)
  381. if err != nil {
  382. err = errors.New("获取Y轴的品种指标配置信息失败,Err:" + err.Error())
  383. return
  384. }
  385. baseVarietyIdMap := make(map[int]int)
  386. for _, v := range xList {
  387. baseVarietyIdMap[v.ChartVarietyId] = v.ChartVarietyId
  388. }
  389. // 两个标签里面的品种并集
  390. needVarietyIdMap := make(map[int]int)
  391. for _, v := range yList {
  392. if val, ok := baseVarietyIdMap[v.ChartVarietyId]; ok {
  393. // 如果在 map2 中存在相同的键,则将键和值添加到结果中
  394. needVarietyIdMap[v.ChartVarietyId] = val
  395. }
  396. }
  397. for _, v := range xList {
  398. if _, ok := needVarietyIdMap[v.ChartVarietyId]; ok {
  399. xVarietyEdbMap[v.ChartVarietyId] = v.EdbInfoId
  400. edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
  401. }
  402. }
  403. for _, v := range yList {
  404. if _, ok := needVarietyIdMap[v.ChartVarietyId]; ok {
  405. yVarietyEdbMap[v.ChartVarietyId] = v.EdbInfoId
  406. edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
  407. }
  408. }
  409. return
  410. }
  411. // AddChartInfo
  412. // @Description: AddChartInfo
  413. // @author: Roc
  414. // @datetime 2023-11-24 15:58:14
  415. // @param req request.AddChartReq
  416. // @param sysUser *system.Admin
  417. // @return chartInfo *data_manage.ChartInfo
  418. // @return err error
  419. // @return errMsg string
  420. // @return isSendEmail bool
  421. func AddChartInfo(req request.AddChartReq, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  422. isSendEmail = true
  423. source := utils.CHART_SOURCE_CROSS_HEDGING
  424. req.ChartName = strings.Trim(req.ChartName, " ")
  425. if req.ChartName == "" {
  426. errMsg = "请填写图表名称!"
  427. err = errors.New(errMsg)
  428. isSendEmail = false
  429. return
  430. }
  431. if req.TagX <= 0 {
  432. errMsg = "请选择X轴坐标的标签!"
  433. err = errors.New(errMsg)
  434. isSendEmail = false
  435. return
  436. }
  437. if req.TagY <= 0 {
  438. errMsg = "请选择Y轴坐标的标签!"
  439. err = errors.New(errMsg)
  440. isSendEmail = false
  441. return
  442. }
  443. if req.CalculateValue <= 0 {
  444. errMsg = "请设置时间长度!"
  445. err = errors.New(errMsg)
  446. isSendEmail = false
  447. return
  448. }
  449. if req.CalculateUnit == `` {
  450. errMsg = "请设置时间频度!"
  451. err = errors.New(errMsg)
  452. isSendEmail = false
  453. return
  454. }
  455. // 品种配置
  456. if len(req.VarietyList) < 0 {
  457. errMsg = "请选择品种!"
  458. err = errors.New(errMsg)
  459. isSendEmail = false
  460. return
  461. }
  462. // 日期配置
  463. dateConfigList := len(req.DateConfigList)
  464. if dateConfigList < 0 {
  465. errMsg = "请选择日期!"
  466. err = errors.New(errMsg)
  467. isSendEmail = false
  468. return
  469. }
  470. if dateConfigList > 5 {
  471. errMsg = "日期数量已达上限!"
  472. err = errors.New(errMsg)
  473. isSendEmail = false
  474. return
  475. }
  476. // 基础配置转string
  477. extraConfigByte, err := json.Marshal(req)
  478. if err != nil {
  479. return
  480. }
  481. chartClassify, err := data_manage.GetCrossVarietyChartClassifyBySysUserId(sysUser.AdminId)
  482. if err != nil {
  483. if err.Error() != utils.ErrNoRow() {
  484. errMsg = "获取分类信息失败"
  485. err = errors.New("获取分类信息失败,Err:" + err.Error())
  486. return
  487. }
  488. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  489. chartClassify = &data_manage.ChartClassify{
  490. ChartClassifyId: 0,
  491. ChartClassifyName: sysUser.RealName,
  492. ParentId: 0,
  493. HasData: 0,
  494. CreateTime: time.Now(),
  495. ModifyTime: time.Now(),
  496. SysUserId: sysUser.AdminId,
  497. SysUserRealName: sysUser.RealName,
  498. Level: 1,
  499. UniqueCode: utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
  500. Sort: 0,
  501. Source: source,
  502. }
  503. }
  504. var chartInfoId int
  505. // 判断图表是否存在
  506. var condition string
  507. var pars []interface{}
  508. condition += " AND chart_name=? AND source = ? "
  509. pars = append(pars, req.ChartName, source)
  510. count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
  511. if err != nil {
  512. errMsg = "判断图表名称是否存在失败"
  513. err = errors.New("判断图表名称是否存在失败,Err:" + err.Error())
  514. return
  515. }
  516. if count > 0 {
  517. errMsg = "图表已存在,请重新填写"
  518. err = errors.New(errMsg)
  519. isSendEmail = false
  520. return
  521. }
  522. chartInfo = new(data_manage.ChartInfo)
  523. chartInfo.ChartName = req.ChartName
  524. //chartInfo.EdbInfoIds = edbInfoIdStr
  525. //chartInfo.ChartClassifyId = req.ChartClassifyId
  526. chartInfo.SysUserId = sysUser.AdminId
  527. chartInfo.SysUserRealName = sysUser.RealName
  528. chartInfo.CreateTime = time.Now()
  529. chartInfo.ModifyTime = time.Now()
  530. chartInfo.IsSetName = 0
  531. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  532. chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
  533. chartInfo.ChartType = 9 // 相关性图
  534. chartInfo.Calendar = "公历"
  535. chartInfo.DateType = 6
  536. //chartInfo.StartDate = req.StartDate
  537. //chartInfo.EndDate = req.EndDate
  538. //chartInfo.SeasonStartDate = req.StartDate
  539. //chartInfo.SeasonEndDate = req.EndDate
  540. chartInfo.LeftMin = req.LeftMin
  541. chartInfo.LeftMax = req.LeftMax
  542. //chartInfo.RightMin = req.RightMin
  543. //chartInfo.RightMax = req.RightMax
  544. //chartInfo.Disabled = disableVal
  545. chartInfo.Source = source
  546. chartInfo.ExtraConfig = string(extraConfigByte)
  547. // 图表品种
  548. chartVarietyMappingList := make([]*cross_varietyModel.ChartVarietyMapping, 0)
  549. for _, varietyId := range req.VarietyList {
  550. chartVarietyMappingList = append(chartVarietyMappingList, &cross_varietyModel.ChartVarietyMapping{
  551. Id: 0,
  552. ChartInfoId: 0,
  553. ChartVarietyId: varietyId,
  554. ModifyTime: time.Now(),
  555. CreateTime: time.Now(),
  556. })
  557. }
  558. // 图表配置
  559. chartInfoCrossVariety := &cross_varietyModel.ChartInfoCrossVariety{
  560. Id: 0,
  561. ChartInfoId: 0,
  562. ChartXTagId: req.TagX,
  563. ChartYTagId: req.TagY,
  564. CalculateValue: req.CalculateValue,
  565. CalculateUnit: req.CalculateUnit,
  566. ModifyTime: time.Now(),
  567. CreateTime: time.Now(),
  568. }
  569. // 新增图表和指标mapping
  570. chartInfoId, e := cross_varietyModel.CreateChart(chartInfo, chartClassify, chartVarietyMappingList, chartInfoCrossVariety)
  571. if e != nil {
  572. errMsg = "操作失败"
  573. err = errors.New("新增相关性图表失败, Err: " + e.Error())
  574. return
  575. }
  576. //添加es数据
  577. go data.EsAddOrEditChartInfo(chartInfoId)
  578. return
  579. }
  580. // EditChartInfo
  581. // @Description: 编辑图表
  582. // @author: Roc
  583. // @datetime 2023-11-24 15:58:31
  584. // @param req request.EditChartReq
  585. // @param sysUser *system.Admin
  586. // @return chartItem *data_manage.ChartInfo
  587. // @return err error
  588. // @return errMsg string
  589. // @return isSendEmail bool
  590. func EditChartInfo(req request.EditChartReq, sysUser *system.Admin) (chartItem *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
  591. isSendEmail = true
  592. chartItem, err = data_manage.GetChartInfoById(req.ChartInfoId)
  593. if err != nil {
  594. if err.Error() == utils.ErrNoRow() {
  595. errMsg = "图表已被删除,请刷新页面"
  596. err = errors.New(errMsg)
  597. isSendEmail = false
  598. return
  599. }
  600. errMsg = "获取图表信息失败"
  601. err = errors.New("获取图表信息失败,Err:" + err.Error())
  602. return
  603. }
  604. if chartItem.Source != utils.CHART_SOURCE_CROSS_HEDGING {
  605. errMsg = "该图不是跨品种分析图表!"
  606. err = errors.New(errMsg)
  607. isSendEmail = false
  608. return
  609. }
  610. req.ChartName = strings.Trim(req.ChartName, " ")
  611. if req.ChartName == "" {
  612. errMsg = "请填写图表名称!"
  613. err = errors.New(errMsg)
  614. isSendEmail = false
  615. return
  616. }
  617. if req.TagX <= 0 {
  618. errMsg = "请选择X轴坐标的标签!"
  619. err = errors.New(errMsg)
  620. isSendEmail = false
  621. return
  622. }
  623. if req.TagY <= 0 {
  624. errMsg = "请选择Y轴坐标的标签!"
  625. err = errors.New(errMsg)
  626. isSendEmail = false
  627. return
  628. }
  629. if req.CalculateValue <= 0 {
  630. errMsg = "请设置时间长度!"
  631. err = errors.New(errMsg)
  632. isSendEmail = false
  633. return
  634. }
  635. if req.CalculateUnit == `` {
  636. errMsg = "请设置时间频度!"
  637. err = errors.New(errMsg)
  638. isSendEmail = false
  639. return
  640. }
  641. // 品种配置
  642. if len(req.VarietyList) < 0 {
  643. errMsg = "请选择品种!"
  644. err = errors.New(errMsg)
  645. isSendEmail = false
  646. return
  647. }
  648. // 日期配置
  649. dateConfigList := len(req.DateConfigList)
  650. if dateConfigList < 0 {
  651. errMsg = "请选择日期!"
  652. err = errors.New(errMsg)
  653. isSendEmail = false
  654. return
  655. }
  656. if dateConfigList > 5 {
  657. errMsg = "日期数量已达上限!"
  658. err = errors.New(errMsg)
  659. isSendEmail = false
  660. return
  661. }
  662. // 基础配置转string
  663. extraConfigByte, err := json.Marshal(req)
  664. if err != nil {
  665. return
  666. }
  667. // 图表操作权限
  668. ok := data.CheckOpChartPermission(sysUser, chartItem.SysUserId)
  669. if !ok {
  670. errMsg = "没有该图表的操作权限"
  671. err = errors.New(errMsg)
  672. isSendEmail = false
  673. return
  674. }
  675. //判断图表是否存在
  676. var condition string
  677. var pars []interface{}
  678. condition += " AND chart_info_id <> ? "
  679. pars = append(pars, req.ChartInfoId)
  680. condition += " AND chart_name=? AND source = ? "
  681. pars = append(pars, req.ChartName, chartItem.Source)
  682. count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
  683. if err != nil {
  684. errMsg = "判断图表名称是否存在失败"
  685. err = errors.New("判断图表名称是否存在失败,Err:" + err.Error())
  686. return
  687. }
  688. if count > 0 {
  689. errMsg = "图表已存在,请重新填写"
  690. err = errors.New(errMsg)
  691. isSendEmail = false
  692. return
  693. }
  694. chartItem.ChartName = req.ChartName
  695. chartItem.ExtraConfig = string(extraConfigByte)
  696. chartItem.ModifyTime = time.Now()
  697. chartUpdateCols := []string{"ChartName", "ExtraConfig", "ModifyTime"}
  698. // 跨品种分析配置
  699. chartInfoCrossVariety, err := cross_varietyModel.GetChartInfoCrossVarietyByChartInfoId(chartItem.ChartInfoId)
  700. if err != nil {
  701. return
  702. }
  703. chartInfoCrossVariety.ChartXTagId = req.TagX
  704. chartInfoCrossVariety.ChartYTagId = req.TagY
  705. chartInfoCrossVariety.CalculateValue = req.CalculateValue
  706. chartInfoCrossVariety.CalculateUnit = req.CalculateUnit
  707. chartInfoCrossVariety.ModifyTime = time.Now()
  708. chartInfoCrossVarietyUpdateCols := []string{"ChartXTagId", "ChartYTagId", "CalculateValue", "CalculateUnit", "ModifyTime"}
  709. // 图表品种
  710. chartVarietyMappingList := make([]*cross_varietyModel.ChartVarietyMapping, 0)
  711. for _, varietyId := range req.VarietyList {
  712. chartVarietyMappingList = append(chartVarietyMappingList, &cross_varietyModel.ChartVarietyMapping{
  713. Id: 0,
  714. ChartInfoId: 0,
  715. ChartVarietyId: varietyId,
  716. ModifyTime: time.Now(),
  717. CreateTime: time.Now(),
  718. })
  719. }
  720. err = cross_varietyModel.EditChart(chartItem, chartVarietyMappingList, chartInfoCrossVariety,
  721. chartUpdateCols, chartInfoCrossVarietyUpdateCols)
  722. if err != nil {
  723. errMsg = "保存失败"
  724. err = errors.New("保存失败,Err:" + err.Error())
  725. return
  726. }
  727. resp := new(data_manage.AddChartInfoResp)
  728. resp.ChartInfoId = chartItem.ChartInfoId
  729. resp.UniqueCode = chartItem.UniqueCode
  730. //resp.ChartType = req.ChartType
  731. //添加es数据
  732. go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
  733. //修改my eta es数据
  734. go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
  735. return
  736. }