classify.go 29 KB

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