index.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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. // tableData最多显示10条
  460. count, limit := 0, 10
  461. for _, v := range list {
  462. if count >= limit {
  463. break
  464. }
  465. tableData = append(tableData, v.Format2Item())
  466. count += 1
  467. }
  468. resp.TableData = tableData
  469. }
  470. // 获取图表数据
  471. chartDetail, e := services.GetAiPredictChartDetailByData(indexItem, indexData)
  472. if e != nil {
  473. br.Msg = "获取失败"
  474. br.ErrMsg = fmt.Sprintf("获取图表数据失败, %v", e)
  475. return
  476. }
  477. resp.ChartView = chartDetail
  478. br.Data = resp
  479. br.Ret = 200
  480. br.Success = true
  481. br.Msg = "获取成功"
  482. }
  483. // Save
  484. // @Title 保存标的
  485. // @Description 保存标的
  486. // @Param request body aiPredictModel.AiPredictModelIndexSaveReq true "type json string"
  487. // @Success 200 Ret=200 保存成功
  488. // @router /index/save [post]
  489. func (this *AiPredictModelIndexController) Save() {
  490. br := new(models.BaseResponse).Init()
  491. defer func() {
  492. if br.ErrMsg == "" {
  493. br.IsSendEmail = false
  494. }
  495. this.Data["json"] = br
  496. this.ServeJSON()
  497. }()
  498. sysUser := this.SysUser
  499. if sysUser == nil {
  500. br.Msg = "请登录"
  501. br.ErrMsg = "请登录,SysUser Is Empty"
  502. br.Ret = 408
  503. return
  504. }
  505. var req aiPredictModel.AiPredictModelIndexSaveReq
  506. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  507. br.Msg = "参数解析异常"
  508. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  509. return
  510. }
  511. if req.IndexId < 0 {
  512. br.Msg = "参数有误"
  513. br.ErrMsg = fmt.Sprintf("标的ID有误, IndexId: %d", req.IndexId)
  514. return
  515. }
  516. indexOb := new(aiPredictModel.AiPredictModelIndex)
  517. indexItem, e := indexOb.GetItemById(req.IndexId)
  518. if e != nil {
  519. if e.Error() == utils.ErrNoRow() {
  520. br.Msg = "标的已被删除,请刷新页面"
  521. return
  522. }
  523. br.Msg = "获取失败"
  524. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  525. return
  526. }
  527. var updateCols []string
  528. if req.LeftMin != "" {
  529. indexItem.LeftMin = req.LeftMin
  530. updateCols = append(updateCols, indexOb.Cols().LeftMin)
  531. }
  532. if req.LeftMax != "" {
  533. indexItem.LeftMax = req.LeftMax
  534. updateCols = append(updateCols, indexOb.Cols().LeftMax)
  535. }
  536. indexItem.ModifyTime = time.Now()
  537. updateCols = append(updateCols, indexOb.Cols().ModifyTime)
  538. if e = indexItem.Update(updateCols); e != nil {
  539. br.Msg = "操作失败"
  540. br.ErrMsg = fmt.Sprintf("保存标的失败, %v", e)
  541. return
  542. }
  543. br.Ret = 200
  544. br.Msg = "操作成功"
  545. br.Success = true
  546. }
  547. // DashboardSave
  548. // @Title 保存看板
  549. // @Description 保存看板
  550. // @Param request body aiPredictModel.AiPredictModelDashboardSaveReq true "type json string"
  551. // @Success 200 Ret=200 新增成功
  552. // @router /index/dashboard/save [post]
  553. func (this *AiPredictModelIndexController) DashboardSave() {
  554. br := new(models.BaseResponse).Init()
  555. defer func() {
  556. if br.ErrMsg == "" {
  557. br.IsSendEmail = false
  558. }
  559. this.Data["json"] = br
  560. this.ServeJSON()
  561. }()
  562. sysUser := this.SysUser
  563. if sysUser == nil {
  564. br.Msg = "请登录"
  565. br.ErrMsg = "请登录,SysUser Is Empty"
  566. br.Ret = 408
  567. return
  568. }
  569. var req aiPredictModel.AiPredictModelDashboardSaveReq
  570. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  571. br.Msg = "参数解析异常"
  572. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  573. return
  574. }
  575. if req.IndexId <= 0 {
  576. br.Msg = "参数有误"
  577. br.ErrMsg = fmt.Sprintf("参数有误, %d", req.IndexId)
  578. return
  579. }
  580. req.DashboardName = strings.TrimSpace(req.DashboardName)
  581. indexOb := new(aiPredictModel.AiPredictModelIndex)
  582. _, e := indexOb.GetItemById(req.IndexId)
  583. if e != nil {
  584. if e.Error() == utils.ErrNoRow() {
  585. br.Msg = "标的已被删除,请刷新页面"
  586. return
  587. }
  588. br.Msg = "操作失败"
  589. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  590. return
  591. }
  592. // 仅标的创建人有权限操作看板
  593. //if sysUser.AdminId != indexItem.SysUserId {
  594. // br.Msg = "仅创建人可操作"
  595. // return
  596. //}
  597. // 获取看板
  598. var isUpdate bool
  599. var updateCols []string
  600. dashboardItem := new(aiPredictModel.AiPredictModelDashboard)
  601. if req.IndexId > 0 {
  602. cond := fmt.Sprintf(" AND %s = ?", dashboardItem.Cols().AiPredictModelIndexId)
  603. pars := make([]interface{}, 0)
  604. pars = append(pars, req.IndexId)
  605. item, e := dashboardItem.GetItemByCondition(cond, pars, "")
  606. if e != nil && e.Error() != utils.ErrNoRow() {
  607. br.Msg = "操作失败"
  608. br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
  609. return
  610. }
  611. if item != nil {
  612. isUpdate = true
  613. dashboardItem = item
  614. dashboardItem.DashboardName = req.DashboardName
  615. dashboardItem.ModifyTime = time.Now()
  616. updateCols = append(updateCols, dashboardItem.Cols().DashboardName, dashboardItem.Cols().ModifyTime)
  617. }
  618. }
  619. if !isUpdate {
  620. dashboardItem.AiPredictModelIndexId = req.IndexId
  621. dashboardItem.DashboardName = req.DashboardName
  622. dashboardItem.SysUserId = sysUser.AdminId
  623. dashboardItem.SysUserRealName = sysUser.RealName
  624. dashboardItem.CreateTime = time.Now()
  625. dashboardItem.ModifyTime = time.Now()
  626. }
  627. // 详情
  628. dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetail, 0)
  629. for i, v := range req.List {
  630. t := &aiPredictModel.AiPredictModelDashboardDetail{
  631. Type: v.Type,
  632. UniqueCode: v.UniqueCode,
  633. Sort: i + 1,
  634. CreateTime: time.Now(),
  635. ModifyTime: time.Now(),
  636. }
  637. dashboardDetails = append(dashboardDetails, t)
  638. }
  639. // 保存
  640. if e := dashboardItem.SaveIndexDashboard(dashboardItem, dashboardDetails, isUpdate, updateCols); e != nil {
  641. br.Msg = "操作失败"
  642. br.ErrMsg = fmt.Sprintf("保存标的看板失败, %v", e)
  643. return
  644. }
  645. br.Ret = 200
  646. br.Success = true
  647. br.Msg = "操作成功"
  648. }
  649. // DashboardDetail
  650. // @Title 看板详情
  651. // @Description 看板详情
  652. // @Param IndexId query int true "标的ID"
  653. // @Success 200 {object} aiPredictModel.AiPredictModelDashboardDetailResp
  654. // @router /index/dashboard/detail [get]
  655. func (this *AiPredictModelIndexController) DashboardDetail() {
  656. br := new(models.BaseResponse).Init()
  657. defer func() {
  658. if br.ErrMsg == "" {
  659. br.IsSendEmail = false
  660. }
  661. this.Data["json"] = br
  662. this.ServeJSON()
  663. }()
  664. sysUser := this.SysUser
  665. if sysUser == nil {
  666. br.Msg = "请登录"
  667. br.ErrMsg = "请登录,SysUser Is Empty"
  668. br.Ret = 408
  669. return
  670. }
  671. indexId, _ := this.GetInt("IndexId")
  672. resp := new(aiPredictModel.AiPredictModelDashboardDetailResp)
  673. indexOb := new(aiPredictModel.AiPredictModelIndex)
  674. indexItem, e := indexOb.GetItemById(indexId)
  675. if e != nil {
  676. if e.Error() == utils.ErrNoRow() {
  677. br.Msg = "标的已被删除,请刷新页面"
  678. return
  679. }
  680. br.Msg = "获取失败"
  681. br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
  682. return
  683. }
  684. resp.CreateUserId = indexItem.SysUserId
  685. resp.CreateUserRealName = indexItem.SysUserRealName
  686. // 获取标的看板
  687. dashboardOb := new(aiPredictModel.AiPredictModelDashboard)
  688. dashboardItem := new(aiPredictModel.AiPredictModelDashboardItem)
  689. {
  690. cond := fmt.Sprintf(" AND %s = ?", dashboardOb.Cols().AiPredictModelIndexId)
  691. pars := make([]interface{}, 0)
  692. pars = append(pars, indexId)
  693. item, e := dashboardOb.GetItemByCondition(cond, pars, "")
  694. if e != nil && e.Error() != utils.ErrNoRow() {
  695. br.Msg = "操作失败"
  696. br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
  697. return
  698. }
  699. if item != nil {
  700. dashboardItem = item.Format2Item()
  701. }
  702. }
  703. // 获取看板详情
  704. dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetailItem, 0)
  705. if dashboardItem.DashboardId > 0 {
  706. detailOb := new(aiPredictModel.AiPredictModelDashboardDetail)
  707. cond := fmt.Sprintf(" AND %s = ?", detailOb.Cols().AiPredictModelDashboardId)
  708. pars := make([]interface{}, 0)
  709. pars = append(pars, dashboardItem.DashboardId)
  710. list, e := detailOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", detailOb.Cols().Sort))
  711. if e != nil {
  712. br.Msg = "获取失败"
  713. br.ErrMsg = fmt.Sprintf("获取看板详情失败, %v", e)
  714. return
  715. }
  716. for _, v := range list {
  717. dashboardDetails = append(dashboardDetails, v.Format2Item())
  718. }
  719. }
  720. resp.AiPredictModelDashboardItem = dashboardItem
  721. resp.List = dashboardDetails
  722. br.Data = resp
  723. br.Ret = 200
  724. br.Success = true
  725. br.Msg = "获取成功"
  726. }