classify.go 28 KB

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