index.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  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. "eta/eta_api/models/system"
  8. "eta/eta_api/services"
  9. "eta/eta_api/utils"
  10. "fmt"
  11. "github.com/rdlucklib/rdluck_tools/paging"
  12. "github.com/tealeg/xlsx"
  13. "os"
  14. "strconv"
  15. "strings"
  16. "time"
  17. )
  18. // AiPredictModelIndexController AI预测模型标的
  19. type AiPredictModelIndexController struct {
  20. controllers.BaseAuthController
  21. }
  22. // List
  23. // @Title 标的列表
  24. // @Description 标的列表
  25. // @Param PageSize query int true "每页数据条数"
  26. // @Param CurrentIndex query int true "当前页页码,从1开始"
  27. // @Param ClassifyId query int false "分类id"
  28. // @Param Keyword query string false "搜索关键词"
  29. // @Success 200 {object} data_manage.ChartListResp
  30. // @router /index/list [get]
  31. func (this *AiPredictModelIndexController) List() {
  32. br := new(models.BaseResponse).Init()
  33. defer func() {
  34. this.Data["json"] = br
  35. this.ServeJSON()
  36. }()
  37. sysUser := this.SysUser
  38. if sysUser == nil {
  39. br.Msg = "请登录"
  40. br.ErrMsg = "请登录,SysUser Is Empty"
  41. br.Ret = 408
  42. return
  43. }
  44. pageSize, _ := this.GetInt("PageSize")
  45. currentIndex, _ := this.GetInt("CurrentIndex")
  46. classifyId, _ := this.GetInt("ClassifyId")
  47. keyword := this.GetString("KeyWord")
  48. keyword = strings.TrimSpace(keyword)
  49. resp := new(aiPredictModel.AiPredictModelIndexPageListResp)
  50. // 分页
  51. var startSize int
  52. if pageSize <= 0 {
  53. pageSize = utils.PageSize20
  54. }
  55. if currentIndex <= 0 {
  56. currentIndex = 1
  57. }
  58. startSize = paging.StartIndex(currentIndex, pageSize)
  59. // 分类
  60. classifyIdName := make(map[int]string)
  61. {
  62. classifyOb := new(aiPredictModel.AiPredictModelClassify)
  63. list, e := classifyOb.GetItemsByCondition("", make([]interface{}, 0), []string{}, "")
  64. if e != nil {
  65. br.Msg = "获取失败"
  66. br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
  67. return
  68. }
  69. for _, v := range list {
  70. classifyIdName[v.AiPredictModelClassifyId] = v.ClassifyName
  71. }
  72. }
  73. // 筛选条件
  74. indexOb := new(aiPredictModel.AiPredictModelIndex)
  75. var cond string
  76. var pars []interface{}
  77. {
  78. if classifyId > 0 {
  79. cond += fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
  80. pars = append(pars, classifyId)
  81. }
  82. if keyword != "" {
  83. cond += fmt.Sprintf(" AND %s LIKE ?", indexOb.Cols().IndexName)
  84. pars = append(pars, fmt.Sprint("%", keyword, "%"))
  85. }
  86. }
  87. // 获取列表
  88. total, e := indexOb.GetCountByCondition(cond, pars)
  89. if e != nil {
  90. br.Msg = "获取失败"
  91. br.ErrMsg = fmt.Sprintf("获取标的总数失败, %v", e)
  92. return
  93. }
  94. list, e := indexOb.GetPageItemsByCondition(cond, pars, []string{}, "", startSize, pageSize)
  95. if e != nil {
  96. br.Msg = "获取失败"
  97. br.ErrMsg = fmt.Sprintf("获取分页列表失败, %v", e)
  98. return
  99. }
  100. pageList := make([]*aiPredictModel.AiPredictModelIndexItem, 0)
  101. for _, v := range list {
  102. t := v.Format2Item()
  103. t.ClassifyName = classifyIdName[v.ClassifyId]
  104. pageList = append(pageList, t)
  105. }
  106. page := paging.GetPaging(currentIndex, pageSize, total)
  107. resp.Paging = page
  108. resp.List = pageList
  109. br.Data = resp
  110. br.Ret = 200
  111. br.Success = true
  112. br.Msg = "获取成功"
  113. }
  114. // Import
  115. // @Title 导入标的和数据
  116. // @Description 导入标的和数据
  117. // @Param IndexFile query file true "标的文件"
  118. // @Success 200 Ret=200 录入成功
  119. // @router /index/import [post]
  120. func (this *AiPredictModelIndexController) Import() {
  121. br := new(models.BaseResponse).Init()
  122. defer func() {
  123. if br.ErrMsg == "" {
  124. br.IsSendEmail = false
  125. }
  126. this.Data["json"] = br
  127. this.ServeJSON()
  128. }()
  129. sysUser := this.SysUser
  130. if sysUser == nil {
  131. br.Msg = "请登录"
  132. br.ErrMsg = "请登录,SysUser Is Empty"
  133. br.Ret = 408
  134. return
  135. }
  136. file, _, e := this.GetFile("IndexFile")
  137. if e != nil {
  138. br.Msg = "导入失败"
  139. br.ErrMsg = fmt.Sprintf("获取文件失败, %v", e)
  140. return
  141. }
  142. path := "./static/ai_predict_model_temp_" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
  143. defer func() {
  144. _ = file.Close()
  145. _ = os.Remove(path)
  146. }()
  147. if e = this.SaveToFile("IndexFile", path); e != nil {
  148. br.Msg = "导入失败"
  149. br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e)
  150. return
  151. }
  152. xlFile, e := xlsx.OpenFile(path)
  153. if e != nil {
  154. br.Msg = "导入失败"
  155. br.ErrMsg = fmt.Sprintf("打开excel文件失败, %v", e)
  156. return
  157. }
  158. // 获取分类和用户,遍历时校验
  159. classifyNameId := make(map[string]int)
  160. adminNameId := make(map[string]int)
  161. {
  162. classifyOb := new(aiPredictModel.AiPredictModelClassify)
  163. classifyCond := fmt.Sprintf(` AND %s = ?`, classifyOb.Cols().ParentId)
  164. classifyPars := make([]interface{}, 0)
  165. classifyPars = append(classifyPars, 0) // 只取一级分类(临时过渡方案,业务端只会加一级)
  166. classifies, e := classifyOb.GetItemsByCondition(classifyCond, classifyPars, []string{}, "")
  167. if e != nil {
  168. br.Msg = "导入失败"
  169. br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
  170. return
  171. }
  172. for _, v := range classifies {
  173. classifyNameId[v.ClassifyName] = v.AiPredictModelClassifyId
  174. }
  175. admins, e := system.GetSysAdminList(``, make([]interface{}, 0), []string{}, "")
  176. if e != nil {
  177. br.Msg = "导入失败"
  178. br.ErrMsg = fmt.Sprintf("获取用户失败, %v", e)
  179. return
  180. }
  181. for _, v := range admins {
  182. adminNameId[v.RealName] = v.AdminId
  183. }
  184. }
  185. // 遍历sheet页
  186. // 列表页:预测标的|分类|模型框架|创建人|预测日期|预测值|预测频度|方向准确率|绝对偏差
  187. type ImportDataColKey struct {
  188. IndexName string
  189. ColKey int
  190. DataDate time.Time
  191. }
  192. imports := make(map[string]*aiPredictModel.AiPredictModelImportData)
  193. importsData := make(map[string]map[time.Time]*aiPredictModel.AiPredictModelData)
  194. for sheetKey, sheet := range xlFile.Sheets {
  195. maxRow := sheet.MaxRow
  196. // 列表页
  197. if sheetKey == 0 {
  198. for i := 0; i < maxRow; i++ {
  199. // 忽略首行标题
  200. if i < 1 {
  201. continue
  202. }
  203. row := sheet.Row(i)
  204. cells := row.Cells
  205. if len(cells) < 9 {
  206. continue
  207. }
  208. // 标的名称
  209. indexName := strings.TrimSpace(cells[0].String())
  210. if indexName == "" {
  211. continue
  212. }
  213. if imports[indexName] == nil {
  214. imports[indexName] = new(aiPredictModel.AiPredictModelImportData)
  215. imports[indexName].Index = new(aiPredictModel.AiPredictModelIndex)
  216. imports[indexName].Data = make([]*aiPredictModel.AiPredictModelData, 0)
  217. }
  218. imports[indexName].Index.IndexName = indexName
  219. imports[indexName].Index.CreateTime = time.Now()
  220. imports[indexName].Index.ModifyTime = time.Now()
  221. // 分类
  222. classifyName := strings.TrimSpace(cells[1].String())
  223. if classifyNameId[classifyName] <= 0 {
  224. br.Msg = fmt.Sprintf("分类:%s不存在", classifyName)
  225. return
  226. }
  227. imports[indexName].Index.ClassifyId = classifyNameId[classifyName]
  228. // 创建人
  229. adminName := strings.TrimSpace(cells[3].String())
  230. if adminNameId[adminName] <= 0 {
  231. br.Msg = fmt.Sprintf("创建人:%s不存在", adminName)
  232. return
  233. }
  234. imports[indexName].Index.SysUserId = adminNameId[adminName]
  235. imports[indexName].Index.SysUserRealName = adminName
  236. // 其余信息
  237. imports[indexName].Index.ModelFramework = strings.TrimSpace(cells[2].String())
  238. strDate := strings.TrimSpace(cells[4].String())
  239. predictDate, _ := time.Parse("2006/01/02", strDate)
  240. if predictDate.IsZero() {
  241. predictDate, _ = time.Parse("01-02-06", strDate)
  242. if predictDate.IsZero() {
  243. predictDate, _ = time.Parse("2006/1/2", strDate)
  244. }
  245. }
  246. imports[indexName].Index.PredictDate = predictDate
  247. predictVal, _ := cells[5].Float()
  248. imports[indexName].Index.PredictValue = predictVal
  249. imports[indexName].Index.PredictFrequency = strings.TrimSpace(cells[6].String())
  250. imports[indexName].Index.DirectionAccuracy = strings.TrimSpace(cells[7].String())
  251. imports[indexName].Index.AbsoluteDeviation = strings.TrimSpace(cells[8].String())
  252. }
  253. }
  254. // 数据页
  255. if sheetKey == 1 {
  256. // 每五列为一个指标的数据
  257. colKeys := make(map[int]*ImportDataColKey) // 每一列对应的指标名称以及对应的字段序号
  258. for i := 0; i < maxRow; i++ {
  259. // 首行为指标名称
  260. if i == 0 {
  261. nameCol := 0
  262. row := sheet.Row(i)
  263. for ck, cell := range row.Cells {
  264. nameCol += 1
  265. if nameCol > 5 {
  266. nameCol = 1
  267. }
  268. if nameCol == 1 {
  269. // nameCol=1时为指标/数据行则为日期
  270. indexName := strings.TrimSpace(cell.String())
  271. if indexName == "" {
  272. continue
  273. }
  274. importsData[indexName] = make(map[time.Time]*aiPredictModel.AiPredictModelData)
  275. colKeys[ck] = &ImportDataColKey{
  276. ColKey: 1,
  277. IndexName: indexName,
  278. }
  279. // 后面四列分别对应: 实际值|预测值|方向|偏差率, 这里直接加无须考虑是否会越界
  280. colKeys[ck+1] = &ImportDataColKey{
  281. ColKey: 2,
  282. IndexName: indexName,
  283. }
  284. colKeys[ck+2] = &ImportDataColKey{
  285. ColKey: 3,
  286. IndexName: indexName,
  287. }
  288. colKeys[ck+3] = &ImportDataColKey{
  289. ColKey: 4,
  290. IndexName: indexName,
  291. }
  292. colKeys[ck+4] = &ImportDataColKey{
  293. ColKey: 5,
  294. IndexName: indexName,
  295. }
  296. continue
  297. }
  298. }
  299. continue
  300. }
  301. // 第二行为标题,跳过
  302. if i == 1 {
  303. continue
  304. }
  305. // 剩余为数据行
  306. row := sheet.Row(i)
  307. for ck, cell := range row.Cells {
  308. if colKeys[ck] == nil {
  309. continue
  310. }
  311. if colKeys[ck].IndexName == "" {
  312. continue
  313. }
  314. switch colKeys[ck].ColKey {
  315. case 1:
  316. // 日期列
  317. strDate := strings.TrimSpace(cell.String())
  318. dataDate, _ := time.Parse("2006/01/02", strDate)
  319. if dataDate.IsZero() {
  320. dataDate, _ = time.Parse("01-02-06", strDate)
  321. if dataDate.IsZero() {
  322. dataDate, _ = time.Parse("2006/1/2", strDate)
  323. if dataDate.IsZero() {
  324. continue
  325. }
  326. }
  327. }
  328. colKeys[ck].DataDate = dataDate
  329. colKeys[ck+1].DataDate = dataDate
  330. colKeys[ck+2].DataDate = dataDate
  331. colKeys[ck+3].DataDate = dataDate
  332. colKeys[ck+4].DataDate = dataDate
  333. importRow := imports[colKeys[ck].IndexName]
  334. if importRow == nil {
  335. continue
  336. }
  337. // 新增当前日期数据
  338. importsData[colKeys[ck].IndexName][dataDate] = new(aiPredictModel.AiPredictModelData)
  339. importsData[colKeys[ck].IndexName][dataDate].DataTime = dataDate
  340. importsData[colKeys[ck].IndexName][dataDate].CreateTime = time.Now()
  341. importsData[colKeys[ck].IndexName][dataDate].ModifyTime = time.Now()
  342. case 2, 3:
  343. // 实际值和预测值, 可能为空
  344. dataDate := colKeys[ck].DataDate
  345. if importsData[colKeys[ck].IndexName][dataDate] == nil {
  346. continue
  347. }
  348. strVal := strings.TrimSpace(cell.String())
  349. if strVal == "" {
  350. continue
  351. }
  352. val, _ := strconv.ParseFloat(strVal, 64)
  353. if colKeys[ck].ColKey == 2 {
  354. importsData[colKeys[ck].IndexName][dataDate].Value.Valid = true
  355. importsData[colKeys[ck].IndexName][dataDate].Value.Float64 = val
  356. } else {
  357. importsData[colKeys[ck].IndexName][dataDate].PredictValue.Valid = true
  358. importsData[colKeys[ck].IndexName][dataDate].PredictValue.Float64 = val
  359. }
  360. case 4, 5:
  361. // 方向/偏差率
  362. dataDate := colKeys[ck].DataDate
  363. if importsData[colKeys[ck].IndexName][dataDate] == nil {
  364. continue
  365. }
  366. str := strings.TrimSpace(cell.String())
  367. if str == "" {
  368. continue
  369. }
  370. if colKeys[ck].ColKey == 4 {
  371. importsData[colKeys[ck].IndexName][dataDate].Direction = str
  372. } else {
  373. importsData[colKeys[ck].IndexName][dataDate].DeviationRate = str
  374. }
  375. default:
  376. continue
  377. }
  378. }
  379. }
  380. }
  381. }
  382. for indexName, v := range importsData {
  383. if imports[indexName] == nil {
  384. continue
  385. }
  386. for _, dateData := range v {
  387. imports[indexName].Data = append(imports[indexName].Data, dateData)
  388. }
  389. }
  390. importIndexes := make([]*aiPredictModel.AiPredictModelImportData, 0)
  391. for _, v := range imports {
  392. importIndexes = append(importIndexes, v)
  393. }
  394. // 导入指标
  395. if e = services.ImportAiPredictModelIndexAndData(importIndexes); e != nil {
  396. br.Msg = "操作失败"
  397. br.ErrMsg = fmt.Sprintf("导入指标数据失败, %v", e)
  398. return
  399. }
  400. br.Ret = 200
  401. br.Success = true
  402. br.Msg = "操作成功"
  403. }
  404. // Detail
  405. // @Title 标的详情
  406. // @Description 标的详情
  407. // @Param IndexId query int true "标的ID"
  408. // @Success 200 {object} data_manage.ChartListResp
  409. // @router /index/detail [get]
  410. func (this *AiPredictModelIndexController) Detail() {
  411. br := new(models.BaseResponse).Init()
  412. defer func() {
  413. if br.ErrMsg == "" {
  414. br.IsSendEmail = false
  415. }
  416. this.Data["json"] = br
  417. this.ServeJSON()
  418. }()
  419. sysUser := this.SysUser
  420. if sysUser == nil {
  421. br.Msg = "请登录"
  422. br.ErrMsg = "请登录,SysUser Is Empty"
  423. br.Ret = 408
  424. return
  425. }
  426. indexId, _ := this.GetInt("IndexId")
  427. if indexId <= 0 {
  428. br.Msg = "参数有误"
  429. br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", indexId)
  430. return
  431. }
  432. resp := new(aiPredictModel.AiPredictModelDetailResp)
  433. indexOb := new(aiPredictModel.AiPredictModelIndex)
  434. indexItem, e := indexOb.GetItemById(indexId)
  435. if e != nil {
  436. if e.Error() == utils.ErrNoRow() {
  437. br.Msg = "标的已被删除,请刷新页面"
  438. return
  439. }
  440. br.Msg = "获取失败"
  441. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  442. return
  443. }
  444. // 获取标的数据
  445. indexData := make([]*aiPredictModel.AiPredictModelData, 0)
  446. {
  447. tableData := make([]*aiPredictModel.AiPredictModelDataItem, 0)
  448. dataOb := new(aiPredictModel.AiPredictModelData)
  449. dataCond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().AiPredictModelIndexId)
  450. dataPars := make([]interface{}, 0)
  451. dataPars = append(dataPars, indexId)
  452. list, e := dataOb.GetItemsByCondition(dataCond, dataPars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
  453. if e != nil {
  454. br.Msg = "获取失败"
  455. br.ErrMsg = fmt.Sprintf("获取标的数据失败, %v", e)
  456. return
  457. }
  458. indexData = list
  459. for _, v := range list {
  460. tableData = append(tableData, v.Format2Item())
  461. }
  462. resp.TableData = tableData
  463. }
  464. // 获取图表数据
  465. chartDetail, e := services.GetAiPredictChartDetailByData(indexItem, indexData)
  466. if e != nil {
  467. br.Msg = "获取失败"
  468. br.ErrMsg = fmt.Sprintf("获取图表数据失败, %v", e)
  469. return
  470. }
  471. resp.ChartView = chartDetail
  472. br.Data = resp
  473. br.Ret = 200
  474. br.Success = true
  475. br.Msg = "获取成功"
  476. }
  477. // Save
  478. // @Title 保存标的
  479. // @Description 保存标的
  480. // @Param request body aiPredictModel.AiPredictModelIndexSaveReq true "type json string"
  481. // @Success 200 Ret=200 保存成功
  482. // @router /index/save [post]
  483. func (this *AiPredictModelIndexController) Save() {
  484. br := new(models.BaseResponse).Init()
  485. defer func() {
  486. if br.ErrMsg == "" {
  487. br.IsSendEmail = false
  488. }
  489. this.Data["json"] = br
  490. this.ServeJSON()
  491. }()
  492. sysUser := this.SysUser
  493. if sysUser == nil {
  494. br.Msg = "请登录"
  495. br.ErrMsg = "请登录,SysUser Is Empty"
  496. br.Ret = 408
  497. return
  498. }
  499. var req aiPredictModel.AiPredictModelIndexSaveReq
  500. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  501. br.Msg = "参数解析异常"
  502. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  503. return
  504. }
  505. if req.IndexId < 0 {
  506. br.Msg = "参数有误"
  507. br.ErrMsg = fmt.Sprintf("标的ID有误, IndexId: %d", req.IndexId)
  508. return
  509. }
  510. indexOb := new(aiPredictModel.AiPredictModelIndex)
  511. indexItem, e := indexOb.GetItemById(req.IndexId)
  512. if e != nil {
  513. if e.Error() == utils.ErrNoRow() {
  514. br.Msg = "标的已被删除,请刷新页面"
  515. return
  516. }
  517. br.Msg = "获取失败"
  518. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  519. return
  520. }
  521. var updateCols []string
  522. if req.LeftMin != "" {
  523. indexItem.LeftMin = req.LeftMin
  524. updateCols = append(updateCols, indexOb.Cols().LeftMin)
  525. }
  526. if req.LeftMax != "" {
  527. indexItem.LeftMax = req.LeftMax
  528. updateCols = append(updateCols, indexOb.Cols().LeftMax)
  529. }
  530. indexItem.ModifyTime = time.Now()
  531. updateCols = append(updateCols, indexOb.Cols().ModifyTime)
  532. if e = indexItem.Update(updateCols); e != nil {
  533. br.Msg = "操作失败"
  534. br.ErrMsg = fmt.Sprintf("保存标的失败, %v", e)
  535. return
  536. }
  537. br.Ret = 200
  538. br.Msg = "操作成功"
  539. br.Success = true
  540. }
  541. // DashboardSave
  542. // @Title 保存看板
  543. // @Description 保存看板
  544. // @Param request body aiPredictModel.AiPredictModelDashboardSaveReq true "type json string"
  545. // @Success 200 Ret=200 新增成功
  546. // @router /index/dashboard/save [post]
  547. func (this *AiPredictModelIndexController) DashboardSave() {
  548. br := new(models.BaseResponse).Init()
  549. defer func() {
  550. if br.ErrMsg == "" {
  551. br.IsSendEmail = false
  552. }
  553. this.Data["json"] = br
  554. this.ServeJSON()
  555. }()
  556. sysUser := this.SysUser
  557. if sysUser == nil {
  558. br.Msg = "请登录"
  559. br.ErrMsg = "请登录,SysUser Is Empty"
  560. br.Ret = 408
  561. return
  562. }
  563. var req aiPredictModel.AiPredictModelDashboardSaveReq
  564. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  565. br.Msg = "参数解析异常"
  566. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  567. return
  568. }
  569. if req.IndexId <= 0 {
  570. br.Msg = "参数有误"
  571. br.ErrMsg = fmt.Sprintf("参数有误, %d", req.IndexId)
  572. return
  573. }
  574. req.DashboardName = strings.TrimSpace(req.DashboardName)
  575. indexOb := new(aiPredictModel.AiPredictModelIndex)
  576. _, e := indexOb.GetItemById(req.IndexId)
  577. if e != nil {
  578. if e.Error() == utils.ErrNoRow() {
  579. br.Msg = "标的已被删除,请刷新页面"
  580. return
  581. }
  582. br.Msg = "操作失败"
  583. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  584. return
  585. }
  586. // 仅标的创建人有权限操作看板
  587. //if sysUser.AdminId != indexItem.SysUserId {
  588. // br.Msg = "仅创建人可操作"
  589. // return
  590. //}
  591. // 获取看板
  592. var isUpdate bool
  593. var updateCols []string
  594. dashboardItem := new(aiPredictModel.AiPredictModelDashboard)
  595. if req.IndexId > 0 {
  596. cond := fmt.Sprintf(" AND %s = ?", dashboardItem.Cols().AiPredictModelIndexId)
  597. pars := make([]interface{}, 0)
  598. pars = append(pars, req.IndexId)
  599. item, e := dashboardItem.GetItemByCondition(cond, pars, "")
  600. if e != nil && e.Error() != utils.ErrNoRow() {
  601. br.Msg = "操作失败"
  602. br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
  603. return
  604. }
  605. if item != nil {
  606. isUpdate = true
  607. dashboardItem = item
  608. dashboardItem.DashboardName = req.DashboardName
  609. dashboardItem.ModifyTime = time.Now()
  610. updateCols = append(updateCols, dashboardItem.Cols().DashboardName, dashboardItem.Cols().ModifyTime)
  611. }
  612. }
  613. if !isUpdate {
  614. dashboardItem.AiPredictModelIndexId = req.IndexId
  615. dashboardItem.DashboardName = req.DashboardName
  616. dashboardItem.SysUserId = sysUser.AdminId
  617. dashboardItem.SysUserRealName = sysUser.RealName
  618. dashboardItem.CreateTime = time.Now()
  619. dashboardItem.ModifyTime = time.Now()
  620. }
  621. // 详情
  622. dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetail, 0)
  623. for i, v := range req.List {
  624. t := &aiPredictModel.AiPredictModelDashboardDetail{
  625. Type: v.Type,
  626. UniqueCode: v.UniqueCode,
  627. Sort: i + 1,
  628. CreateTime: time.Now(),
  629. ModifyTime: time.Now(),
  630. }
  631. dashboardDetails = append(dashboardDetails, t)
  632. }
  633. // 保存
  634. if e := dashboardItem.SaveIndexDashboard(dashboardItem, dashboardDetails, isUpdate, updateCols); e != nil {
  635. br.Msg = "操作失败"
  636. br.ErrMsg = fmt.Sprintf("保存标的看板失败, %v", e)
  637. return
  638. }
  639. br.Ret = 200
  640. br.Success = true
  641. br.Msg = "操作成功"
  642. }
  643. // DashboardDetail
  644. // @Title 看板详情
  645. // @Description 看板详情
  646. // @Param IndexId query int true "标的ID"
  647. // @Success 200 {object} aiPredictModel.AiPredictModelDashboardDetailResp
  648. // @router /index/dashboard/detail [get]
  649. func (this *AiPredictModelIndexController) DashboardDetail() {
  650. br := new(models.BaseResponse).Init()
  651. defer func() {
  652. if br.ErrMsg == "" {
  653. br.IsSendEmail = false
  654. }
  655. this.Data["json"] = br
  656. this.ServeJSON()
  657. }()
  658. sysUser := this.SysUser
  659. if sysUser == nil {
  660. br.Msg = "请登录"
  661. br.ErrMsg = "请登录,SysUser Is Empty"
  662. br.Ret = 408
  663. return
  664. }
  665. indexId, _ := this.GetInt("IndexId")
  666. resp := new(aiPredictModel.AiPredictModelDashboardDetailResp)
  667. indexOb := new(aiPredictModel.AiPredictModelIndex)
  668. indexItem, e := indexOb.GetItemById(indexId)
  669. if e != nil {
  670. if e.Error() == utils.ErrNoRow() {
  671. br.Msg = "标的已被删除,请刷新页面"
  672. return
  673. }
  674. br.Msg = "获取失败"
  675. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  676. return
  677. }
  678. resp.CreateUserId = indexItem.SysUserId
  679. resp.CreateUserRealName = indexItem.SysUserRealName
  680. // 获取标的看板
  681. dashboardOb := new(aiPredictModel.AiPredictModelDashboard)
  682. dashboardItem := new(aiPredictModel.AiPredictModelDashboardItem)
  683. {
  684. cond := fmt.Sprintf(" AND %s = ?", dashboardOb.Cols().AiPredictModelIndexId)
  685. pars := make([]interface{}, 0)
  686. pars = append(pars, indexId)
  687. item, e := dashboardOb.GetItemByCondition(cond, pars, "")
  688. if e != nil && e.Error() != utils.ErrNoRow() {
  689. br.Msg = "操作失败"
  690. br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
  691. return
  692. }
  693. if item != nil {
  694. dashboardItem = item.Format2Item()
  695. }
  696. }
  697. // 获取看板详情
  698. dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetailItem, 0)
  699. if dashboardItem.DashboardId > 0 {
  700. detailOb := new(aiPredictModel.AiPredictModelDashboardDetail)
  701. cond := fmt.Sprintf(" AND %s = ?", detailOb.Cols().AiPredictModelDashboardId)
  702. pars := make([]interface{}, 0)
  703. pars = append(pars, dashboardItem.DashboardId)
  704. list, e := detailOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", detailOb.Cols().Sort))
  705. if e != nil {
  706. br.Msg = "获取失败"
  707. br.ErrMsg = fmt.Sprintf("获取看板详情失败, %v", e)
  708. return
  709. }
  710. for _, v := range list {
  711. dashboardDetails = append(dashboardDetails, v.Format2Item())
  712. }
  713. }
  714. resp.AiPredictModelDashboardItem = dashboardItem
  715. resp.List = dashboardDetails
  716. br.Data = resp
  717. br.Ret = 200
  718. br.Success = true
  719. br.Msg = "获取成功"
  720. }