index.go 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. package ai_predict_model
  2. import (
  3. "encoding/json"
  4. "eta/eta_api/controllers"
  5. "eta/eta_api/models"
  6. aiPredictModel "eta/eta_api/models/ai_predict_model"
  7. dataSourceModel "eta/eta_api/models/data_source"
  8. "eta/eta_api/models/system"
  9. "eta/eta_api/services"
  10. "eta/eta_api/services/elastic"
  11. "eta/eta_api/utils"
  12. "fmt"
  13. "github.com/rdlucklib/rdluck_tools/paging"
  14. "github.com/tealeg/xlsx"
  15. "os"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. // AiPredictModelIndexController AI预测模型标的
  21. type AiPredictModelIndexController struct {
  22. controllers.BaseAuthController
  23. }
  24. // List
  25. // @Title 标的列表
  26. // @Description 标的列表
  27. // @Param PageSize query int true "每页数据条数"
  28. // @Param CurrentIndex query int true "当前页页码,从1开始"
  29. // @Param ClassifyId query int false "分类id"
  30. // @Param IndexId query int false "模型标的ID"
  31. // @Param Keyword query string false "搜索关键词"
  32. // @Success 200 {object} data_manage.ChartListResp
  33. // @router /index/list [get]
  34. func (this *AiPredictModelIndexController) List() {
  35. br := new(models.BaseResponse).Init()
  36. defer func() {
  37. this.Data["json"] = br
  38. this.ServeJSON()
  39. }()
  40. sysUser := this.SysUser
  41. if sysUser == nil {
  42. br.Msg = "请登录"
  43. br.ErrMsg = "请登录,SysUser Is Empty"
  44. br.Ret = 408
  45. return
  46. }
  47. pageSize, _ := this.GetInt("PageSize")
  48. currentIndex, _ := this.GetInt("CurrentIndex")
  49. classifyId, _ := this.GetInt("ClassifyId")
  50. indexId, _ := this.GetInt("IndexId")
  51. keyword := this.GetString("KeyWord")
  52. if keyword == "" {
  53. keyword = this.GetString("Keyword")
  54. }
  55. keyword = strings.TrimSpace(keyword)
  56. resp := new(aiPredictModel.AiPredictModelIndexPageListResp)
  57. // 分页
  58. var startSize int
  59. if pageSize <= 0 {
  60. pageSize = utils.PageSize20
  61. }
  62. if currentIndex <= 0 {
  63. currentIndex = 1
  64. }
  65. startSize = paging.StartIndex(currentIndex, pageSize)
  66. // 分类
  67. classifyIdName := make(map[int]string)
  68. {
  69. classifyOb := new(aiPredictModel.AiPredictModelClassify)
  70. list, e := classifyOb.GetItemsByCondition("", make([]interface{}, 0), []string{}, "")
  71. if e != nil {
  72. br.Msg = "获取失败"
  73. br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
  74. return
  75. }
  76. for _, v := range list {
  77. classifyIdName[v.AiPredictModelClassifyId] = v.ClassifyName
  78. }
  79. }
  80. // 筛选条件
  81. highlightMap := make(map[int]string)
  82. indexOb := new(aiPredictModel.AiPredictModelIndex)
  83. var cond string
  84. var pars []interface{}
  85. {
  86. if indexId > 0 {
  87. cond += fmt.Sprintf(" AND %s = ?", indexOb.Cols().PrimaryId)
  88. pars = append(pars, indexId)
  89. }
  90. if classifyId > 0 {
  91. cond += fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
  92. pars = append(pars, classifyId)
  93. }
  94. //if keyword != "" {
  95. // cond += fmt.Sprintf(" AND %s LIKE ?", indexOb.Cols().IndexName)
  96. // pars = append(pars, fmt.Sprint("%", keyword, "%"))
  97. //}
  98. // 有关键词从es中搜索
  99. if keyword != "" {
  100. _, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, utils.DATA_SOURCE_AI_PREDICT_MODEL, 0, []int{}, []int{}, []string{}, startSize, pageSize)
  101. if e != nil {
  102. br.Msg = "获取失败"
  103. br.ErrMsg = fmt.Sprintf("ES-搜索手工指标列表失败, %v", e)
  104. return
  105. }
  106. if len(list) == 0 {
  107. resp.List = make([]*aiPredictModel.AiPredictModelIndexItem, 0)
  108. br.Ret = 200
  109. br.Success = true
  110. br.Msg = "获取成功"
  111. br.Data = resp
  112. return
  113. }
  114. var ids []int
  115. for _, v := range list {
  116. ids = append(ids, v.PrimaryId)
  117. highlightMap[v.PrimaryId] = v.SearchText
  118. }
  119. cond += fmt.Sprintf(` AND %s IN (%s)`, indexOb.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
  120. pars = append(pars, ids)
  121. }
  122. }
  123. // 获取列表
  124. total, e := indexOb.GetCountByCondition(cond, pars)
  125. if e != nil {
  126. br.Msg = "获取失败"
  127. br.ErrMsg = fmt.Sprintf("获取标的总数失败, %v", e)
  128. return
  129. }
  130. list, e := indexOb.GetPageItemsByCondition(cond, pars, []string{}, "", startSize, pageSize)
  131. if e != nil {
  132. br.Msg = "获取失败"
  133. br.ErrMsg = fmt.Sprintf("获取分页列表失败, %v", e)
  134. return
  135. }
  136. pageList := make([]*aiPredictModel.AiPredictModelIndexItem, 0)
  137. for _, v := range list {
  138. t := v.Format2Item()
  139. t.ClassifyName = classifyIdName[v.ClassifyId]
  140. // 搜索高亮
  141. t.SearchText = v.IndexName
  142. s := highlightMap[v.AiPredictModelIndexId]
  143. if s != "" {
  144. t.SearchText = s
  145. }
  146. pageList = append(pageList, t)
  147. }
  148. page := paging.GetPaging(currentIndex, pageSize, total)
  149. resp.Paging = page
  150. resp.List = pageList
  151. br.Data = resp
  152. br.Ret = 200
  153. br.Success = true
  154. br.Msg = "获取成功"
  155. }
  156. // Import
  157. // @Title 导入标的和数据
  158. // @Description 导入标的和数据
  159. // @Param IndexFile query file true "标的文件"
  160. // @Success 200 Ret=200 录入成功
  161. // @router /index/import [post]
  162. func (this *AiPredictModelIndexController) Import() {
  163. br := new(models.BaseResponse).Init()
  164. defer func() {
  165. if br.ErrMsg == "" {
  166. br.IsSendEmail = false
  167. }
  168. this.Data["json"] = br
  169. this.ServeJSON()
  170. }()
  171. sysUser := this.SysUser
  172. if sysUser == nil {
  173. br.Msg = "请登录"
  174. br.ErrMsg = "请登录,SysUser Is Empty"
  175. br.Ret = 408
  176. return
  177. }
  178. file, _, e := this.GetFile("IndexFile")
  179. if e != nil {
  180. br.Msg = "导入失败"
  181. br.ErrMsg = fmt.Sprintf("获取文件失败, %v", e)
  182. return
  183. }
  184. path := "./static/ai_predict_model_temp_" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
  185. defer func() {
  186. _ = file.Close()
  187. _ = os.Remove(path)
  188. }()
  189. if e = this.SaveToFile("IndexFile", path); e != nil {
  190. br.Msg = "导入失败"
  191. br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e)
  192. return
  193. }
  194. xlFile, e := xlsx.OpenFile(path)
  195. if e != nil {
  196. br.Msg = "导入失败"
  197. br.ErrMsg = fmt.Sprintf("打开excel文件失败, %v", e)
  198. return
  199. }
  200. // 获取分类和用户,遍历时校验
  201. classifyNameId := make(map[string]int)
  202. adminNameId := make(map[string]int)
  203. {
  204. classifyOb := new(aiPredictModel.AiPredictModelClassify)
  205. classifyCond := fmt.Sprintf(` AND %s = ?`, classifyOb.Cols().ParentId)
  206. classifyPars := make([]interface{}, 0)
  207. classifyPars = append(classifyPars, 0) // 只取一级分类(临时过渡方案,业务端只会加一级)
  208. classifies, e := classifyOb.GetItemsByCondition(classifyCond, classifyPars, []string{}, "")
  209. if e != nil {
  210. br.Msg = "导入失败"
  211. br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
  212. return
  213. }
  214. for _, v := range classifies {
  215. classifyNameId[v.ClassifyName] = v.AiPredictModelClassifyId
  216. }
  217. admins, e := system.GetSysAdminList(``, make([]interface{}, 0), []string{}, "")
  218. if e != nil {
  219. br.Msg = "导入失败"
  220. br.ErrMsg = fmt.Sprintf("获取用户失败, %v", e)
  221. return
  222. }
  223. for _, v := range admins {
  224. adminNameId[v.RealName] = v.AdminId
  225. }
  226. }
  227. // 遍历sheet页
  228. // 列表页:预测标的|分类|模型框架|创建人|预测日期|预测值|预测频度|方向准确率|绝对偏差
  229. type ImportDataColKey struct {
  230. IndexName string
  231. ColKey int
  232. DataDate time.Time
  233. }
  234. imports := make(map[string]*aiPredictModel.AiPredictModelImportData)
  235. importsData := make(map[string]map[time.Time]*aiPredictModel.AiPredictModelData)
  236. importsDailyData := make(map[string]map[time.Time]*aiPredictModel.AiPredictModelData)
  237. for sheetKey, sheet := range xlFile.Sheets {
  238. maxRow := sheet.MaxRow
  239. // 列表页
  240. if sheetKey == 0 {
  241. for i := 0; i < maxRow; i++ {
  242. // 忽略首行标题
  243. if i < 1 {
  244. continue
  245. }
  246. row := sheet.Row(i)
  247. cells := row.Cells
  248. if len(cells) < 9 {
  249. continue
  250. }
  251. // 标的名称
  252. indexName := strings.TrimSpace(cells[0].String())
  253. if indexName == "" {
  254. continue
  255. }
  256. if imports[indexName] == nil {
  257. imports[indexName] = new(aiPredictModel.AiPredictModelImportData)
  258. imports[indexName].Index = new(aiPredictModel.AiPredictModelIndex)
  259. imports[indexName].Data = make([]*aiPredictModel.AiPredictModelData, 0)
  260. }
  261. imports[indexName].Index.IndexName = indexName
  262. imports[indexName].Index.CreateTime = time.Now()
  263. imports[indexName].Index.ModifyTime = time.Now()
  264. // 分类
  265. classifyName := strings.TrimSpace(cells[1].String())
  266. if classifyNameId[classifyName] <= 0 {
  267. br.Msg = fmt.Sprintf("分类:%s不存在", classifyName)
  268. return
  269. }
  270. imports[indexName].Index.ClassifyId = classifyNameId[classifyName]
  271. // 创建人
  272. adminName := strings.TrimSpace(cells[3].String())
  273. if adminNameId[adminName] <= 0 {
  274. br.Msg = fmt.Sprintf("创建人:%s不存在", adminName)
  275. return
  276. }
  277. imports[indexName].Index.SysUserId = adminNameId[adminName]
  278. imports[indexName].Index.SysUserRealName = adminName
  279. // 其余信息
  280. imports[indexName].Index.ModelFramework = strings.TrimSpace(cells[2].String())
  281. strDate := strings.TrimSpace(cells[4].String())
  282. predictDate, _ := time.Parse("2006/01/02", strDate)
  283. if predictDate.IsZero() {
  284. predictDate, _ = time.Parse("01-02-06", strDate)
  285. if predictDate.IsZero() {
  286. predictDate, _ = time.Parse("2006/1/2", strDate)
  287. }
  288. }
  289. imports[indexName].Index.PredictDate = predictDate
  290. strVal := strings.TrimSpace(cells[5].String())
  291. if strVal == "" {
  292. continue
  293. }
  294. predictVal, _ := strconv.ParseFloat(strVal, 64)
  295. imports[indexName].Index.PredictValue = predictVal
  296. imports[indexName].Index.PredictFrequency = strings.TrimSpace(cells[6].String())
  297. imports[indexName].Index.DirectionAccuracy = strings.TrimSpace(cells[7].String())
  298. imports[indexName].Index.AbsoluteDeviation = strings.TrimSpace(cells[8].String())
  299. }
  300. }
  301. // 月度数据页
  302. if sheetKey == 1 {
  303. // 每五列为一个指标的数据
  304. colKeys := make(map[int]*ImportDataColKey) // 每一列对应的指标名称以及对应的字段序号
  305. for i := 0; i < maxRow; i++ {
  306. // 首行为指标名称
  307. if i == 0 {
  308. nameCol := 0
  309. row := sheet.Row(i)
  310. for ck, cell := range row.Cells {
  311. nameCol += 1
  312. if nameCol > 5 {
  313. nameCol = 1
  314. }
  315. if nameCol == 1 {
  316. // nameCol=1时为指标/数据行则为日期
  317. indexName := strings.TrimSpace(cell.String())
  318. if indexName == "" {
  319. continue
  320. }
  321. importsData[indexName] = make(map[time.Time]*aiPredictModel.AiPredictModelData)
  322. colKeys[ck] = &ImportDataColKey{
  323. ColKey: 1,
  324. IndexName: indexName,
  325. }
  326. // 后面四列分别对应: 实际值|预测值|方向|偏差率, 这里直接加无须考虑是否会越界
  327. colKeys[ck+1] = &ImportDataColKey{
  328. ColKey: 2,
  329. IndexName: indexName,
  330. }
  331. colKeys[ck+2] = &ImportDataColKey{
  332. ColKey: 3,
  333. IndexName: indexName,
  334. }
  335. colKeys[ck+3] = &ImportDataColKey{
  336. ColKey: 4,
  337. IndexName: indexName,
  338. }
  339. colKeys[ck+4] = &ImportDataColKey{
  340. ColKey: 5,
  341. IndexName: indexName,
  342. }
  343. continue
  344. }
  345. }
  346. continue
  347. }
  348. // 第二行为标题,跳过
  349. if i == 1 {
  350. continue
  351. }
  352. // 剩余为数据行
  353. row := sheet.Row(i)
  354. for ck, cell := range row.Cells {
  355. if colKeys[ck] == nil {
  356. continue
  357. }
  358. if colKeys[ck].IndexName == "" {
  359. continue
  360. }
  361. switch colKeys[ck].ColKey {
  362. case 1:
  363. // 日期列
  364. strDate := strings.TrimSpace(cell.String())
  365. dataDate, _ := time.Parse("2006/01/02", strDate)
  366. if dataDate.IsZero() {
  367. dataDate, _ = time.Parse("01-02-06", strDate)
  368. if dataDate.IsZero() {
  369. dataDate, _ = time.Parse("2006/1/2", strDate)
  370. if dataDate.IsZero() {
  371. continue
  372. }
  373. }
  374. }
  375. colKeys[ck].DataDate = dataDate
  376. colKeys[ck+1].DataDate = dataDate
  377. colKeys[ck+2].DataDate = dataDate
  378. colKeys[ck+3].DataDate = dataDate
  379. colKeys[ck+4].DataDate = dataDate
  380. importRow := imports[colKeys[ck].IndexName]
  381. if importRow == nil {
  382. continue
  383. }
  384. // 新增当前日期数据
  385. importsData[colKeys[ck].IndexName][dataDate] = new(aiPredictModel.AiPredictModelData)
  386. importsData[colKeys[ck].IndexName][dataDate].DataTime = dataDate
  387. importsData[colKeys[ck].IndexName][dataDate].CreateTime = time.Now()
  388. importsData[colKeys[ck].IndexName][dataDate].ModifyTime = time.Now()
  389. importsData[colKeys[ck].IndexName][dataDate].Source = aiPredictModel.ModelDataSourceMonthly
  390. case 2, 3:
  391. // 实际值和预测值, 可能为空
  392. dataDate := colKeys[ck].DataDate
  393. if importsData[colKeys[ck].IndexName][dataDate] == nil {
  394. continue
  395. }
  396. strVal := strings.TrimSpace(cell.String())
  397. if strVal == "" {
  398. continue
  399. }
  400. val, _ := strconv.ParseFloat(strVal, 64)
  401. if colKeys[ck].ColKey == 2 {
  402. importsData[colKeys[ck].IndexName][dataDate].Value.Valid = true
  403. importsData[colKeys[ck].IndexName][dataDate].Value.Float64 = val
  404. } else {
  405. importsData[colKeys[ck].IndexName][dataDate].PredictValue.Valid = true
  406. importsData[colKeys[ck].IndexName][dataDate].PredictValue.Float64 = val
  407. }
  408. case 4, 5:
  409. // 方向/偏差率
  410. dataDate := colKeys[ck].DataDate
  411. if importsData[colKeys[ck].IndexName][dataDate] == nil {
  412. continue
  413. }
  414. str := strings.TrimSpace(cell.String())
  415. if str == "" {
  416. continue
  417. }
  418. if colKeys[ck].ColKey == 4 {
  419. importsData[colKeys[ck].IndexName][dataDate].Direction = str
  420. } else {
  421. importsData[colKeys[ck].IndexName][dataDate].DeviationRate = str
  422. }
  423. default:
  424. continue
  425. }
  426. }
  427. }
  428. }
  429. // 日度数据页
  430. if sheetKey == 2 {
  431. // 每3列为一个指标的数据
  432. colKeys := make(map[int]*ImportDataColKey) // 每一列对应的指标名称以及对应的字段序号
  433. for i := 0; i < maxRow; i++ {
  434. // 首行为指标名称
  435. if i == 0 {
  436. nameCol := 0
  437. row := sheet.Row(i)
  438. for ck, cell := range row.Cells {
  439. nameCol += 1
  440. if nameCol > 3 {
  441. nameCol = 1
  442. }
  443. if nameCol == 1 {
  444. // nameCol=1时为指标/数据行则为日期
  445. indexName := strings.TrimSpace(cell.String())
  446. if indexName == "" {
  447. continue
  448. }
  449. importsDailyData[indexName] = make(map[time.Time]*aiPredictModel.AiPredictModelData)
  450. colKeys[ck] = &ImportDataColKey{
  451. ColKey: 1,
  452. IndexName: indexName,
  453. }
  454. // 后面两列分别对应: 实际值|预测值, 这里直接加无须考虑是否会越界
  455. colKeys[ck+1] = &ImportDataColKey{
  456. ColKey: 2,
  457. IndexName: indexName,
  458. }
  459. colKeys[ck+2] = &ImportDataColKey{
  460. ColKey: 3,
  461. IndexName: indexName,
  462. }
  463. continue
  464. }
  465. }
  466. continue
  467. }
  468. // 第二行为标题,遇到"预测值"单元格,需要取出其中的值作为预测图例名称
  469. if i == 1 {
  470. row := sheet.Row(i)
  471. for ck, cell := range row.Cells {
  472. if colKeys[ck] == nil {
  473. continue
  474. }
  475. if colKeys[ck].IndexName == "" {
  476. continue
  477. }
  478. if colKeys[ck].ColKey != 3 {
  479. continue
  480. }
  481. if imports[colKeys[ck].IndexName] != nil && imports[colKeys[ck].IndexName].Index != nil {
  482. var extraConfig aiPredictModel.AiPredictModelIndexExtraConfig
  483. extraConfig.DailyChart.PredictLegendName = strings.TrimSpace(cell.String())
  484. b, _ := json.Marshal(extraConfig)
  485. imports[colKeys[ck].IndexName].Index.ExtraConfig = string(b)
  486. }
  487. }
  488. continue
  489. }
  490. // 剩余为数据行
  491. row := sheet.Row(i)
  492. for ck, cell := range row.Cells {
  493. if colKeys[ck] == nil {
  494. continue
  495. }
  496. if colKeys[ck].IndexName == "" {
  497. continue
  498. }
  499. switch colKeys[ck].ColKey {
  500. case 1:
  501. // 日期列
  502. strDate := strings.TrimSpace(cell.String())
  503. dataDate, _ := time.Parse("2006/01/02", strDate)
  504. if dataDate.IsZero() {
  505. dataDate, _ = time.Parse("01-02-06", strDate)
  506. if dataDate.IsZero() {
  507. dataDate, _ = time.Parse("2006/1/2", strDate)
  508. if dataDate.IsZero() {
  509. continue
  510. }
  511. }
  512. }
  513. colKeys[ck].DataDate = dataDate
  514. colKeys[ck+1].DataDate = dataDate
  515. colKeys[ck+2].DataDate = dataDate
  516. importRow := imports[colKeys[ck].IndexName]
  517. if importRow == nil {
  518. continue
  519. }
  520. // 新增当前日期数据
  521. importsDailyData[colKeys[ck].IndexName][dataDate] = new(aiPredictModel.AiPredictModelData)
  522. importsDailyData[colKeys[ck].IndexName][dataDate].DataTime = dataDate
  523. importsDailyData[colKeys[ck].IndexName][dataDate].CreateTime = time.Now()
  524. importsDailyData[colKeys[ck].IndexName][dataDate].ModifyTime = time.Now()
  525. importsDailyData[colKeys[ck].IndexName][dataDate].Source = aiPredictModel.ModelDataSourceDaily
  526. case 2, 3:
  527. // 实际值和预测值, 可能为空
  528. dataDate := colKeys[ck].DataDate
  529. if importsDailyData[colKeys[ck].IndexName][dataDate] == nil {
  530. continue
  531. }
  532. strVal := strings.TrimSpace(cell.String())
  533. if strVal == "" {
  534. continue
  535. }
  536. val, _ := strconv.ParseFloat(strVal, 64)
  537. if colKeys[ck].ColKey == 2 {
  538. importsDailyData[colKeys[ck].IndexName][dataDate].Value.Valid = true
  539. importsDailyData[colKeys[ck].IndexName][dataDate].Value.Float64 = val
  540. } else {
  541. importsDailyData[colKeys[ck].IndexName][dataDate].PredictValue.Valid = true
  542. importsDailyData[colKeys[ck].IndexName][dataDate].PredictValue.Float64 = val
  543. }
  544. default:
  545. continue
  546. }
  547. }
  548. }
  549. }
  550. }
  551. for indexName, v := range importsData {
  552. if imports[indexName] == nil {
  553. continue
  554. }
  555. for _, dateData := range v {
  556. imports[indexName].Data = append(imports[indexName].Data, dateData)
  557. }
  558. }
  559. for indexName, v := range importsDailyData {
  560. if imports[indexName] == nil {
  561. continue
  562. }
  563. for _, dateData := range v {
  564. imports[indexName].Data = append(imports[indexName].Data, dateData)
  565. }
  566. }
  567. importIndexes := make([]*aiPredictModel.AiPredictModelImportData, 0)
  568. for _, v := range imports {
  569. importIndexes = append(importIndexes, v)
  570. }
  571. // 导入指标
  572. if e = services.ImportAiPredictModelIndexAndData(importIndexes); e != nil {
  573. br.Msg = "操作失败"
  574. br.ErrMsg = fmt.Sprintf("导入指标数据失败, %v", e)
  575. return
  576. }
  577. // 写入es
  578. go func() {
  579. for _, v := range importIndexes {
  580. indexItem := new(dataSourceModel.SearchDataSource)
  581. indexItem.PrimaryId = v.Index.AiPredictModelIndexId
  582. indexItem.IndexName = v.Index.IndexName
  583. indexItem.IndexCode = v.Index.IndexCode
  584. indexItem.ClassifyId = v.Index.ClassifyId
  585. indexItem.Source = utils.DATA_SOURCE_AI_PREDICT_MODEL
  586. indexItem.SourceName = "AI预测模型"
  587. indexItem.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.Index.CreateTime)
  588. indexItem.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, v.Index.ModifyTime)
  589. docId := fmt.Sprintf("%d-%d", indexItem.Source, indexItem.PrimaryId)
  590. if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
  591. utils.FileLog.Info("AI预测模型-写入es失败, %v", e)
  592. continue
  593. }
  594. }
  595. }()
  596. br.Ret = 200
  597. br.Success = true
  598. br.Msg = "操作成功"
  599. }
  600. // Detail
  601. // @Title 标的详情
  602. // @Description 标的详情
  603. // @Param IndexId query int true "标的ID"
  604. // @Success 200 {object} data_manage.ChartListResp
  605. // @router /index/detail [get]
  606. func (this *AiPredictModelIndexController) Detail() {
  607. br := new(models.BaseResponse).Init()
  608. defer func() {
  609. if br.ErrMsg == "" {
  610. br.IsSendEmail = false
  611. }
  612. this.Data["json"] = br
  613. this.ServeJSON()
  614. }()
  615. sysUser := this.SysUser
  616. if sysUser == nil {
  617. br.Msg = "请登录"
  618. br.ErrMsg = "请登录,SysUser Is Empty"
  619. br.Ret = 408
  620. return
  621. }
  622. indexId, _ := this.GetInt("IndexId")
  623. if indexId <= 0 {
  624. br.Msg = "参数有误"
  625. br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", indexId)
  626. return
  627. }
  628. resp := new(aiPredictModel.AiPredictModelDetailResp)
  629. indexOb := new(aiPredictModel.AiPredictModelIndex)
  630. indexItem, e := indexOb.GetItemById(indexId)
  631. if e != nil {
  632. if e.Error() == utils.ErrNoRow() {
  633. br.Msg = "标的已被删除,请刷新页面"
  634. return
  635. }
  636. br.Msg = "获取失败"
  637. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  638. return
  639. }
  640. // 获取标的数据
  641. monthData, dailyData := make([]*aiPredictModel.AiPredictModelData, 0), make([]*aiPredictModel.AiPredictModelData, 0)
  642. {
  643. tableData := make([]*aiPredictModel.AiPredictModelDataItem, 0)
  644. dataOb := new(aiPredictModel.AiPredictModelData)
  645. dataCond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().IndexCode)
  646. dataPars := make([]interface{}, 0)
  647. dataPars = append(dataPars, indexItem.IndexCode)
  648. list, e := dataOb.GetItemsByCondition(dataCond, dataPars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
  649. if e != nil {
  650. br.Msg = "获取失败"
  651. br.ErrMsg = fmt.Sprintf("获取标的数据失败, %v", e)
  652. return
  653. }
  654. // tableData取月度数据,最多显示10条
  655. count, limit := 0, 10
  656. for _, v := range list {
  657. // 日度数据
  658. if v.Source == aiPredictModel.ModelDataSourceDaily {
  659. dailyData = append(dailyData, v)
  660. continue
  661. }
  662. // 月度数据
  663. if count < limit {
  664. tableData = append(tableData, v.Format2Item())
  665. count += 1
  666. }
  667. monthData = append(monthData, v)
  668. }
  669. resp.TableData = tableData
  670. }
  671. // 月度图表
  672. if len(monthData) > 0 {
  673. chartDetail, e := services.GetAiPredictChartDetailByData(indexItem, monthData, aiPredictModel.ModelDataSourceMonthly)
  674. if e != nil {
  675. br.Msg = "获取失败"
  676. br.ErrMsg = fmt.Sprintf("获取月度图表失败, %v", e)
  677. return
  678. }
  679. resp.ChartView = chartDetail
  680. }
  681. // 日度图表
  682. if len(dailyData) > 0 {
  683. dailyChartDetail, e := services.GetAiPredictChartDetailByData(indexItem, dailyData, aiPredictModel.ModelDataSourceDaily)
  684. if e != nil {
  685. br.Msg = "获取失败"
  686. br.ErrMsg = fmt.Sprintf("获取日度图表失败, %v", e)
  687. return
  688. }
  689. resp.DailyChartView = dailyChartDetail
  690. }
  691. br.Data = resp
  692. br.Ret = 200
  693. br.Success = true
  694. br.Msg = "获取成功"
  695. }
  696. // Save
  697. // @Title 保存标的
  698. // @Description 保存标的
  699. // @Param request body aiPredictModel.AiPredictModelIndexSaveReq true "type json string"
  700. // @Success 200 Ret=200 保存成功
  701. // @router /index/save [post]
  702. func (this *AiPredictModelIndexController) Save() {
  703. br := new(models.BaseResponse).Init()
  704. defer func() {
  705. if br.ErrMsg == "" {
  706. br.IsSendEmail = false
  707. }
  708. this.Data["json"] = br
  709. this.ServeJSON()
  710. }()
  711. sysUser := this.SysUser
  712. if sysUser == nil {
  713. br.Msg = "请登录"
  714. br.ErrMsg = "请登录,SysUser Is Empty"
  715. br.Ret = 408
  716. return
  717. }
  718. var req aiPredictModel.AiPredictModelIndexSaveReq
  719. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  720. br.Msg = "参数解析异常"
  721. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  722. return
  723. }
  724. if req.IndexId < 0 {
  725. br.Msg = "参数有误"
  726. br.ErrMsg = fmt.Sprintf("标的ID有误, IndexId: %d", req.IndexId)
  727. return
  728. }
  729. indexOb := new(aiPredictModel.AiPredictModelIndex)
  730. indexItem, e := indexOb.GetItemById(req.IndexId)
  731. if e != nil {
  732. if e.Error() == utils.ErrNoRow() {
  733. br.Msg = "标的已被删除,请刷新页面"
  734. return
  735. }
  736. br.Msg = "操作失败"
  737. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  738. return
  739. }
  740. var extraConfig aiPredictModel.AiPredictModelIndexExtraConfig
  741. if indexItem.ExtraConfig != "" {
  742. if e = json.Unmarshal([]byte(indexItem.ExtraConfig), &extraConfig); e != nil {
  743. br.Msg = "操作失败"
  744. br.ErrMsg = fmt.Sprintf("标的配置解析失败, %v", e)
  745. return
  746. }
  747. }
  748. if req.MonthlyChart != nil {
  749. extraConfig.MonthlyChart.LeftMin = req.MonthlyChart.LeftMin
  750. extraConfig.MonthlyChart.LeftMax = req.MonthlyChart.LeftMax
  751. extraConfig.MonthlyChart.Unit = req.MonthlyChart.Unit
  752. }
  753. if req.DailyChart != nil {
  754. extraConfig.DailyChart.LeftMin = req.DailyChart.LeftMin
  755. extraConfig.DailyChart.LeftMax = req.DailyChart.LeftMax
  756. extraConfig.DailyChart.Unit = req.DailyChart.Unit
  757. }
  758. configByte, _ := json.Marshal(extraConfig)
  759. indexItem.ExtraConfig = string(configByte)
  760. indexItem.ModifyTime = time.Now()
  761. updateCols := []string{indexOb.Cols().ExtraConfig, indexOb.Cols().ModifyTime}
  762. if e = indexItem.Update(updateCols); e != nil {
  763. br.Msg = "操作失败"
  764. br.ErrMsg = fmt.Sprintf("保存标的失败, %v", e)
  765. return
  766. }
  767. br.Ret = 200
  768. br.Msg = "操作成功"
  769. br.Success = true
  770. }
  771. // DashboardSave
  772. // @Title 保存看板
  773. // @Description 保存看板
  774. // @Param request body aiPredictModel.AiPredictModelDashboardSaveReq true "type json string"
  775. // @Success 200 Ret=200 新增成功
  776. // @router /index/dashboard/save [post]
  777. func (this *AiPredictModelIndexController) DashboardSave() {
  778. br := new(models.BaseResponse).Init()
  779. defer func() {
  780. if br.ErrMsg == "" {
  781. br.IsSendEmail = false
  782. }
  783. this.Data["json"] = br
  784. this.ServeJSON()
  785. }()
  786. sysUser := this.SysUser
  787. if sysUser == nil {
  788. br.Msg = "请登录"
  789. br.ErrMsg = "请登录,SysUser Is Empty"
  790. br.Ret = 408
  791. return
  792. }
  793. var req aiPredictModel.AiPredictModelDashboardSaveReq
  794. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  795. br.Msg = "参数解析异常"
  796. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  797. return
  798. }
  799. if req.IndexId <= 0 {
  800. br.Msg = "参数有误"
  801. br.ErrMsg = fmt.Sprintf("参数有误, %d", req.IndexId)
  802. return
  803. }
  804. req.DashboardName = strings.TrimSpace(req.DashboardName)
  805. indexOb := new(aiPredictModel.AiPredictModelIndex)
  806. _, e := indexOb.GetItemById(req.IndexId)
  807. if e != nil {
  808. if e.Error() == utils.ErrNoRow() {
  809. br.Msg = "标的已被删除,请刷新页面"
  810. return
  811. }
  812. br.Msg = "操作失败"
  813. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  814. return
  815. }
  816. // 获取看板
  817. var isUpdate bool
  818. var updateCols []string
  819. dashboardItem := new(aiPredictModel.AiPredictModelDashboard)
  820. if req.IndexId > 0 {
  821. cond := fmt.Sprintf(" AND %s = ?", dashboardItem.Cols().AiPredictModelIndexId)
  822. pars := make([]interface{}, 0)
  823. pars = append(pars, req.IndexId)
  824. item, e := dashboardItem.GetItemByCondition(cond, pars, "")
  825. if e != nil && e.Error() != utils.ErrNoRow() {
  826. br.Msg = "操作失败"
  827. br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
  828. return
  829. }
  830. if item != nil {
  831. isUpdate = true
  832. dashboardItem = item
  833. dashboardItem.DashboardName = req.DashboardName
  834. dashboardItem.ModifyTime = time.Now()
  835. updateCols = append(updateCols, dashboardItem.Cols().DashboardName, dashboardItem.Cols().ModifyTime)
  836. }
  837. }
  838. if !isUpdate {
  839. dashboardItem.AiPredictModelIndexId = req.IndexId
  840. dashboardItem.DashboardName = req.DashboardName
  841. dashboardItem.SysUserId = sysUser.AdminId
  842. dashboardItem.SysUserRealName = sysUser.RealName
  843. dashboardItem.CreateTime = time.Now()
  844. dashboardItem.ModifyTime = time.Now()
  845. }
  846. // 详情
  847. dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetail, 0)
  848. for i, v := range req.List {
  849. t := &aiPredictModel.AiPredictModelDashboardDetail{
  850. Type: v.Type,
  851. UniqueCode: v.UniqueCode,
  852. Sort: i + 1,
  853. CreateTime: time.Now(),
  854. ModifyTime: time.Now(),
  855. }
  856. dashboardDetails = append(dashboardDetails, t)
  857. }
  858. // 保存
  859. if e := dashboardItem.SaveIndexDashboard(dashboardItem, dashboardDetails, isUpdate, updateCols); e != nil {
  860. br.Msg = "操作失败"
  861. br.ErrMsg = fmt.Sprintf("保存标的看板失败, %v", e)
  862. return
  863. }
  864. br.Ret = 200
  865. br.Success = true
  866. br.Msg = "操作成功"
  867. }
  868. // DashboardDetail
  869. // @Title 看板详情
  870. // @Description 看板详情
  871. // @Param IndexId query int true "标的ID"
  872. // @Success 200 {object} aiPredictModel.AiPredictModelDashboardDetailResp
  873. // @router /index/dashboard/detail [get]
  874. func (this *AiPredictModelIndexController) DashboardDetail() {
  875. br := new(models.BaseResponse).Init()
  876. defer func() {
  877. if br.ErrMsg == "" {
  878. br.IsSendEmail = false
  879. }
  880. this.Data["json"] = br
  881. this.ServeJSON()
  882. }()
  883. sysUser := this.SysUser
  884. if sysUser == nil {
  885. br.Msg = "请登录"
  886. br.ErrMsg = "请登录,SysUser Is Empty"
  887. br.Ret = 408
  888. return
  889. }
  890. indexId, _ := this.GetInt("IndexId")
  891. resp := new(aiPredictModel.AiPredictModelDashboardDetailResp)
  892. indexOb := new(aiPredictModel.AiPredictModelIndex)
  893. indexItem, e := indexOb.GetItemById(indexId)
  894. if e != nil {
  895. if e.Error() == utils.ErrNoRow() {
  896. br.Msg = "标的已被删除,请刷新页面"
  897. return
  898. }
  899. br.Msg = "获取失败"
  900. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  901. return
  902. }
  903. resp.CreateUserId = indexItem.SysUserId
  904. resp.CreateUserRealName = indexItem.SysUserRealName
  905. // 获取标的看板
  906. dashboardOb := new(aiPredictModel.AiPredictModelDashboard)
  907. dashboardItem := new(aiPredictModel.AiPredictModelDashboardItem)
  908. {
  909. cond := fmt.Sprintf(" AND %s = ?", dashboardOb.Cols().AiPredictModelIndexId)
  910. pars := make([]interface{}, 0)
  911. pars = append(pars, indexId)
  912. item, e := dashboardOb.GetItemByCondition(cond, pars, "")
  913. if e != nil && e.Error() != utils.ErrNoRow() {
  914. br.Msg = "操作失败"
  915. br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
  916. return
  917. }
  918. if item != nil {
  919. dashboardItem = item.Format2Item()
  920. }
  921. }
  922. // 获取看板详情
  923. dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetailItem, 0)
  924. if dashboardItem.DashboardId > 0 {
  925. detailOb := new(aiPredictModel.AiPredictModelDashboardDetail)
  926. cond := fmt.Sprintf(" AND %s = ?", detailOb.Cols().AiPredictModelDashboardId)
  927. pars := make([]interface{}, 0)
  928. pars = append(pars, dashboardItem.DashboardId)
  929. list, e := detailOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", detailOb.Cols().Sort))
  930. if e != nil {
  931. br.Msg = "获取失败"
  932. br.ErrMsg = fmt.Sprintf("获取看板详情失败, %v", e)
  933. return
  934. }
  935. for _, v := range list {
  936. dashboardDetails = append(dashboardDetails, v.Format2Item())
  937. }
  938. }
  939. resp.AiPredictModelDashboardItem = dashboardItem
  940. resp.List = dashboardDetails
  941. br.Data = resp
  942. br.Ret = 200
  943. br.Success = true
  944. br.Msg = "获取成功"
  945. }