classify.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  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/data_manage"
  8. dataSourceModel "eta/eta_api/models/data_source"
  9. "eta/eta_api/services"
  10. "eta/eta_api/services/elastic"
  11. "eta/eta_api/utils"
  12. "fmt"
  13. "sort"
  14. "strconv"
  15. "strings"
  16. "time"
  17. )
  18. // AiPredictModelClassifyController AI预测模型-分类
  19. type AiPredictModelClassifyController struct {
  20. controllers.BaseAuthController
  21. }
  22. // List
  23. // @Title 分类列表
  24. // @Description 分类列表
  25. // @Param ParentId query bool false "父级ID"
  26. // @Success 200 {object} data_manage.ChartClassifyListResp
  27. // @router /classify/list [get]
  28. func (this *AiPredictModelClassifyController) List() {
  29. br := new(models.BaseResponse).Init()
  30. defer func() {
  31. if br.ErrMsg == "" {
  32. br.IsSendEmail = false
  33. }
  34. this.Data["json"] = br
  35. this.ServeJSON()
  36. }()
  37. parentId, _ := this.GetInt("ParentId")
  38. resp := new(aiPredictModel.AiPredictModelClassifyListResp)
  39. // (懒加载)仅查询直属分类
  40. classifyOb := new(aiPredictModel.AiPredictModelClassify)
  41. {
  42. cond := fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ParentId)
  43. pars := make([]interface{}, 0)
  44. pars = append(pars, parentId)
  45. list, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", classifyOb.Cols().Sort))
  46. if e != nil {
  47. br.Msg = "获取失败"
  48. br.ErrMsg = fmt.Sprintf("获取子分类失败, %v", e)
  49. return
  50. }
  51. for _, v := range list {
  52. resp.AllNodes = append(resp.AllNodes, &aiPredictModel.AiPredictModelClassifyListItem{
  53. NodeName: v.ClassifyName,
  54. ClassifyId: v.AiPredictModelClassifyId,
  55. ClassifyName: v.ClassifyName,
  56. ParentId: v.ParentId,
  57. Level: v.Level,
  58. Sort: v.Sort,
  59. UniqueCode: v.UniqueCode,
  60. })
  61. }
  62. }
  63. // 非顶级目录查询指标
  64. indexOb := new(aiPredictModel.AiPredictModelIndex)
  65. if parentId > 0 {
  66. parentClassify, e := classifyOb.GetItemById(parentId)
  67. if e != nil {
  68. br.Msg = "父级分类不存在, 请刷新页面"
  69. return
  70. }
  71. cond := fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
  72. pars := make([]interface{}, 0)
  73. pars = append(pars, parentId)
  74. list, e := indexOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", indexOb.Cols().Sort))
  75. if e != nil {
  76. br.Msg = "获取失败"
  77. br.ErrMsg = fmt.Sprintf("获取分类下指标失败, %v", e)
  78. return
  79. }
  80. for _, v := range list {
  81. resp.AllNodes = append(resp.AllNodes, &aiPredictModel.AiPredictModelClassifyListItem{
  82. NodeType: 1,
  83. NodeName: v.IndexName,
  84. ClassifyId: parentClassify.AiPredictModelClassifyId,
  85. ClassifyName: parentClassify.ClassifyName,
  86. IndexId: v.AiPredictModelIndexId,
  87. IndexCode: v.IndexCode,
  88. IndexName: v.IndexName,
  89. ParentId: parentId,
  90. Sort: v.Sort,
  91. UniqueCode: v.IndexCode,
  92. })
  93. }
  94. }
  95. sort.Slice(resp.AllNodes, func(i, j int) bool {
  96. return resp.AllNodes[i].Sort < resp.AllNodes[j].Sort
  97. })
  98. br.Data = resp
  99. br.Ret = 200
  100. br.Success = true
  101. br.Msg = "获取成功"
  102. }
  103. // Add
  104. // @Title 新增分类
  105. // @Description 新增分类
  106. // @Param request body aiPredictModel.AiPredictModelClassifyAddReq true "type json string"
  107. // @Success 200 Ret=200 保存成功
  108. // @router /classify/add [post]
  109. func (this *AiPredictModelClassifyController) Add() {
  110. br := new(models.BaseResponse).Init()
  111. defer func() {
  112. if br.ErrMsg == "" {
  113. br.IsSendEmail = false
  114. }
  115. this.Data["json"] = br
  116. this.ServeJSON()
  117. }()
  118. sysUser := this.SysUser
  119. if sysUser == nil {
  120. br.Msg = "请登录"
  121. br.ErrMsg = "请登录,SysUser Is Empty"
  122. br.Ret = 408
  123. return
  124. }
  125. var req aiPredictModel.AiPredictModelClassifyAddReq
  126. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  127. br.Msg = "参数解析异常"
  128. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  129. return
  130. }
  131. req.ClassifyName = strings.TrimSpace(req.ClassifyName)
  132. if req.ClassifyName == "" {
  133. br.Msg = "请输入分类名称"
  134. return
  135. }
  136. if req.ParentId < 0 {
  137. br.Msg = "请选择上级分类"
  138. return
  139. }
  140. if req.Level > 5 {
  141. br.Msg = "目前只支持6级目录"
  142. return
  143. }
  144. // 校验分类名称
  145. classifyOb := new(aiPredictModel.AiPredictModelClassify)
  146. {
  147. cond := fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ParentId)
  148. if this.Lang == utils.EnLangVersion {
  149. cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyNameEn)
  150. } else {
  151. cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyName)
  152. }
  153. pars := make([]interface{}, 0)
  154. pars = append(pars, req.ParentId, req.ClassifyName)
  155. count, e := classifyOb.GetCountByCondition(cond, pars)
  156. if e != nil {
  157. br.Msg = "操作失败"
  158. br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
  159. return
  160. }
  161. if count > 0 {
  162. br.Msg = "分类名称已存在"
  163. return
  164. }
  165. }
  166. // 层级路径
  167. var levelPath string
  168. var rootId int
  169. if req.ParentId > 0 {
  170. parent, e := classifyOb.GetItemById(req.ParentId)
  171. if e != nil {
  172. br.Msg = "上级分类有误"
  173. br.ErrMsg = fmt.Sprintf("获取上级分类失败, %v", e)
  174. return
  175. }
  176. levelPath = parent.LevelPath
  177. rootId = parent.RootId
  178. }
  179. sortMax, e := classifyOb.GetSortMax(req.ParentId)
  180. if e != nil {
  181. br.Msg = "操作失败"
  182. br.ErrMsg = fmt.Sprintf("获取分类最大排序失败, %v", e)
  183. return
  184. }
  185. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  186. classifyOb.ParentId = req.ParentId
  187. classifyOb.ClassifyName = req.ClassifyName
  188. classifyOb.ClassifyNameEn = req.ClassifyName
  189. classifyOb.Level = req.Level + 1
  190. classifyOb.Sort = sortMax + 1
  191. classifyOb.SysUserId = sysUser.AdminId
  192. classifyOb.SysUserRealName = sysUser.RealName
  193. classifyOb.UniqueCode = utils.MD5(classifyOb.TableName() + "_" + timestamp)
  194. classifyOb.CreateTime = time.Now().Local()
  195. classifyOb.ModifyTime = time.Now().Local()
  196. if e = classifyOb.Create(); e != nil {
  197. br.Msg = "操作失败"
  198. br.ErrMsg = fmt.Sprintf("新增分类失败, %v", e)
  199. return
  200. }
  201. if req.ParentId > 0 {
  202. // 用英文逗号拼接方便查询
  203. classifyOb.LevelPath = fmt.Sprintf("%s,%d", levelPath, classifyOb.AiPredictModelClassifyId)
  204. classifyOb.RootId = rootId
  205. } else {
  206. classifyOb.LevelPath = fmt.Sprint(classifyOb.AiPredictModelClassifyId)
  207. classifyOb.RootId = classifyOb.AiPredictModelClassifyId
  208. }
  209. if e = classifyOb.Update([]string{classifyOb.Cols().LevelPath, classifyOb.Cols().RootId}); e != nil {
  210. br.Msg = "操作失败"
  211. br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
  212. return
  213. }
  214. br.Ret = 200
  215. br.Msg = "操作成功"
  216. br.Success = true
  217. }
  218. // Edit
  219. // @Title 修改分类
  220. // @Description 修改分类
  221. // @Param request body aiPredictModel.AiPredictModelClassifyEditReq true "type json string"
  222. // @Success 200 Ret=200 修改成功
  223. // @router /classify/edit [post]
  224. func (this *AiPredictModelClassifyController) Edit() {
  225. br := new(models.BaseResponse).Init()
  226. defer func() {
  227. if br.ErrMsg == "" {
  228. br.IsSendEmail = false
  229. }
  230. this.Data["json"] = br
  231. this.ServeJSON()
  232. }()
  233. sysUser := this.SysUser
  234. if sysUser == nil {
  235. br.Msg = "请登录"
  236. br.ErrMsg = "请登录,SysUser Is Empty"
  237. br.Ret = 408
  238. return
  239. }
  240. var req aiPredictModel.AiPredictModelClassifyEditReq
  241. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  242. br.Msg = "参数解析异常"
  243. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  244. return
  245. }
  246. if req.ClassifyId < 0 {
  247. br.Msg = "请选择分类"
  248. return
  249. }
  250. req.ClassifyName = strings.TrimSpace(req.ClassifyName)
  251. if req.ClassifyName == "" {
  252. br.Msg = "请输入分类名称"
  253. return
  254. }
  255. classifyOb := new(aiPredictModel.AiPredictModelClassify)
  256. classifyItem, e := classifyOb.GetItemById(req.ClassifyId)
  257. if e != nil {
  258. if e.Error() == utils.ErrNoRow() {
  259. br.Msg = "分类不存在, 请刷新页面"
  260. return
  261. }
  262. br.Msg = "操作失败"
  263. br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
  264. return
  265. }
  266. // 校验分类名称
  267. {
  268. cond := fmt.Sprintf(" AND %s <> ?", classifyOb.Cols().PrimaryId)
  269. if this.Lang == utils.EnLangVersion {
  270. cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyNameEn)
  271. } else {
  272. cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyName)
  273. }
  274. pars := make([]interface{}, 0)
  275. pars = append(pars, req.ClassifyId, req.ClassifyName)
  276. count, e := classifyOb.GetCountByCondition(cond, pars)
  277. if e != nil {
  278. br.Msg = "操作失败"
  279. br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
  280. return
  281. }
  282. if count > 0 {
  283. br.Msg = "分类名称已存在"
  284. return
  285. }
  286. }
  287. classifyItem.ClassifyName = req.ClassifyName
  288. classifyItem.ClassifyNameEn = req.ClassifyName
  289. classifyItem.ModifyTime = time.Now().Local()
  290. updateCols := []string{classifyOb.Cols().ClassifyName, classifyOb.Cols().ClassifyNameEn, classifyOb.Cols().ModifyTime}
  291. if e = classifyItem.Update(updateCols); e != nil {
  292. br.Msg = "操作失败"
  293. br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
  294. return
  295. }
  296. br.Ret = 200
  297. br.Msg = "操作成功"
  298. br.Success = true
  299. }
  300. // RemoveCheck
  301. // @Title 删除校验
  302. // @Description 删除校验
  303. // @Param request body aiPredictModel.AiPredictModelClassifyRemoveReq true "type json string"
  304. // @Success 200 Ret=200 检测成功
  305. // @router /classify/remove_check [post]
  306. func (this *AiPredictModelClassifyController) RemoveCheck() {
  307. br := new(models.BaseResponse).Init()
  308. defer func() {
  309. if br.ErrMsg == "" {
  310. br.IsSendEmail = false
  311. }
  312. this.Data["json"] = br
  313. this.ServeJSON()
  314. }()
  315. var req aiPredictModel.AiPredictModelClassifyRemoveReq
  316. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  317. br.Msg = "参数解析异常"
  318. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  319. return
  320. }
  321. if req.ClassifyId < 0 && req.IndexId <= 0 {
  322. br.Msg = "参数错误"
  323. return
  324. }
  325. var deleteStatus int
  326. var tipsMsg string
  327. // 删除分类
  328. if req.ClassifyId > 0 && req.IndexId == 0 {
  329. count, err := aiPredictModel.GetAiPredictModelIndexCountByClassifyId(req.ClassifyId)
  330. if err != nil {
  331. br.Msg = "删除失败"
  332. br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
  333. return
  334. }
  335. if count > 0 {
  336. deleteStatus = 1
  337. tipsMsg = "该分类下关联图表不可删除"
  338. }
  339. }
  340. if deleteStatus != 1 && req.IndexId == 0 {
  341. classifyCount, err := aiPredictModel.GetAiPredictModelClassifyCountByClassifyId(req.ClassifyId)
  342. if err != nil && err.Error() != utils.ErrNoRow() {
  343. br.Msg = "删除失败"
  344. br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
  345. return
  346. }
  347. if classifyCount > 0 {
  348. deleteStatus = 2
  349. tipsMsg = "确认删除当前目录及包含的子目录吗"
  350. }
  351. }
  352. if deleteStatus == 0 {
  353. tipsMsg = "可删除,进行删除操作"
  354. }
  355. resp := new(data_manage.ChartClassifyDeleteCheckResp)
  356. resp.DeleteStatus = deleteStatus
  357. resp.TipsMsg = tipsMsg
  358. br.Ret = 200
  359. br.Msg = "检测成功"
  360. br.Success = true
  361. br.Data = resp
  362. }
  363. // Remove
  364. // @Title 删除分类/标的
  365. // @Description 删除分类/标的
  366. // @Param request body aiPredictModel.AiPredictModelClassifyRemoveReq true "type json string"
  367. // @Success 200 Ret=200 删除成功
  368. // @router /classify/remove [post]
  369. func (this *AiPredictModelClassifyController) Remove() {
  370. br := new(models.BaseResponse).Init()
  371. defer func() {
  372. if br.ErrMsg == "" {
  373. br.IsSendEmail = false
  374. }
  375. this.Data["json"] = br
  376. this.ServeJSON()
  377. }()
  378. var req aiPredictModel.AiPredictModelClassifyRemoveReq
  379. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  380. br.Msg = "参数解析异常"
  381. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  382. return
  383. }
  384. if req.ClassifyId < 0 && req.IndexId <= 0 {
  385. br.Msg = "参数错误"
  386. return
  387. }
  388. // 删除分类
  389. if req.ClassifyId > 0 && req.IndexId == 0 {
  390. count, err := aiPredictModel.GetAiPredictModelIndexCountByClassifyId(req.ClassifyId)
  391. if err != nil && err.Error() != utils.ErrNoRow() {
  392. br.Msg = "删除失败"
  393. br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
  394. return
  395. }
  396. if count > 0 {
  397. br.Msg = "该目录下存在关联指标,不可删除"
  398. br.IsSendEmail = false
  399. return
  400. }
  401. err = aiPredictModel.RemoveAiPredictModelClassify(req.ClassifyId)
  402. if err != nil {
  403. br.Msg = "删除失败"
  404. br.ErrMsg = "删除失败,Err:" + err.Error()
  405. return
  406. }
  407. }
  408. // 删除标的
  409. if req.IndexId > 0 {
  410. indexOb := new(aiPredictModel.AiPredictModelIndex)
  411. aiIndex, e := indexOb.GetItemById(req.IndexId)
  412. if e != nil {
  413. if e.Error() == utils.ErrNoRow() {
  414. br.Ret = 200
  415. br.Msg = "删除成功"
  416. br.Success = true
  417. return
  418. }
  419. br.Msg = "操作失败"
  420. br.ErrMsg = fmt.Sprintf("获取标的信息失败, %v", e)
  421. return
  422. }
  423. // 删除标的及数据
  424. if e = indexOb.RemoveIndexAndData(req.IndexId); e != nil {
  425. br.Msg = "操作失败"
  426. br.ErrMsg = fmt.Sprintf("删除标的及数据失败, %v", e)
  427. return
  428. }
  429. // ES标记删除
  430. go func() {
  431. indexItem := new(dataSourceModel.SearchDataSource)
  432. indexItem.PrimaryId = aiIndex.AiPredictModelIndexId
  433. indexItem.IndexName = aiIndex.IndexName
  434. indexItem.IndexCode = aiIndex.IndexCode
  435. indexItem.ClassifyId = aiIndex.ClassifyId
  436. indexItem.Source = utils.DATA_SOURCE_AI_PREDICT_MODEL
  437. indexItem.SourceName = "AI预测模型"
  438. indexItem.IsDeleted = 1
  439. indexItem.CreateTime = utils.TimeTransferString(utils.FormatDateTime, aiIndex.CreateTime)
  440. indexItem.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, aiIndex.ModifyTime)
  441. docId := fmt.Sprintf("%d-%d", indexItem.Source, indexItem.PrimaryId)
  442. if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
  443. utils.FileLog.Info("AI预测模型-标记删除es失败, %v", e)
  444. return
  445. }
  446. }()
  447. }
  448. br.Ret = 200
  449. br.Msg = "删除成功"
  450. br.Success = true
  451. br.IsAddLog = true
  452. }
  453. // Move
  454. // @Title 移动
  455. // @Description 移动
  456. // @Success 200 {object} aiPredictModel.AiPredictModelClassifyMoveReq
  457. // @router /classify/move [post]
  458. func (this *AiPredictModelClassifyController) Move() {
  459. br := new(models.BaseResponse).Init()
  460. defer func() {
  461. if br.ErrMsg == "" {
  462. br.IsSendEmail = false
  463. }
  464. this.Data["json"] = br
  465. this.ServeJSON()
  466. }()
  467. sysUser := this.SysUser
  468. if sysUser == nil {
  469. br.Msg = "请登录"
  470. br.ErrMsg = "请登录,SysUser Is Empty"
  471. br.Ret = 408
  472. return
  473. }
  474. var req aiPredictModel.AiPredictModelClassifyMoveReq
  475. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  476. br.Msg = "参数解析异常"
  477. br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
  478. return
  479. }
  480. if req.ClassifyId <= 0 && req.ItemId <= 0 {
  481. br.Msg = "请选择分类或指标"
  482. return
  483. }
  484. err, errMsg := services.AiPredictModelMoveClassify(req, sysUser)
  485. if errMsg != `` {
  486. br.Msg = errMsg
  487. br.ErrMsg = errMsg
  488. if err != nil {
  489. br.ErrMsg = err.Error()
  490. } else {
  491. br.IsSendEmail = false
  492. }
  493. return
  494. }
  495. br.Ret = 200
  496. br.Success = true
  497. br.Msg = "移动成功"
  498. }