classify.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. package services
  2. import (
  3. "errors"
  4. "eta/eta_api/models"
  5. "eta/eta_api/models/report_approve"
  6. "eta/eta_api/utils"
  7. "fmt"
  8. "sort"
  9. "time"
  10. )
  11. // MoveReportClassify 移动分类
  12. func MoveReportClassify(req models.ClassifyMoveReq) (err error, errMsg string) {
  13. classifyId := req.ClassifyId
  14. prevClassifyId := req.PrevClassifyId
  15. nextClassifyId := req.NextClassifyId
  16. //如果有传入 上一个兄弟节点分类id
  17. var (
  18. classifyInfo *models.Classify
  19. prevClassify *models.Classify
  20. nextClassify *models.Classify
  21. prevSort int
  22. nextSort int
  23. )
  24. // 移动对象为分类, 判断权限
  25. classifyInfo, err = models.GetClassifyById(classifyId)
  26. if err != nil {
  27. if err.Error() == utils.ErrNoRow() {
  28. errMsg = "分类不存在, 请刷新页面"
  29. err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
  30. return
  31. }
  32. errMsg = "移动失败"
  33. err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
  34. return
  35. } else if classifyInfo.Id == 0 {
  36. errMsg = "分类不存在, 请刷新页面"
  37. err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
  38. return
  39. }
  40. parentClassifyId := classifyInfo.ParentId
  41. if prevClassifyId > 0 {
  42. prevClassify, err = models.GetClassifyById(prevClassifyId)
  43. if err != nil {
  44. if err.Error() == utils.ErrNoRow() {
  45. errMsg = "上一个分类不存在, 请刷新页面"
  46. err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
  47. return
  48. }
  49. errMsg = "移动失败"
  50. err = fmt.Errorf("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
  51. return
  52. }
  53. if prevClassify.ParentId != parentClassifyId {
  54. errMsg = "禁止拖动到其他节点"
  55. err = fmt.Errorf(errMsg)
  56. return
  57. }
  58. prevSort = prevClassify.Sort
  59. }
  60. if nextClassifyId > 0 {
  61. //下一个兄弟节点
  62. nextClassify, err = models.GetClassifyById(nextClassifyId)
  63. if err != nil {
  64. if err.Error() == utils.ErrNoRow() {
  65. errMsg = "下一个分类不存在, 请刷新页面"
  66. err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
  67. return
  68. }
  69. errMsg = "移动失败"
  70. err = fmt.Errorf("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
  71. return
  72. }
  73. if nextClassify.ParentId != parentClassifyId {
  74. errMsg = "禁止拖动到其他节点"
  75. err = fmt.Errorf(errMsg)
  76. return
  77. }
  78. nextSort = nextClassify.Sort
  79. }
  80. err, errMsg = moveReportClassify(classifyInfo, prevClassify, nextClassify, parentClassifyId, prevSort, nextSort)
  81. return
  82. }
  83. // moveReportClassify 移动分类
  84. func moveReportClassify(classifyInfo, prevClassify, nextClassify *models.Classify, parentId, prevSort, nextSort int) (err error, errMsg string) {
  85. ob := new(models.Classify)
  86. updateCol := make([]string, 0)
  87. //判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
  88. if classifyInfo.ParentId != parentId {
  89. errMsg = "移动失败"
  90. err = fmt.Errorf("不支持目录层级变更")
  91. return
  92. }
  93. if prevSort > 0 {
  94. //如果是移动在两个兄弟节点之间
  95. if nextSort > 0 {
  96. //下一个兄弟节点
  97. //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
  98. if prevSort == nextSort || prevSort == classifyInfo.Sort {
  99. //变更兄弟节点的排序
  100. updateSortStr := `sort + 2`
  101. //变更分类
  102. if prevClassify != nil {
  103. _ = models.UpdateClassifySortByParentId(parentId, prevClassify.Id, prevClassify.Sort, updateSortStr)
  104. } else {
  105. _ = models.UpdateClassifySortByParentId(parentId, 0, prevSort, updateSortStr)
  106. }
  107. } else {
  108. //如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
  109. if nextSort-prevSort == 1 {
  110. //变更兄弟节点的排序
  111. updateSortStr := `sort + 1`
  112. //变更分类
  113. if prevClassify != nil {
  114. _ = models.UpdateClassifySortByParentId(parentId, prevClassify.Id, prevSort, updateSortStr)
  115. } else {
  116. _ = models.UpdateClassifySortByParentId(parentId, 0, prevSort, updateSortStr)
  117. }
  118. }
  119. }
  120. }
  121. classifyInfo.Sort = prevSort + 1
  122. classifyInfo.ModifyTime = time.Now()
  123. updateCol = append(updateCol, "Sort", "ModifyTime")
  124. } else if prevClassify == nil && nextClassify == nil && parentId > 0 {
  125. //处理只拖动到目录里,默认放到目录底部的情况
  126. var maxSort int
  127. maxSort, err = ob.GetMaxSortByParentId(parentId)
  128. if err != nil {
  129. errMsg = "移动失败"
  130. err = fmt.Errorf("查询组内排序信息失败,Err:" + err.Error())
  131. return
  132. }
  133. classifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
  134. classifyInfo.ModifyTime = time.Now()
  135. updateCol = append(updateCol, "Sort", "ModifyTime")
  136. } else {
  137. // 拖动到父级分类的第一位
  138. firstPermission, tmpErr := ob.GetFirstClassifyByParentId(parentId)
  139. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  140. errMsg = "移动失败"
  141. err = fmt.Errorf("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
  142. return
  143. }
  144. //如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
  145. if firstPermission != nil && firstPermission.Id != 0 && firstPermission.Sort == 0 {
  146. updateSortStr := ` sort + 1 `
  147. _ = models.UpdateClassifySortByParentId(parentId, firstPermission.Id-1, 0, updateSortStr)
  148. }
  149. classifyInfo.Sort = 0 //那就是排在第一位
  150. classifyInfo.ModifyTime = time.Now()
  151. updateCol = append(updateCol, "Sort", "ModifyTime")
  152. }
  153. //更新
  154. if len(updateCol) > 0 {
  155. err = classifyInfo.UpdateClassify(updateCol)
  156. if err != nil {
  157. errMsg = "移动失败"
  158. err = fmt.Errorf("修改失败,Err:" + err.Error())
  159. return
  160. }
  161. }
  162. return
  163. }
  164. // AddReportClassify
  165. // @Description: 添加报告分类
  166. // @author: Roc
  167. // @datetime 2024-06-17 11:01:21
  168. // @param classifyName string
  169. // @param parentId int
  170. // @param chartPermissionIdList []int
  171. // @return err error
  172. // @return errMsg string
  173. // @return isSendEmail bool
  174. func AddReportClassify(classifyName string, parentId int, chartPermissionIdList []int) (err error, errMsg string, isSendEmail bool) {
  175. isSendEmail = true
  176. errMsg = `添加失败`
  177. item, err := models.GetClassifyByName(classifyName, parentId)
  178. if err != nil && err.Error() != utils.ErrNoRow() {
  179. errMsg = "获取分类信息失败"
  180. if err.Error() == utils.ErrNoRow() {
  181. errMsg = "分类名称:" + classifyName + "已存在"
  182. isSendEmail = false
  183. }
  184. return
  185. }
  186. if item != nil {
  187. errMsg = "分类名称:" + classifyName + "已存在"
  188. isSendEmail = false
  189. err = errors.New(errMsg)
  190. return
  191. }
  192. level := 1
  193. // 父级分类
  194. var parentClassifyItem *models.Classify
  195. // 父级分类下的子分类数量
  196. var childClassifyCount int
  197. if parentId > 0 {
  198. // 获取父级分类信息
  199. parentClassifyItem, err = models.GetClassifyById(parentId)
  200. if err != nil {
  201. errMsg = "获取父级分类信息失败"
  202. if err.Error() == utils.ErrNoRow() {
  203. errMsg = "父级分类不存在"
  204. }
  205. return
  206. }
  207. level = parentClassifyItem.Level + 1
  208. if level > 3 {
  209. errMsg = "分类层级不可超过三级"
  210. isSendEmail = false
  211. return
  212. }
  213. // 判断是否分类存在待操作的审批单
  214. err, errMsg = checkClassifyApprove(parentClassifyItem)
  215. if err != nil {
  216. return
  217. }
  218. // 获取父级分类下的子分类数量
  219. childClassifyCount, err = models.GetCountClassifyChildByParentId(parentId)
  220. if err != nil {
  221. errMsg = "获取父级分类的子分类信息失败"
  222. return
  223. }
  224. }
  225. nowTime := time.Now().Local()
  226. classify := new(models.Classify)
  227. maxSort, err := classify.GetMaxSort()
  228. if err != nil {
  229. errMsg = "操作失败"
  230. err = errors.New("查询品种排序失败, Err: " + err.Error())
  231. return
  232. }
  233. classify.ClassifyName = classifyName
  234. classify.ParentId = parentId
  235. classify.CreateTime = nowTime
  236. classify.ModifyTime = nowTime
  237. classify.Sort = maxSort + 1
  238. classify.Enabled = 1
  239. classify.ShowType = 1 //默认列表格式
  240. classify.ReportDetailShowType = 1 //默认列表格式
  241. classify.IsShow = 1
  242. classify.Level = level
  243. /*classify.Abstract = req.Abstract
  244. classify.Descript = req.Descript
  245. classify.Abstract = req.Abstract
  246. classify.Descript = req.Descript
  247. classify.ReportAuthor = req.ReportAuthor
  248. classify.AuthorDescript = req.AuthorDescript
  249. classify.ColumnImgUrl = req.ColumnImgUrl
  250. classify.ReportImgUrl = req.ReportImgUrl
  251. classify.HeadImgUrl = req.HeadImgUrl
  252. classify.AvatarImgUrl = req.AvatarImgUrl
  253. classify.HomeImgUrl = req.HomeImgUrl
  254. classify.ClassifyLabel = req.ClassifyLabel
  255. classify.ShowType = req.ShowType
  256. classify.HasTeleconference = req.HasTeleconference
  257. classify.VipTitle = req.VipTitle
  258. classify.IsShow = req.IsShow
  259. classify.YbFiccSort = req.YbFiccSort
  260. classify.YbFiccIcon = req.YbFiccIcon
  261. classify.YbFiccPcIcon = req.YbFiccPcIcon
  262. classify.YbIconUrl = req.YbIconUrl
  263. classify.YbBgUrl = req.YbBgUrl
  264. classify.YbListImg = req.YbListImg
  265. classify.YbShareBgImg = req.YbShareBgImg
  266. classify.YbRightBanner = req.YbRightBanner
  267. classify.RelateTel = req.RelateTel
  268. classify.RelateVideo = req.RelateVideo
  269. if req.ParentId > 0 {
  270. parentClassify := new(models.Classify)
  271. if parentClassify, err = models.GetClassifyById(req.ParentId); err != nil {
  272. br.Msg = "获取父级分类信息失败"
  273. br.ErrMsg = "获取父级分类信息失败, Err:" + err.Error()
  274. return
  275. }
  276. updateParent := false
  277. updateCols := make([]string, 0)
  278. updateCols = append(updateCols, "HasTeleconference")
  279. if req.HasTeleconference == 1 {
  280. // 二级分类包含电话会,则一级分类也默认包含电话会
  281. if parentClassify.HasTeleconference == 0 {
  282. parentClassify.HasTeleconference = 1
  283. updateParent = true
  284. }
  285. } else {
  286. // 二级分类均无电话会,则一级分类也无电话会
  287. if parentClassify.HasTeleconference == 1 {
  288. child, err := models.GetClassifyChild(parentClassify.Id, "")
  289. if err != nil {
  290. br.Msg = "获取子分类失败"
  291. br.ErrMsg = "获取子分类失败,Err:" + err.Error()
  292. return
  293. }
  294. // 存在同一级分类下的二级分类有电话会则不变动
  295. hasTel := false
  296. for i := 0; i < len(child); i++ {
  297. if child[i].HasTeleconference == 1 {
  298. hasTel = true
  299. break
  300. }
  301. }
  302. if !hasTel {
  303. parentClassify.HasTeleconference = 0
  304. updateParent = true
  305. }
  306. }
  307. }
  308. if updateParent {
  309. if err = parentClassify.UpdateClassify(updateCols); err != nil {
  310. br.Msg = "更新父级分类失败"
  311. br.ErrMsg = "更新父级分类失败, Err:" + err.Error()
  312. return
  313. }
  314. }
  315. }*/
  316. err = models.AddClassify(classify)
  317. if err != nil {
  318. return
  319. }
  320. //获取报告分类权限列表
  321. err = models.EditChartPermissionSearchKeyWordMappingMulti(classifyName, chartPermissionIdList, classify.Id)
  322. if err != nil {
  323. errMsg = "修改分类权限失败"
  324. return
  325. }
  326. // 修改CRM权限
  327. go func() {
  328. _ = EditClassifyChartPermissionSync(classifyName, classify.Id)
  329. }()
  330. // 如果父级分类不为空的话,那么就标记有子级分类,同时
  331. if parentClassifyItem != nil {
  332. parentClassifyItem.HasChild = 1
  333. parentClassifyItem.UpdateClassify([]string{"HasChild"})
  334. // 如果以前没有子级分类,那么就继承父级分类下的章节类型(创建新的章节与分类的关系)
  335. if childClassifyCount <= 0 {
  336. // 继承父级分类下的章节类型(创建新的章节与分类的关系)
  337. tmpErr := inheritReportChapterType(parentId, classify.Id)
  338. if tmpErr != nil {
  339. return
  340. }
  341. // 继承父级分类审批流
  342. go inheritReportApproveFlow(parentClassifyItem, classify)
  343. moveReportByAddClassify(parentClassifyItem, classify)
  344. }
  345. }
  346. return
  347. }
  348. // checkClassifyApprove
  349. // @Description: 判断分类是否存在待操作的审批单
  350. // @author: Roc
  351. // @datetime 2024-06-27 13:19:15
  352. // @param currClassify *models.Classify
  353. // @return err error
  354. // @return errMsg string
  355. func checkClassifyApprove(currClassify *models.Classify) (err error, errMsg string) {
  356. errMsg = `判断是否有审批流关联失败`
  357. var firstClassifyId, secondClassifyId int
  358. if currClassify.ParentId > 0 {
  359. parentClassifyItem, tmpErr := models.GetClassifyById(currClassify.ParentId)
  360. if tmpErr != nil {
  361. err = tmpErr
  362. errMsg = "获取父级分类信息失败"
  363. if tmpErr.Error() == utils.ErrNoRow() {
  364. errMsg = "父级分类不存在"
  365. }
  366. return
  367. }
  368. firstClassifyId = parentClassifyItem.Id
  369. secondClassifyId = currClassify.Id
  370. } else {
  371. firstClassifyId = currClassify.Id
  372. }
  373. // 校验审批流是否关联了进行中的审批
  374. {
  375. flowOb := new(report_approve.ReportApproveFlow)
  376. existCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ? AND %s = ?`, report_approve.ReportApproveFlowCols.ReportType, report_approve.ReportApproveFlowCols.ClassifyFirstId, report_approve.ReportApproveFlowCols.ClassifySecondId, report_approve.ReportApproveFlowCols.ClassifyThirdId)
  377. existPars := make([]interface{}, 0)
  378. existPars = append(existPars, report_approve.FlowReportTypeChinese, firstClassifyId, secondClassifyId, 0)
  379. flowItem, e := flowOb.GetItemByCondition(existCond, existPars, "")
  380. if e != nil {
  381. // 父级分类如果没有审批流,那么就正常进行就好了
  382. if e.Error() != utils.ErrNoRow() {
  383. err = errors.New("获取审批流是否已存在失败, Err: " + e.Error())
  384. return
  385. }
  386. err = nil
  387. return
  388. }
  389. if flowItem == nil {
  390. return
  391. }
  392. approvingOb := new(report_approve.ReportApprove)
  393. approvingCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ?`, report_approve.ReportApproveCols.FlowId, report_approve.ReportApproveCols.FlowVersion, report_approve.ReportApproveCols.State)
  394. approvingPars := make([]interface{}, 0)
  395. approvingPars = append(approvingPars, flowItem.ReportApproveFlowId, flowItem.CurrVersion, report_approve.ReportApproveStateApproving)
  396. count, e := approvingOb.GetCountByCondition(approvingCond, approvingPars)
  397. if e != nil {
  398. err = errors.New("获取审批流关联进行中的审批数失败. Err: " + e.Error())
  399. return
  400. }
  401. if count > 0 {
  402. errMsg = "当前有未走完流程的报告,请走完流程后再做变更"
  403. err = errors.New(errMsg)
  404. return
  405. }
  406. }
  407. return
  408. }
  409. // 关于研报分类,因只允许报告或品种关联在最小分类下,所以当某个父分类(非三级分类)已关联报告或品种,需要在该父分类下增加子分类,则第一个子分类添加成功时,默认把该父分类关联的品种和报告转移至新创建的子分类(第一个子分类)下
  410. // moveReportByAddClassify
  411. // @Description: 报告和章节的转移
  412. // @author: Roc
  413. // @datetime 2024-06-17 16:29:56
  414. // @param parentClassifyInfo *models.Classify
  415. // @param currClassifyInfo *models.Classify
  416. // @return err error
  417. func moveReportByAddClassify(parentClassifyInfo, currClassifyInfo *models.Classify) (err error) {
  418. defer func() {
  419. if err != nil {
  420. utils.FileLog.Error(fmt.Sprint("历史报告更改分类失败,父级分类ID:", parentClassifyInfo.Id, ";当前分类ID:", currClassifyInfo.Id, ";错误信息:", err.Error()))
  421. }
  422. }()
  423. if currClassifyInfo.Level > 3 {
  424. err = errors.New("父级分类不支持三级分类以上")
  425. return
  426. }
  427. // 报告的分类归属调整,转为下一级的分类
  428. var condition, updateStr string
  429. pars := make([]interface{}, 0)
  430. switch currClassifyInfo.Level {
  431. case 3: // 当前分类是3级分类
  432. updateStr += ` classify_id_third = ?,classify_name_third = ?`
  433. condition += ` AND classify_id_second = ? `
  434. case 2: // 当前分类是2级分类
  435. updateStr += ` classify_id_second = ?,classify_name_second = ?`
  436. condition += ` AND classify_id_first = ? `
  437. default:
  438. err = errors.New("错误的分类层级")
  439. return
  440. }
  441. pars = append(pars, currClassifyInfo.Id, currClassifyInfo.ClassifyName, parentClassifyInfo.Id)
  442. // 获取当前分类下的所有章节类型
  443. currReportChapterTypeList, err := models.GetAllReportChapterTypeListByClassifyId(currClassifyInfo.Id)
  444. if err != nil {
  445. return
  446. }
  447. // 当前的章节类型ID ---> 继承的章节类型ID
  448. chapterTypeIdMap := make(map[int]int)
  449. for _, v := range currReportChapterTypeList {
  450. chapterTypeIdMap[v.ReportChapterTypeId] = v.InheritReportChapterTypeId
  451. }
  452. // 报告转移后,历史章节报告中的type_id也要修复成最新的type_id
  453. err = models.ModifyReportClassifyAndReportChapterTypeByCondition(condition, pars, updateStr, chapterTypeIdMap, parentClassifyInfo.Id, currClassifyInfo.Id, currClassifyInfo.ClassifyName)
  454. if err != nil {
  455. return
  456. }
  457. return
  458. }
  459. // inheritReportChapterType
  460. // @Description: 继承父级分类下的章节类型
  461. // @author: Roc
  462. // @datetime 2024-06-17 14:41:04
  463. // @param parentClassifyId int
  464. // @param currClassifyId int
  465. // @return err error
  466. func inheritReportChapterType(parentClassifyId, currClassifyId int) (err error) {
  467. defer func() {
  468. if err != nil {
  469. utils.FileLog.Error(fmt.Sprint("继承父级分类下的章节类型失败,父级分类ID:", parentClassifyId, ";当前分类ID:", currClassifyId, ";错误信息:", err.Error()))
  470. }
  471. }()
  472. parentReportChapterTypeList, err := models.GetAllReportChapterTypeListByClassifyId(parentClassifyId)
  473. if err != nil {
  474. return
  475. }
  476. // 如果没有章节类型,那么就直接返回
  477. if len(parentReportChapterTypeList) <= 0 {
  478. return
  479. }
  480. addList := make([]*models.ReportChapterType, 0)
  481. for _, v := range parentReportChapterTypeList {
  482. addList = append(addList, &models.ReportChapterType{
  483. //ReportChapterTypeId: 0,
  484. ReportChapterTypeKey: v.ReportChapterTypeKey,
  485. ReportChapterTypeThumb: v.ReportChapterTypeThumb,
  486. BannerUrl: v.BannerUrl,
  487. ReportChapterTypeName: v.ReportChapterTypeName,
  488. Sort: v.Sort,
  489. Enabled: v.Enabled,
  490. CreatedTime: time.Now(),
  491. LastUpdatedTime: time.Now(),
  492. ResearchType: v.ResearchType,
  493. SelectedImage: v.SelectedImage,
  494. UnselectedImage: v.UnselectedImage,
  495. PcSelectedImage: v.PcSelectedImage,
  496. PcUnselectedImage: v.PcUnselectedImage,
  497. EditImgUrl: v.EditImgUrl,
  498. TickerTitle: v.TickerTitle,
  499. IsShow: v.IsShow,
  500. PauseStartTime: v.PauseStartTime,
  501. PauseEndTime: v.PauseEndTime,
  502. IsSet: v.IsSet,
  503. YbIconUrl: v.YbIconUrl,
  504. YbBottomIcon: v.YbBottomIcon,
  505. ReportClassifyId: currClassifyId,
  506. InheritReportChapterTypeId: v.ReportChapterTypeId,
  507. })
  508. }
  509. obj := models.ReportChapterType{}
  510. err = obj.MultiCreate(addList)
  511. // 修改CRM权限
  512. go func() {
  513. var syncReq ChapterTypeSyncReq
  514. _, _ = ReportChapterTypeSync(&syncReq)
  515. }()
  516. return
  517. }
  518. // inheritReportApproveFlow
  519. // @Description: 继承父级分类下的审批流
  520. // @author: Roc
  521. // @datetime 2024-06-17 14:41:04
  522. // @param parentClassifyId int
  523. // @param currClassifyId int
  524. // @return err error
  525. func inheritReportApproveFlow(parentClassifyItem, currClassifyItem *models.Classify) (err error) {
  526. defer func() {
  527. if err != nil {
  528. utils.FileLog.Error(fmt.Sprint("继承父级分类下的审批流失败,父级分类ID:", parentClassifyItem.Id, ";当前分类ID:", currClassifyItem.Id, ";错误信息:", err.Error()))
  529. }
  530. }()
  531. var firstClassify, secondClassify, thirdClassify *models.Classify
  532. if parentClassifyItem.ParentId > 0 {
  533. // 获取父级分类信息
  534. firstClassify, err = models.GetClassifyById(parentClassifyItem.ParentId)
  535. if err != nil {
  536. return
  537. }
  538. secondClassify = parentClassifyItem
  539. thirdClassify = currClassifyItem
  540. } else {
  541. firstClassify = parentClassifyItem
  542. secondClassify = currClassifyItem
  543. }
  544. flowObj := report_approve.ReportApproveFlow{}
  545. // 获取父级的审批流
  546. existCond := fmt.Sprintf(` AND %s = ? AND %s = ? `, report_approve.ReportApproveFlowCols.ReportType, report_approve.ReportApproveFlowCols.ClassifyFirstId)
  547. existPars := make([]interface{}, 0)
  548. existPars = append(existPars, report_approve.FlowReportTypeChinese, firstClassify.Id)
  549. // 如果这是第三级,那么说明只需要查找第二级的审批配置就好了
  550. if thirdClassify != nil {
  551. existCond = fmt.Sprintf(`%s AND %s = ?`, existCond, report_approve.ReportApproveFlowCols.ClassifySecondId)
  552. existPars = append(existPars, secondClassify.Id)
  553. }
  554. //if thirdClassify != nil {
  555. // existCond = fmt.Sprintf(`%s AND %s = ?`, existCond, report_approve.ReportApproveFlowCols.ClassifyThirdId)
  556. // existPars = append(existPars, thirdClassify.Id)
  557. //}
  558. parentFlow, err := flowObj.GetItemByCondition(existCond, existPars, "")
  559. if err != nil {
  560. // 如果没有配置审批流,那么就直接返回
  561. if err.Error() == utils.ErrNoRow() {
  562. err = nil
  563. }
  564. return
  565. }
  566. // 获取父级的审批节点
  567. nodeObj := report_approve.ReportApproveNode{}
  568. nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, report_approve.ReportApproveNodeCols.ReportApproveFlowId, report_approve.ReportApproveNodeCols.CurrVersion)
  569. nodePars := make([]interface{}, 0)
  570. nodePars = append(nodePars, parentFlow.ReportApproveFlowId, parentFlow.CurrVersion)
  571. parentNodeList, err := nodeObj.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
  572. if err != nil {
  573. return
  574. }
  575. // 新审批流
  576. currFlow := &report_approve.ReportApproveFlow{
  577. ReportApproveFlowId: 0,
  578. FlowName: currClassifyItem.ClassifyName,
  579. ReportType: parentFlow.ReportType,
  580. ClassifyFirstId: firstClassify.Id,
  581. ClassifySecondId: secondClassify.Id,
  582. //ClassifyThirdId: 0,
  583. CurrVersion: 1,
  584. Enabled: 1,
  585. CreateTime: time.Now().Local(),
  586. ModifyTime: time.Now().Local(),
  587. }
  588. if thirdClassify != nil {
  589. currFlow.ClassifyThirdId = thirdClassify.Id
  590. }
  591. // 新审批流的节点
  592. nodeItems := make([]*report_approve.ReportApproveNode, 0)
  593. for _, v := range parentNodeList {
  594. n := &report_approve.ReportApproveNode{
  595. //ReportApproveNodeId: 0,
  596. //ReportApproveFlowId: 0,
  597. PrevNodeId: 0,
  598. NextNodeId: 0,
  599. NodeType: v.NodeType,
  600. ApproveType: v.ApproveType,
  601. Users: v.Users,
  602. CurrVersion: 1,
  603. CreateTime: time.Now().Local(),
  604. }
  605. nodeItems = append(nodeItems, n)
  606. }
  607. // 新增审批流和节点
  608. err = flowObj.CreateFlowAndNodes(currFlow, nodeItems)
  609. if err != nil {
  610. return
  611. }
  612. parentFlow.Enabled = 0
  613. err = parentFlow.Update([]string{"Enabled"})
  614. return
  615. }
  616. // EditReportClassify
  617. // @Description: 编辑报告分类
  618. // @author: Roc
  619. // @datetime 2024-06-17 13:31:33
  620. // @param classifyId int
  621. // @param classifyName string
  622. // @param chartPermissionIdList []int
  623. // @return err error
  624. // @return errMsg string
  625. // @return isSendEmail bool
  626. func EditReportClassify(classifyId int, classifyName string, chartPermissionIdList []int) (err error, errMsg string, isSendEmail bool) {
  627. isSendEmail = true
  628. errMsg = `修改失败`
  629. item, err := models.GetClassifyById(classifyId)
  630. if err != nil {
  631. errMsg = "获取分类信息失败"
  632. if err.Error() == utils.ErrNoRow() {
  633. errMsg = "分类不存在, 或已被删除"
  634. isSendEmail = false
  635. }
  636. return
  637. }
  638. originName := item.ClassifyName
  639. // 重名校验
  640. existName, e := models.GetClassifyByName(classifyName, item.ParentId)
  641. if e != nil && e.Error() != utils.ErrNoRow() {
  642. errMsg = "获取信息失败"
  643. err = errors.New("获取重名分类失败, Err: " + err.Error())
  644. return
  645. }
  646. if existName != nil && existName.Id != item.Id {
  647. errMsg = "分类名称:" + classifyName + "已存在"
  648. err = errors.New(errMsg)
  649. isSendEmail = false
  650. return
  651. }
  652. item.ClassifyName = classifyName
  653. // ETA1.8.3:不允许修改上级分类 2024-6-17 13:21:01
  654. //item.ParentId = req.ParentId
  655. item.ModifyTime = time.Now().Local()
  656. cols := make([]string, 0)
  657. cols = append(cols, "ClassifyName", "ModifyTime")
  658. err = item.UpdateClassify(cols)
  659. if err != nil {
  660. return
  661. }
  662. err = models.EditChartPermissionSearchKeyWordMappingMulti(item.ClassifyName, chartPermissionIdList, item.Id)
  663. if err != nil {
  664. errMsg = "修改分类权限失败"
  665. return
  666. }
  667. // 修改CRM权限
  668. go func() {
  669. _ = EditClassifyChartPermissionSync(item.ClassifyName, item.Id)
  670. }()
  671. // TODO 修改分类的关联品种时,历史报告中关联的品种怎么处理?
  672. // 更新报告分类名称/父级分类后
  673. go func() {
  674. _ = AfterUpdateClassifyNameOrParent(item.Id, item.ParentId, item.ParentId, originName, item.ClassifyName, item.Level)
  675. }()
  676. return
  677. }
  678. // GetClassifyTreeRecursive 递归获取分类树形结构
  679. func GetClassifyTreeRecursive(list []*models.ClassifyItem, parentId int) []*models.ClassifyItem {
  680. res := make([]*models.ClassifyItem, 0)
  681. for _, v := range list {
  682. if v.ParentId == parentId {
  683. v.Child = GetClassifyTreeRecursive(list, v.Id)
  684. res = append(res, v)
  685. }
  686. }
  687. return res
  688. }
  689. // GetParentClassifyListByParentIdList
  690. // @Description: 递归获取父级分类信息,正常来讲只有三次
  691. // @author: Roc
  692. // @datetime 2024-06-19 13:23:33
  693. // @param parentClassifyIdList []int
  694. // @return list []*models.ClassifyList
  695. // @return err error
  696. func GetParentClassifyListByParentIdList(parentClassifyIdList []int) (list []*models.ClassifyList, err error) {
  697. num := len(parentClassifyIdList)
  698. if num <= 0 {
  699. return
  700. }
  701. list, err = models.GetClassifyListByParentIdList(parentClassifyIdList)
  702. if err != nil {
  703. return
  704. }
  705. // 是否还有上级
  706. {
  707. currParentClassifyIdList := make([]int, 0)
  708. for _, v := range list {
  709. if v.ParentId > 0 {
  710. currParentClassifyIdList = append(currParentClassifyIdList, v.ParentId)
  711. }
  712. }
  713. if len(currParentClassifyIdList) > 0 {
  714. tmpList, tmpErr := GetParentClassifyListByParentIdList(currParentClassifyIdList)
  715. if tmpErr != nil {
  716. err = tmpErr
  717. return
  718. }
  719. list = append(tmpList, list...)
  720. }
  721. }
  722. return
  723. }
  724. // GetClassifyListTreeRecursive
  725. // @Description: 递归获取分类树形结构
  726. // @author: Roc
  727. // @datetime 2024-06-19 13:23:28
  728. // @param list []*models.ClassifyList
  729. // @param parentId int
  730. // @return []*models.ClassifyList
  731. func GetClassifyListTreeRecursive(list []*models.ClassifyList, parentId int) []*models.ClassifyList {
  732. res := make([]*models.ClassifyList, 0)
  733. for _, v := range list {
  734. if v.ParentId == parentId {
  735. v.Child = GetClassifyListTreeRecursive(list, v.Id)
  736. res = append(res, v)
  737. }
  738. }
  739. // 前端的JP需要我这么返回
  740. if len(res) <= 0 {
  741. res = nil
  742. }
  743. return res
  744. }
  745. // BySortAndCreateTime 用来排序,先按Sort字段升序排序,若Sort相同,则按照CreateTime字段升序排序。
  746. type BySortAndCreateTime []*models.ClassifyList
  747. func (a BySortAndCreateTime) Len() int {
  748. return len(a)
  749. }
  750. func (a BySortAndCreateTime) Swap(i, j int) {
  751. a[i], a[j] = a[j], a[i]
  752. }
  753. func (a BySortAndCreateTime) Less(i, j int) bool {
  754. if a[i].Sort == a[j].Sort {
  755. return a[i].CreateTime.Before(a[j].CreateTime)
  756. }
  757. return a[i].Sort < a[j].Sort
  758. }
  759. // SortClassifyListBySortAndCreateTime sorts the ClassifyList slice by Sort and then CreateTime in ascending order.
  760. func SortClassifyListBySortAndCreateTime(classifyList []*models.ClassifyList) {
  761. sort.Sort(BySortAndCreateTime(classifyList))
  762. }