chart.go 21 KB

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