sa_doc.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. package semantic_analysis
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/rdlucklib/rdluck_tools/paging"
  6. "hongze/hz_eta_api/controllers"
  7. "hongze/hz_eta_api/models"
  8. saModel "hongze/hz_eta_api/models/semantic_analysis"
  9. "hongze/hz_eta_api/services"
  10. "hongze/hz_eta_api/utils"
  11. "html"
  12. "strings"
  13. "time"
  14. )
  15. // SaDocController 语义分析-文档
  16. type SaDocController struct {
  17. controllers.BaseAuthController
  18. }
  19. // Add
  20. // @Title 新增文档
  21. // @Description 新增文档
  22. // @Param request body saModel.SaDocAddReq true "type json string"
  23. // @Success 200 Ret=200 操作成功
  24. // @router /doc/add [post]
  25. func (this *SaDocController) Add() {
  26. br := new(models.BaseResponse).Init()
  27. defer func() {
  28. if br.ErrMsg == "" {
  29. br.IsSendEmail = false
  30. }
  31. this.Data["json"] = br
  32. this.ServeJSON()
  33. }()
  34. var req saModel.SaDocAddReq
  35. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  36. br.Msg = "参数解析异常!"
  37. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  38. return
  39. }
  40. req.Title = strings.TrimSpace(req.Title)
  41. if req.Title == "" {
  42. br.Msg = "请输入标题"
  43. return
  44. }
  45. if req.ClassifyId <= 0 {
  46. br.Msg = "请选择分类"
  47. return
  48. }
  49. // 过滤Editor版权内容
  50. req.Content = strings.Replace(req.Content, "Powered by Froala Editor", "", -1)
  51. req.Content = strings.Replace(req.Content, " ", "", -1)
  52. req.Content = strings.Replace(req.Content, "<p data-f-id=\"pbf\" style=\"text-align: center; font-size: 14px; margin-top: 30px; opacity: 0.65; font-family: sanered by <a href=\"https://www.froala.com/wysiwyg-editor?pb=1\" title=\"Froala Editor\">Froala Editor</a></p>", "", -1)
  53. if req.Content == "" {
  54. br.Msg = "请输入文档内容"
  55. return
  56. }
  57. // 重名校验、内容重复校验
  58. contentMd5 := utils.MD5(req.Content)
  59. existItem := new(saModel.SaDoc)
  60. existCond := ` AND %s = ? OR %s = ?`
  61. existCond = fmt.Sprintf(existCond, saModel.SaDocColumns.Title, saModel.SaDocColumns.ContentMd5)
  62. existPars := make([]interface{}, 0)
  63. existPars = append(existPars, req.Title, contentMd5)
  64. if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
  65. br.Msg = "操作失败"
  66. br.ErrMsg = "获取重复文档失败, Err: " + e.Error()
  67. return
  68. }
  69. if existItem != nil && existItem.SaDocId > 0 {
  70. if existItem.Title == req.Title {
  71. br.Msg = "文档名称已存在"
  72. }
  73. if existItem.ContentMd5 == contentMd5 {
  74. br.Msg = "该文档内容已上传"
  75. }
  76. return
  77. }
  78. // 拆分文档成段落, 分段读取
  79. sections, e := services.LoadSaDocContent2Section(req.Content)
  80. if e != nil || len(sections) == 0 {
  81. br.Msg = "内容段落信息有误"
  82. br.ErrMsg = "读取内容段落失败, Err: " + e.Error()
  83. return
  84. }
  85. // 分类
  86. classifyItem := new(saModel.SaDocClassify)
  87. if e = classifyItem.GetItemById(req.ClassifyId); e != nil {
  88. br.Msg = "分类信息有误"
  89. br.ErrMsg = "获取文档分类信息失败, Err: " + e.Error()
  90. return
  91. }
  92. // 新增
  93. newDoc := new(saModel.SaDoc)
  94. newDoc.ClassifyId = req.ClassifyId
  95. newDoc.ClassifyName = classifyItem.ClassifyName
  96. newDoc.Title = req.Title
  97. newDoc.CoverImg = classifyItem.CoverImg
  98. newDoc.ContentMd5 = contentMd5
  99. newDoc.SysAdminId = this.SysUser.AdminId
  100. newDoc.SysAdminName = this.SysUser.RealName
  101. newDoc.CreateTime = time.Now().Local()
  102. newDoc.ModifyTime = time.Now().Local()
  103. newSections := make([]*saModel.SaDocSection, 0)
  104. for i := range sections {
  105. newSections = append(newSections, &saModel.SaDocSection{
  106. Content: html.EscapeString(sections[i]),
  107. Sort: i + 1,
  108. })
  109. }
  110. if e = saModel.InsertSaDocAndSections(newDoc, newSections); e != nil {
  111. br.Msg = "操作失败"
  112. br.ErrMsg = "新增文档和段落失败, Err: " + e.Error()
  113. return
  114. }
  115. // 新增ES文档
  116. go func() {
  117. _ = services.HandleElasticSaDocAndSection(newDoc, newSections, []int{})
  118. }()
  119. br.Ret = 200
  120. br.Success = true
  121. br.Msg = "操作成功"
  122. br.Data = newDoc.SaDocId
  123. }
  124. // Edit
  125. // @Title 编辑文档
  126. // @Description 编辑文档
  127. // @Param request body saModel.SaDocEditReq true "type json string"
  128. // @Success 200 Ret=200 操作成功
  129. // @router /doc/edit [post]
  130. func (this *SaDocController) Edit() {
  131. br := new(models.BaseResponse).Init()
  132. defer func() {
  133. if br.ErrMsg == "" {
  134. br.IsSendEmail = false
  135. }
  136. this.Data["json"] = br
  137. this.ServeJSON()
  138. }()
  139. var req saModel.SaDocEditReq
  140. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  141. br.Msg = "参数解析异常!"
  142. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  143. return
  144. }
  145. if req.SaDocId <= 0 {
  146. br.Msg = "参数异常"
  147. return
  148. }
  149. req.Title = strings.TrimSpace(req.Title)
  150. if req.Title == "" {
  151. br.Msg = "请输入标题"
  152. return
  153. }
  154. if req.ClassifyId <= 0 {
  155. br.Msg = "请选择分类"
  156. return
  157. }
  158. if len(req.SectionList) == 0 {
  159. br.Msg = "段落不可为空"
  160. return
  161. }
  162. sectionIds := make([]int, 0)
  163. for i := range req.SectionList {
  164. if req.SectionList[i].Content == "" {
  165. br.Msg = "段落不可为空"
  166. return
  167. }
  168. if req.SectionList[i].SaDocSectionId > 0 {
  169. sectionIds = append(sectionIds, req.SectionList[i].SaDocSectionId)
  170. }
  171. }
  172. item := new(saModel.SaDoc)
  173. e := item.GetItemById(req.SaDocId)
  174. if e != nil {
  175. if e.Error() == utils.ErrNoRow() {
  176. br.Msg = "文档已被删除, 请刷新页面"
  177. return
  178. }
  179. br.Msg = "获取失败"
  180. br.ErrMsg = "获取文档信息失败, Err: " + e.Error()
  181. return
  182. }
  183. // 获取原段落
  184. sectionOB := new(saModel.SaDocSection)
  185. sectionCond := fmt.Sprintf(` AND %s = ?`, saModel.SaDocSectionColumns.DocId)
  186. sectionPars := make([]interface{}, 0)
  187. sectionPars = append(sectionPars, item.SaDocId)
  188. originSections, e := sectionOB.GetItemsByCondition(sectionCond, sectionPars, []string{saModel.SaDocSectionColumns.SaDocSectionId}, "")
  189. if e != nil {
  190. br.Msg = "获取失败"
  191. br.ErrMsg = "获取段落信息失败, Err: " + e.Error()
  192. return
  193. }
  194. originSectionIds := make([]int, 0)
  195. for i := range originSections {
  196. originSectionIds = append(originSectionIds, originSections[i].SaDocSectionId)
  197. }
  198. // 比对原段落, 判断段落SQL操作类型
  199. insertSecs := make([]*saModel.SaDocSection, 0)
  200. updateSecs := make([]*saModel.SaDocSection, 0)
  201. delSecIds := utils.MinusInt(originSectionIds, sectionIds)
  202. for i, v := range req.SectionList {
  203. v.Content = html.EscapeString(v.Content)
  204. v.Sort = i + 1
  205. // 新增
  206. if v.SaDocSectionId == 0 {
  207. insertSecs = append(insertSecs, v)
  208. continue
  209. }
  210. if utils.InArrayByInt(originSectionIds, v.SaDocSectionId) {
  211. updateSecs = append(updateSecs, v)
  212. }
  213. }
  214. // 分类
  215. classifyItem := new(saModel.SaDocClassify)
  216. if e = classifyItem.GetItemById(req.ClassifyId); e != nil {
  217. br.Msg = "分类信息有误"
  218. br.ErrMsg = "获取文档分类信息失败, Err: " + e.Error()
  219. return
  220. }
  221. item.Title = req.Title
  222. item.ClassifyId = req.ClassifyId
  223. item.ClassifyName = classifyItem.ClassifyName
  224. item.ModifyTime = time.Now().Local()
  225. updateCols := []string{
  226. saModel.SaDocColumns.Title, saModel.SaDocColumns.Theme, saModel.SaDocColumns.ClassifyId,
  227. saModel.SaDocColumns.ClassifyName, saModel.SaDocColumns.ModifyTime,
  228. }
  229. // 保存文档和段落
  230. updateSecCols := []string{saModel.SaDocSectionColumns.Content, saModel.SaDocSectionColumns.Sort}
  231. if e = saModel.UpdateSaDocAndSections(item, insertSecs, updateSecs, delSecIds, updateCols, updateSecCols); e != nil {
  232. br.Msg = "操作失败"
  233. br.ErrMsg = "更新文档段落失败, Err: " + e.Error()
  234. return
  235. }
  236. // 编辑ES文档
  237. go func() {
  238. sections := make([]*saModel.SaDocSection, 0)
  239. sections = append(sections, insertSecs...)
  240. sections = append(sections, updateSecs...)
  241. _ = services.HandleElasticSaDocAndSection(item, sections, delSecIds)
  242. }()
  243. br.Ret = 200
  244. br.Success = true
  245. br.Msg = "操作成功"
  246. br.Data = item.SaDocId
  247. }
  248. // Del
  249. // @Title 删除文档
  250. // @Description 删除文档
  251. // @Param request body saModel.SaDocDelReq true "type json string"
  252. // @Success 200 Ret=200 操作成功
  253. // @router /doc/del [post]
  254. func (this *SaDocController) Del() {
  255. br := new(models.BaseResponse).Init()
  256. defer func() {
  257. if br.ErrMsg == "" {
  258. br.IsSendEmail = false
  259. }
  260. this.Data["json"] = br
  261. this.ServeJSON()
  262. }()
  263. var req saModel.SaDocDelReq
  264. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  265. br.Msg = "参数解析异常!"
  266. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  267. return
  268. }
  269. if req.SaDocId <= 0 {
  270. br.Msg = "参数有误"
  271. return
  272. }
  273. item := new(saModel.SaDoc)
  274. e := item.GetItemById(req.SaDocId)
  275. if e != nil {
  276. if e.Error() == utils.ErrNoRow() {
  277. br.Msg = "文档已被删除, 请刷新页面"
  278. return
  279. }
  280. br.Msg = "操作失败"
  281. br.ErrMsg = "获取文档信息失败, Err: " + e.Error()
  282. return
  283. }
  284. secOB := new(saModel.SaDocSection)
  285. secCond := fmt.Sprintf(` AND %s = ?`, saModel.SaDocSectionColumns.DocId)
  286. secPars := make([]interface{}, 0)
  287. secPars = append(secPars, item.SaDocId)
  288. sections, e := secOB.GetItemsByCondition(secCond, secPars, []string{saModel.SaDocSectionColumns.SaDocSectionId}, "")
  289. if e != nil {
  290. br.Msg = "操作失败"
  291. br.ErrMsg = "获取文档段落信息失败, Err: " + e.Error()
  292. return
  293. }
  294. secIds := make([]int, 0)
  295. for i := range sections {
  296. secIds = append(secIds, sections[i].SaDocSectionId)
  297. }
  298. // 校验文档引用数
  299. useCond := fmt.Sprintf(` AND %s = ?`, saModel.SaCompareLabelColumns.DocId)
  300. usePars := make([]interface{}, 0)
  301. usePars = append(usePars, item.SaDocId)
  302. useOB := new(saModel.SaCompareLabel)
  303. count, e := useOB.GetCountByCondition(useCond, usePars)
  304. if e != nil {
  305. br.Msg = "操作失败"
  306. br.ErrMsg = "获取文档引用数失败, Err: " + e.Error()
  307. return
  308. }
  309. if count > 0 {
  310. br.Msg = "文档已被引用, 不可删除"
  311. return
  312. }
  313. // 删除文档及段落
  314. if e = saModel.DelSaDocAndSections(item.SaDocId); e != nil {
  315. br.Msg = "操作失败"
  316. br.ErrMsg = "删除文档失败, Err: " + e.Error()
  317. return
  318. }
  319. // 删除ES文档
  320. go func() {
  321. _ = services.DeleteElasticSaDocAndSection(item.SaDocId, secIds)
  322. }()
  323. br.Ret = 200
  324. br.Success = true
  325. br.Msg = "操作成功"
  326. }
  327. // Detail
  328. // @Title 文档详情
  329. // @Description 文档详情
  330. // @Param DocId query string true "文档ID"
  331. // @Success 200 Ret=200 获取成功
  332. // @router /doc/detail [get]
  333. func (this *SaDocController) Detail() {
  334. br := new(models.BaseResponse).Init()
  335. defer func() {
  336. if br.ErrMsg == "" {
  337. br.IsSendEmail = false
  338. }
  339. this.Data["json"] = br
  340. this.ServeJSON()
  341. }()
  342. docId, _ := this.GetInt("DocId", 0)
  343. if docId <= 0 {
  344. br.Msg = "参数异常"
  345. return
  346. }
  347. item := new(saModel.SaDoc)
  348. e := item.GetItemById(docId)
  349. if e != nil {
  350. if e.Error() == utils.ErrNoRow() {
  351. br.Msg = "文档已被删除, 请刷新页面"
  352. return
  353. }
  354. br.Msg = "获取失败"
  355. br.ErrMsg = "获取文档信息失败, Err: " + e.Error()
  356. return
  357. }
  358. // 获取段落
  359. sectionOB := new(saModel.SaDocSection)
  360. sectionCond := fmt.Sprintf(` AND %s = ?`, saModel.SaDocSectionColumns.DocId)
  361. sectionPars := make([]interface{}, 0)
  362. sectionPars = append(sectionPars, item.SaDocId)
  363. sectionList, e := sectionOB.GetItemsByCondition(sectionCond, sectionPars, []string{}, "")
  364. if e != nil {
  365. br.Msg = "获取失败"
  366. br.ErrMsg = "获取段落信息失败, Err: " + e.Error()
  367. return
  368. }
  369. secIds := make([]int, 0)
  370. for _, s := range sectionList {
  371. secIds = append(secIds, s.SaDocSectionId)
  372. }
  373. // 段落引用数
  374. useMap := make(map[int]int)
  375. usePartMap := make(map[int]int)
  376. if len(secIds) > 0 {
  377. // 整段
  378. useOB := new(saModel.SaCompareLabel)
  379. useCond := fmt.Sprintf(` AND %s IN (%s) AND %s = 0`, saModel.SaCompareLabelColumns.SectionId, utils.GetOrmInReplace(len(secIds)), saModel.SaCompareLabelColumns.IsPart)
  380. usePars := make([]interface{}, 0)
  381. usePars = append(usePars, secIds)
  382. countList, e := useOB.GetGroupCountByCondition(useCond, usePars, saModel.SaCompareLabelColumns.SectionId)
  383. if e != nil && e.Error() != utils.ErrNoRow() {
  384. br.Msg = "获取失败"
  385. br.ErrMsg = "获取标签段落引用数失败, Err: " + e.Error()
  386. return
  387. }
  388. for i := range countList {
  389. useMap[countList[i].SectionId] = countList[i].UseNum
  390. }
  391. // 片段
  392. usePartCond := fmt.Sprintf(` AND %s IN (%s) AND %s = 1`, saModel.SaCompareLabelColumns.SectionId, utils.GetOrmInReplace(len(secIds)), saModel.SaCompareLabelColumns.IsPart)
  393. usePartPars := make([]interface{}, 0)
  394. usePartPars = append(usePartPars, secIds)
  395. countPartList, e := useOB.GetGroupCountByCondition(usePartCond, usePartPars, saModel.SaCompareLabelColumns.SectionId)
  396. for i := range countPartList {
  397. usePartMap[countPartList[i].SectionId] = countPartList[i].UseNum
  398. }
  399. }
  400. secList := make([]*saModel.SaDocSectionItem, 0)
  401. for _, s := range sectionList {
  402. c := html.UnescapeString(s.Content)
  403. c = strings.ReplaceAll(c, `<p>`, "")
  404. c = strings.ReplaceAll(c, `</p>`, "")
  405. s.Content = c
  406. v := new(saModel.SaDocSectionItem)
  407. v.SaDocSection = *s
  408. v.UseNum = useMap[s.SaDocSectionId]
  409. v.UsePartNum = usePartMap[s.SaDocSectionId]
  410. secList = append(secList, v)
  411. }
  412. detail := new(saModel.SaDocDetail)
  413. detail.SaDocId = item.SaDocId
  414. detail.ClassifyId = item.ClassifyId
  415. detail.ClassifyName = item.ClassifyName
  416. detail.Title = item.Title
  417. detail.Theme = item.Theme
  418. detail.CoverImg = item.CoverImg
  419. detail.SysAdminId = item.SysAdminId
  420. detail.SysAdminName = item.SysAdminName
  421. detail.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
  422. detail.SectionList = secList
  423. br.Data = detail
  424. br.Ret = 200
  425. br.Success = true
  426. br.Msg = "获取成功"
  427. }
  428. // PageList
  429. // @Title 文档列表
  430. // @Description 文档列表
  431. // @Param Keyword query string false "文档关键词"
  432. // @Param ClassifyId query int false "文档分类ID"
  433. // @Success 200 Ret=200 获取成功
  434. // @router /doc/page_list [get]
  435. func (this *SaDocController) PageList() {
  436. br := new(models.BaseResponse).Init()
  437. defer func() {
  438. if br.ErrMsg == "" {
  439. br.IsSendEmail = false
  440. }
  441. this.Data["json"] = br
  442. this.ServeJSON()
  443. }()
  444. keyword := this.GetString("Keyword", "")
  445. classifyId, _ := this.GetInt("ClassifyId", 0)
  446. var startSize int
  447. pageSize, _ := this.GetInt("PageSize")
  448. currentIndex, _ := this.GetInt("CurrentIndex")
  449. if pageSize <= 0 {
  450. pageSize = utils.PageSize20
  451. }
  452. if currentIndex <= 0 {
  453. currentIndex = 1
  454. }
  455. startSize = paging.StartIndex(currentIndex, pageSize)
  456. itemOB := new(saModel.SaDoc)
  457. cond := ``
  458. pars := make([]interface{}, 0)
  459. if keyword != "" {
  460. kw := "%" + keyword + "%"
  461. cond += fmt.Sprintf(` AND %s LIKE ?`, saModel.SaDocColumns.Title)
  462. pars = append(pars, kw)
  463. }
  464. if classifyId > 0 {
  465. cond += fmt.Sprintf(` AND %s = ?`, saModel.SaDocColumns.ClassifyId)
  466. pars = append(pars, classifyId)
  467. }
  468. total, list, e := itemOB.GetPageItemsByCondition(startSize, pageSize, cond, pars, []string{}, "sort ASC, create_time DESC, sa_doc_id ASC")
  469. if e != nil {
  470. br.Msg = "获取失败"
  471. br.ErrMsg = "获取文档列表失败, Err: " + e.Error()
  472. return
  473. }
  474. respList := make([]*saModel.SaDocItem, 0)
  475. for i := range list {
  476. v := new(saModel.SaDocItem)
  477. v.SaDocId = list[i].SaDocId
  478. v.ClassifyId = list[i].ClassifyId
  479. v.ClassifyName = list[i].ClassifyName
  480. v.CoverImg = list[i].CoverImg
  481. v.Title = list[i].Title
  482. v.Theme = list[i].Theme
  483. v.SysAdminId = list[i].SysAdminId
  484. v.SysAdminName = list[i].SysAdminName
  485. v.Sort = list[i].Sort
  486. v.CreateTime = list[i].CreateTime.Format(utils.FormatDateTime)
  487. respList = append(respList, v)
  488. }
  489. page := paging.GetPaging(currentIndex, pageSize, total)
  490. resp := &saModel.SaDocPageListResp{
  491. Paging: page,
  492. List: respList,
  493. }
  494. br.Data = resp
  495. br.Ret = 200
  496. br.Success = true
  497. br.Msg = "获取成功"
  498. }
  499. // Move
  500. // @Title 移动文档
  501. // @Description 移动文档
  502. // @Param request body saModel.SaDocEditReq true "type json string"
  503. // @Success 200 Ret=200 操作成功
  504. // @router /doc/move [post]
  505. func (this *SaDocController) Move() {
  506. br := new(models.BaseResponse).Init()
  507. defer func() {
  508. if br.ErrMsg == "" {
  509. br.IsSendEmail = false
  510. }
  511. this.Data["json"] = br
  512. this.ServeJSON()
  513. }()
  514. var req saModel.SaDocMoveReq
  515. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  516. br.Msg = "参数解析异常!"
  517. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  518. return
  519. }
  520. if req.SaDocClassifyId <= 0 {
  521. br.Msg = "请选择分类"
  522. return
  523. }
  524. if req.SaDocId <= 0 {
  525. br.Msg = "参数异常"
  526. return
  527. }
  528. item := new(saModel.SaDoc)
  529. e := item.GetItemById(req.SaDocId)
  530. if e != nil {
  531. if e.Error() == utils.ErrNoRow() {
  532. br.Msg = "文档已被删除, 请刷新页面"
  533. return
  534. }
  535. br.Msg = "操作失败"
  536. br.ErrMsg = "获取文档信息失败, Err: " + e.Error()
  537. return
  538. }
  539. originClassifyId := item.ClassifyId
  540. // 分类
  541. classifyItem := new(saModel.SaDocClassify)
  542. if e = classifyItem.GetItemById(req.SaDocClassifyId); e != nil {
  543. br.Msg = "分类信息有误"
  544. br.ErrMsg = "获取文档分类信息失败, Err: " + e.Error()
  545. return
  546. }
  547. // CV的指标库指标的移动, 没有技术, 全是感情~
  548. if req.PrevSaDocId > 0 {
  549. prevDoc := new(saModel.SaDoc)
  550. if e = prevDoc.GetItemById(req.PrevSaDocId); e != nil {
  551. if e.Error() == utils.ErrNoRow() {
  552. br.Msg = "上一个文档已被删除, 请刷新页面"
  553. return
  554. }
  555. br.Msg = "操作失败"
  556. br.ErrMsg = "获取上一个文档信息失败, Err: " + e.Error()
  557. return
  558. }
  559. // 如果是在两个文档之间
  560. if req.NextSaDocId > 0 {
  561. nextDoc := new(saModel.SaDoc)
  562. if e = nextDoc.GetItemById(req.NextSaDocId); e != nil {
  563. if e.Error() == utils.ErrNoRow() {
  564. br.Msg = "下一个文档已被删除, 请刷新页面"
  565. return
  566. }
  567. br.Msg = "操作失败"
  568. br.ErrMsg = "获取下一个文档信息失败, Err: " + e.Error()
  569. return
  570. }
  571. // 判断上一个文档与当前文档/下一个文档的位置
  572. if prevDoc.Sort == item.Sort || prevDoc.Sort == nextDoc.Sort {
  573. _ = saModel.UpdateSaDocSort(prevDoc.ClassifyId, prevDoc.Sort, prevDoc.SaDocId, `sort + 2`)
  574. } else {
  575. if nextDoc.Sort-prevDoc.Sort == 1 {
  576. _ = saModel.UpdateSaDocSort(prevDoc.ClassifyId, prevDoc.Sort, prevDoc.SaDocId, `sort + 1`)
  577. }
  578. }
  579. }
  580. item.Sort = prevDoc.Sort + 1
  581. } else {
  582. firstDoc, e := saModel.GetFirstSortSaDoc(req.SaDocClassifyId)
  583. if e != nil && e.Error() != utils.ErrNoRow() {
  584. br.Msg = "操作失败"
  585. br.ErrMsg = "获取首个文档失败, Err: " + e.Error()
  586. return
  587. }
  588. if firstDoc != nil && firstDoc.Sort == 0 {
  589. _ = saModel.UpdateSaDocSort(firstDoc.ClassifyId, 0, firstDoc.SaDocId-1, `sort + 1`)
  590. }
  591. item.Sort = 0
  592. }
  593. // 更新
  594. item.ClassifyId = classifyItem.SaDocClassifyId
  595. item.ClassifyName = classifyItem.ClassifyName
  596. item.ModifyTime = time.Now().Local()
  597. updateCols := []string{
  598. saModel.SaDocColumns.ClassifyId, saModel.SaDocColumns.ClassifyName, saModel.SaDocColumns.Sort, saModel.SaDocColumns.ModifyTime,
  599. }
  600. if e = item.Update(updateCols); e != nil {
  601. br.Msg = "操作失败"
  602. br.ErrMsg = "移动文档失败, Err: " + e.Error()
  603. return
  604. }
  605. // 若更改了分类-则更新ES文档
  606. if originClassifyId != req.SaDocClassifyId {
  607. go func() {
  608. sectionOB := new(saModel.SaDocSection)
  609. sectionCond := fmt.Sprintf(` AND %s = ?`, saModel.SaDocSectionColumns.DocId)
  610. sectionPars := make([]interface{}, 0)
  611. sectionPars = append(sectionPars, item.SaDocId)
  612. sections, e := sectionOB.GetItemsByCondition(sectionCond, sectionPars, []string{}, "")
  613. if e != nil {
  614. return
  615. }
  616. _ = services.HandleElasticSaDocAndSection(item, sections, []int{})
  617. }()
  618. }
  619. br.Ret = 200
  620. br.Success = true
  621. br.Msg = "操作成功"
  622. br.Data = item.SaDocId
  623. }