package services import ( "archive/zip" "errors" "eta/eta_api/models" "eta/eta_api/models/report" "eta/eta_api/models/report_approve" "eta/eta_api/models/system" "eta/eta_api/utils" "fmt" "github.com/rdlucklib/rdluck_tools/file" "github.com/rdlucklib/rdluck_tools/http" "html" "os" "path" "strconv" "time" ) // AddReportAndChapter // @Description: 新增报告(包含章节) // @author: Roc // @datetime 2024-06-04 11:23:20 // @param reportInfo *models.Report // @param inheritReportId int // @return err error // @return errMsg string func AddReportAndChapter(reportInfo *models.Report, inheritReportId int, grantAdminIdList []int) (err error, errMsg string) { // 根据审批开关及审批流判断当前报告状态 state, e := CheckReportCurrState(report_approve.FlowReportTypeChinese, reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird, models.ReportOperateAdd) if e != nil { //errMsg = "操作失败" err = errors.New("校验报告当前状态失败, Err: " + e.Error()) return } // 报告状态 reportInfo.State = state // 获取最小分类id minClassifyId := reportInfo.ClassifyIdThird if minClassifyId <= 0 { minClassifyId = reportInfo.ClassifyIdSecond } if minClassifyId <= 0 { minClassifyId = reportInfo.ClassifyIdFirst } if minClassifyId <= 0 { errMsg = "分类异常" err = errors.New(errMsg) return } errMsg = "生成报告失败" // 报告继承 if inheritReportId > 0 { inheritReport, tmpErr := models.GetReportByReportId(inheritReportId) if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() { errMsg = "获取待继承的报告失败" err = tmpErr return } if inheritReport != nil { // 判断当前的报告分类与继承的报告分类是否一致 if inheritReport.ClassifyIdFirst != reportInfo.ClassifyIdFirst || inheritReport.ClassifyIdSecond != reportInfo.ClassifyIdSecond || inheritReport.ClassifyIdThird != reportInfo.ClassifyIdThird { errMsg = "分类异常,与继承的报告分类不一致" err = errors.New(errMsg) return } reportInfo.ChapterType = inheritReport.ChapterType reportInfo.Content = inheritReport.Content reportInfo.ContentSub = inheritReport.ContentSub reportInfo.ContentStruct = inheritReport.ContentStruct reportInfo.CanvasColor = inheritReport.CanvasColor //reportInfo.NeedSplice = inheritReport.NeedSplice reportInfo.NeedSplice = 1 reportInfo.HeadResourceId = inheritReport.HeadResourceId //reportInfo.HeadImg = inheritReport.HeadImg //reportInfo.EndImg = inheritReport.EndImg reportInfo.HeadImg = `` reportInfo.EndImg = `` reportInfo.EndResourceId = inheritReport.EndResourceId if inheritReport.HeadResourceId > 0 { reportInfo.HeadImg = inheritReport.HeadImg } if inheritReport.EndResourceId > 0 { reportInfo.EndImg = inheritReport.EndImg } reportInfo.InheritReportId = inheritReport.Id } } // 获取待生成的报告章节 addChapterList, allGrantUserList, err, errMsg := getAddChapter(reportInfo, minClassifyId, inheritReportId, grantAdminIdList) // 新增报告及章节 var reportId int64 reportId, err = models.AddReportAndChapter(reportInfo, allGrantUserList, addChapterList) if err != nil { err = errors.New("新增报告及章节失败, Err: " + err.Error()) return } reportCode := utils.MD5(strconv.Itoa(reportInfo.Id)) reportInfo.ReportCode = reportCode // 修改唯一编码 { go models.ModifyReportCode(reportId, reportCode) } // 报告权限处理 go handleReportPermission(reportId, minClassifyId) return } // EditReport // @Description: 修改报告的基础信息、授权用户权限 // @author: Roc // @datetime 2024-06-06 17:16:58 // @param reportInfo *models.Report // @param req models.EditReq // @param sysUser *system.Admin // @return err error // @return errMsg string func EditReport(reportInfo *models.Report, req models.EditReq, sysUser *system.Admin) (err error, errMsg string) { errMsg = `保存失败` //var stage int //if reportInfo.ClassifyNameFirst != req.ClassifyNameFirst || reportInfo.ClassifyNameSecond != req.ClassifyNameSecond { // // 报告期数 // maxStage, _ := models.GetReportStageEdit(req.ClassifyIdFirst, req.ClassifyIdSecond, req.ClassifyIdThird, int(req.ReportId)) // maxStage = maxStage + 1 // stage = maxStage //} else { // stage = reportInfo.Stage //} //if req.State != reportInfo.State { // recordItem := &models.ReportStateRecord{ // ReportId: int(req.ReportId), // ReportType: 1, // State: req.State, // AdminId: this.SysUser.AdminId, // AdminName: this.SysUser.AdminName, // CreateTime: time.Now(), // } // go func() { // _, _ = models.AddReportStateRecord(recordItem) // }() //} //item := new(models.Report) //reportInfo.ClassifyIdFirst = req.ClassifyIdFirst //reportInfo.ClassifyNameFirst = req.ClassifyNameFirst //reportInfo.ClassifyIdSecond = req.ClassifyIdSecond //reportInfo.ClassifyNameSecond = req.ClassifyNameSecond //reportInfo.ClassifyIdThird = req.ClassifyIdThird //reportInfo.ClassifyNameThird = req.ClassifyNameThird reportInfo.Title = req.Title reportInfo.Abstract = req.Abstract reportInfo.Author = req.Author reportInfo.Frequency = req.Frequency //reportInfo.State = reportInfo.State // 编辑不变更状态 //reportInfo.Stage = stage // 编辑不变更期数 //reportInfo.Content = html.EscapeString(req.Content) // 编辑不变更具体内容 //reportInfo.ContentSub = html.EscapeString(contentSub) // 编辑不变更具体内容 reportInfo.CreateTime = req.CreateTime //reportInfo.CollaborateType = req.CollaborateType //reportInfo.ReportLayout = req.ReportLayout if req.IsPublicPublish <= 0 { req.IsPublicPublish = 1 } reportInfo.IsPublicPublish = req.IsPublicPublish reportInfo.LastModifyAdminId = sysUser.AdminId reportInfo.LastModifyAdminName = sysUser.RealName reportInfo.ModifyTime = time.Now() state, e := CheckReportCurrState(report_approve.FlowReportTypeChinese, reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird, models.ReportOperateEdit) if e != nil { //errMsg = "操作失败" err = errors.New("校验报告当前状态失败, Err: " + e.Error()) return } // 报告状态 reportInfo.State = state //updateCols := []string{"ClassifyIdFirst", "ClassifyNameFirst", "ClassifyIdSecond", "ClassifyNameSecond", "ClassifyIdThird", "ClassifyNameThird", "Title", "Abstract", "Author", "Frequency", "Stage", "CreateTime", "IsPublicPublish", "LastModifyAdminId", "LastModifyAdminName", "ModifyTime"} updateCols := []string{"Title", "Abstract", "Author", "Frequency", "CreateTime", "IsPublicPublish", "LastModifyAdminId", "LastModifyAdminName", "ModifyTime", "State"} if req.HeadResourceId > 0 { reportInfo.HeadResourceId = req.HeadResourceId updateCols = append(updateCols, "HeadResourceId") } if req.EndResourceId > 0 { reportInfo.EndResourceId = req.EndResourceId updateCols = append(updateCols, "EndResourceId") } // 需要添加的报告授权数据 addReportAdminList := make([]*report.ReportGrant, 0) // 待移除的报告授权数据id delReportGrantIdList := make([]int, 0) // 处理当前报告需要新增/移除的授权信息 { reportGrantObj := report.ReportGrant{} // 获取当前报告已经授权的用户信息 reportGrantList, tmpErr := reportGrantObj.GetGrantListById(reportInfo.Id) if tmpErr != nil { err = tmpErr return } // 当前报告已经授权的用户信息 currReportAdminMap := make(map[int]*report.ReportGrant) // 需要删除的报告授权数据 delReportAdminMap := make(map[int]*report.ReportGrant) for _, v := range reportGrantList { currReportAdminMap[v.AdminId] = v delReportAdminMap[v.AdminId] = v } // 先看需要新增哪些用户 for _, tmpAdminId := range req.GrantAdminIdList { _, ok := currReportAdminMap[tmpAdminId] // 如果章节中需要新增的用户 已经在 报告授权用户里面,那么就忽略,可以不用新增了 if ok { delete(delReportAdminMap, tmpAdminId) continue } // 如果不存在,那么就新增授权 addReportAdminList = append(addReportAdminList, &report.ReportGrant{ //GrantId: 0, ReportId: reportInfo.Id, AdminId: tmpAdminId, CreateTime: time.Now(), }) } // 查出需要移除的授权id for _, v := range delReportAdminMap { delReportGrantIdList = append(delReportGrantIdList, v.GrantId) } } // 修改报告的基本信息,以及报告的授权用户 err = models.EditReportAndPermission(reportInfo, updateCols, addReportAdminList, delReportGrantIdList) if err != nil { return } // 报告权限处理 { minClassifyId, _, tmpErr := getMinClassify(reportInfo) if tmpErr != nil { return } go handleReportPermission(int64(reportInfo.Id), minClassifyId) } return } // getAddChapter // @Description: 获取待新增的报告章节列表 // @author: Roc // @datetime 2024-06-04 13:10:58 // @param reportInfo *models.Report // @param minClassifyId int // @param inheritReportId int // @param grantAdminIdList []int // @return chapterList []*models.ReportChapter // @return err error // @return errMsg string func getAddChapter(reportInfo *models.Report, minClassifyId, inheritReportId int, grantAdminIdList []int) (chapterList []models.AddReportChapter, allGrantUserList []*report.ReportGrant, err error, errMsg string) { // 待生成的报告章节内容 chapterList = make([]models.AddReportChapter, 0) // 所有的授权用户 allGrantUserList = make([]*report.ReportGrant, 0) // 报告授权的用户ID needAdminIdMap := make(map[int]bool) for _, adminId := range grantAdminIdList { needAdminIdMap[adminId] = true allGrantUserList = append(allGrantUserList, &report.ReportGrant{ //GrantId: 0, //ReportId: 0, AdminId: adminId, CreateTime: time.Now(), }) } if reportInfo.HasChapter != 1 { return } // 最小单元的分类 var minClassifyName string if reportInfo.ClassifyIdThird == minClassifyId { minClassifyName = reportInfo.ClassifyNameThird } else if reportInfo.ClassifyIdSecond == minClassifyId { minClassifyName = reportInfo.ClassifyNameSecond } else { minClassifyName = reportInfo.ClassifyNameFirst } errMsg = "生成报告章节失败" // 章节类型列表 allTypeList, err := models.GetReportChapterTypeListByClassifyId(minClassifyId) if err != nil { err = errors.New(errMsg) return } // 待添加的章节 chapterTypeList := make([]*models.ReportChapterType, 0) // 待添加的章节类型id列表 chapterTypeIdList := make([]int, 0) nowTime := time.Now().Local() for _, chapterType := range allTypeList { // 如果被永久暂停更新了 if chapterType.Enabled == 0 { //该章节已被永久禁用,那么就不允许继承或者新增该章节 continue } if chapterType.PauseStartTime != "" && chapterType.PauseEndTime != "" && chapterType.PauseStartTime != utils.EmptyDateStr && chapterType.PauseEndTime != utils.EmptyDateStr { startTime, timeErr := time.ParseInLocation(utils.FormatDate, chapterType.PauseStartTime, time.Local) if timeErr != nil { utils.FileLog.Error("更新规则时间转换失败4001, Err: " + timeErr.Error()) continue } endTime, timeErr := time.ParseInLocation(utils.FormatDate, chapterType.PauseEndTime, time.Local) if timeErr != nil { utils.FileLog.Error("更新规则时间转换失败4002, Err: " + timeErr.Error()) continue } // 暂停更新 if nowTime.After(startTime) && nowTime.Before(endTime.AddDate(0, 0, 1)) { continue } } // 正常的章节类型状态,那么应该自动创建该章节 chapterTypeList = append(chapterTypeList, chapterType) chapterTypeIdList = append(chapterTypeIdList, chapterType.ReportChapterTypeId) } // 待继承的章节类id的授权用户 oldChapterIdGrantListMap := make(map[int][]*report.ReportChapterGrant) // 待继承的章节类id关联的品种列表 oldChapterPermissionListMap := make(map[int][]*report.ReportChapterPermissionMapping) // 自定义章节列表 customAddChapterList := make([]models.AddReportChapter, 0) // 报告继承 inheritChapterMap := make(map[int]*models.ReportChapter) // 当前分类下配置的章节类型id所关联的品种列表(默认配置,不是从继承报告里面获取的,如果有继承章节,那么需要从继承报告里面获取) currChapterTypePermissionListMap := make(map[int][]*report.ReportChapterPermissionMapping) if len(chapterTypeIdList) > 0 { mappingList, e := models.GetChapterTypePermissionByChapterTypeIdList(chapterTypeIdList) if e != nil { err = fmt.Errorf("获取章节类型权限列表失败, Err: " + e.Error()) return } hasPermissionMap := make(map[string]bool) for _, v := range mappingList { tmpChapterTypePermissionList, ok := currChapterTypePermissionListMap[v.ReportChapterTypeId] if !ok { tmpChapterTypePermissionList = make([]*report.ReportChapterPermissionMapping, 0) } key := fmt.Sprint(v.ReportChapterTypeId, "-", v.ChartPermissionId) if _, has := hasPermissionMap[key]; !has { hasPermissionMap[key] = true currChapterTypePermissionListMap[v.ReportChapterTypeId] = append(tmpChapterTypePermissionList, &report.ReportChapterPermissionMapping{ ReportChapterPermissionMappingId: 0, ReportChapterId: 0, ChartPermissionId: v.ChartPermissionId, CreateTime: time.Now(), }) } } } if inheritReportId > 0 { // 继承待继承的报告章节内容 inheritReportChapters, tmpErr := models.GetChapterListByReportId(inheritReportId) if tmpErr != nil { errMsg = "获取待继承的报告章节失败" err = tmpErr return } reportChaptersIdList := make([]int, 0) for _, v := range inheritReportChapters { reportChaptersIdList = append(reportChaptersIdList, v.ReportChapterId) } // 继承的报告章节用户map grantListMap := make(map[int][]*report.ReportChapterGrant) // 继承的报告章节的关联品种map chapterPermissionListMap := make(map[int][]*report.ReportChapterPermissionMapping) // 授权数据列表 if len(reportChaptersIdList) > 0 { // 授权用户数据 obj := report.ReportChapterGrant{} grantList, tmpErr := obj.GetGrantListByIdList(reportChaptersIdList) if tmpErr != nil { errMsg = "获取待继承的报告章节的授权用户列表失败" err = tmpErr return } for _, v := range grantList { // 如果不在报告授权的用户ID里面,那么该章节就不继承该授权用户 if _, ok := needAdminIdMap[v.AdminId]; !ok { continue } currReportChapterId := v.ReportChapterId tmpGrantList, ok := grantListMap[currReportChapterId] if !ok { tmpGrantList = make([]*report.ReportChapterGrant, 0) } v.ReportChapterId = 0 v.GrantId = 0 tmpGrantList = append(tmpGrantList, v) grantListMap[currReportChapterId] = tmpGrantList } // 授权关联品种数据 permissionObj := report.ReportChapterPermissionMapping{} permissionList, tmpErr := permissionObj.GetPermissionListByIdList(reportChaptersIdList) if tmpErr != nil { errMsg = "获取待继承的报告章节的授权用户列表失败" err = tmpErr return } for _, v := range permissionList { currReportChapterId := v.ReportChapterId tmpPermissionList, ok := chapterPermissionListMap[currReportChapterId] if !ok { tmpPermissionList = make([]*report.ReportChapterPermissionMapping, 0) } v.ReportChapterId = 0 v.ReportChapterPermissionMappingId = 0 tmpPermissionList = append(tmpPermissionList, v) chapterPermissionListMap[currReportChapterId] = tmpPermissionList } } // 继承的报告章节内容 for i := 0; i < len(inheritReportChapters); i++ { customChapter := inheritReportChapters[i] // 授权用户列表 tmpGrantList, ok := grantListMap[customChapter.ReportChapterId] if !ok { tmpGrantList = make([]*report.ReportChapterGrant, 0) } oldChapterIdGrantListMap[customChapter.ReportChapterId] = tmpGrantList // 关联品种列表 chapterPermissionList, ok := chapterPermissionListMap[customChapter.ReportChapterId] if !ok { chapterPermissionList = make([]*report.ReportChapterPermissionMapping, 0) } oldChapterPermissionListMap[customChapter.ReportChapterId] = chapterPermissionList // 判断该章节是否是系统章节,如果是的话,那就是需要额外创建的 if customChapter.TypeId > 0 { inheritChapterMap[customChapter.TypeId] = customChapter continue } // 自定义的报告内容 customChapter.ReportId = reportInfo.Id customChapter.ReportChapterId = 0 customChapter.ClassifyIdFirst = minClassifyId customChapter.ClassifyNameFirst = minClassifyName customChapter.Stage = reportInfo.Stage customChapter.PublishState = 1 customChapter.CreateTime = reportInfo.CreateTime customChapter.ModifyTime = time.Now() customChapter.LastModifyAdminId = reportInfo.LastModifyAdminId customChapter.LastModifyAdminName = reportInfo.LastModifyAdminName customChapter.ContentModifyTime = time.Now() customAddChapter := models.AddReportChapter{ ReportChapter: customChapter, GrantList: tmpGrantList, GrantPermissionList: chapterPermissionList, } customAddChapterList = append(customAddChapterList, customAddChapter) } } // 最大排序 var maxSort int for _, typeItem := range chapterTypeList { v, ok := inheritChapterMap[typeItem.ReportChapterTypeId] // 章节授权用户 var tmpGrantList []*report.ReportChapterGrant // 章节关联品种 var tmpChapterPermissionList []*report.ReportChapterPermissionMapping chapterItem := new(models.ReportChapter) if ok && v != nil { // 如果存在继承的章节,那么就从继承的章节内容中获取 chapterItem.AddType = 2 chapterItem.Title = v.Title chapterItem.ReportType = v.ReportType chapterItem.ClassifyIdFirst = minClassifyId chapterItem.ClassifyNameFirst = minClassifyName chapterItem.TypeId = typeItem.ReportChapterTypeId chapterItem.TypeName = typeItem.ReportChapterTypeName chapterItem.Content = v.Content chapterItem.ContentSub = v.ContentSub chapterItem.Stage = reportInfo.Stage chapterItem.PublishState = 1 chapterItem.Sort = typeItem.Sort chapterItem.CreateTime = reportInfo.CreateTime chapterItem.ModifyTime = time.Now() chapterItem.LastModifyAdminId = reportInfo.LastModifyAdminId chapterItem.LastModifyAdminName = reportInfo.LastModifyAdminName chapterItem.ContentModifyTime = time.Now() chapterItem.ContentStruct = v.ContentStruct chapterItem.ReportLayout = v.ReportLayout chapterItem.ReportCreateTime = time.Now() // 继承历史章节中的授权用户列表 tmpGrantList, ok = oldChapterIdGrantListMap[v.ReportChapterId] if !ok { tmpGrantList = make([]*report.ReportChapterGrant, 0) } // 继承历史章节中的关联品种列表 tmpChapterPermissionList, ok = oldChapterPermissionListMap[v.ReportChapterId] if !ok { tmpChapterPermissionList = make([]*report.ReportChapterPermissionMapping, 0) } } else { chapterItem.AddType = 1 chapterItem.Title = typeItem.ReportChapterTypeName chapterItem.ReportType = typeItem.ResearchType chapterItem.ClassifyIdFirst = minClassifyId chapterItem.ClassifyNameFirst = minClassifyName chapterItem.TypeId = typeItem.ReportChapterTypeId chapterItem.TypeName = typeItem.ReportChapterTypeName chapterItem.Stage = reportInfo.Stage chapterItem.PublishState = 1 chapterItem.Sort = typeItem.Sort chapterItem.CreateTime = reportInfo.CreateTime chapterItem.ModifyTime = time.Now() chapterItem.LastModifyAdminId = reportInfo.LastModifyAdminId chapterItem.LastModifyAdminName = reportInfo.LastModifyAdminName chapterItem.ContentModifyTime = time.Now() //chapterItem.ContentStruct = v.ContentStruct chapterItem.ReportLayout = reportInfo.ReportLayout chapterItem.ReportCreateTime = time.Now() // 默认配置:从当前分类下配置的章节类型id所关联的品种列表 tmpChapterPermissionList, ok = currChapterTypePermissionListMap[typeItem.ReportChapterTypeId] if !ok { tmpChapterPermissionList = make([]*report.ReportChapterPermissionMapping, 0) } } if typeItem.Sort > maxSort { maxSort = typeItem.Sort } addChapter := models.AddReportChapter{ ReportChapter: chapterItem, GrantList: tmpGrantList, GrantPermissionList: tmpChapterPermissionList, } chapterList = append(chapterList, addChapter) } // 将自定义的章节内容添加到待生成的章节内容中 for _, addChapterItem := range customAddChapterList { maxSort++ addChapterItem.ReportChapter.Sort = maxSort chapterList = append(chapterList, addChapterItem) } //hasGrantUserMap := make(map[int]bool) //for _, grantList := range typeGrantListMap { // for _, grant := range grantList { // if _, ok := hasGrantUserMap[grant.AdminId]; !ok { // allGrantUserList = append(allGrantUserList, &report.ReportGrant{ // //GrantId: 0, // //ReportId: 0, // AdminId: grant.AdminId, // CreateTime: time.Now(), // }) // } // } //} return } // AddChapterBaseInfoAndPermission // @Description: 添加章节基本信息及权限 // @author: Roc // @datetime 2024-06-11 15:35:23 // @param reportInfo *models.Report // @param reportChapterInfo *models.ReportChapter // @param permissionIdList []int // @param adminIdList []int // @return err error // @return errMsg string func AddChapterBaseInfoAndPermission(reportInfo *models.Report, reportChapterInfo *models.ReportChapter, permissionIdList []int, adminIdList []int) (err error, errMsg string) { errMsg = "新增失败" if reportInfo.State == 2 { errMsg = "该报告已发布,不允许编辑" err = errors.New(errMsg) return } // 需要添加的报告章节授权数据 addChapterAdminList := make([]*report.ReportChapterGrant, 0) for _, adminId := range adminIdList { //新增授权 addChapterAdminList = append(addChapterAdminList, &report.ReportChapterGrant{ //GrantId: 0, //ReportChapterId: reportChapterInfo.ReportChapterId, AdminId: adminId, CreateTime: time.Now(), }) } // 需要添加的报告章节品种权限数据 addChapterPermissionList := make([]*report.ReportChapterPermissionMapping, 0) // 品种权限 for _, permissionId := range permissionIdList { // 如果不存在,那么就新增品种权限配置 addChapterPermissionList = append(addChapterPermissionList, &report.ReportChapterPermissionMapping{ //ReportChapterPermissionMappingId: 0, //ReportChapterId: reportChapterInfo.ReportChapterId, ChartPermissionId: permissionId, CreateTime: time.Now(), }) } err = models.AddChapterBaseInfoAndPermission(reportChapterInfo, addChapterAdminList, addChapterPermissionList) return } // EditChapterBaseInfoAndPermission // @Description: 修改报告章节的基础信息、授权用户权限、品种权限 // @author: Roc // @datetime 2024-06-05 11:49:11 // @param reportInfo *models.Report // @param reportChapterInfo *models.ReportChapter // @param title string // @param permissionIdList []int // @param adminIdList []int // @return err error // @return errMsg string func EditChapterBaseInfoAndPermission(reportInfo *models.Report, reportChapterInfo *models.ReportChapter, title string, permissionIdList []int, adminIdList []int) (err error, errMsg string) { errMsg = "修改失败" if reportInfo.State == 2 { errMsg = "该报告已发布,不允许编辑" err = errors.New(errMsg) return } updateCols := make([]string, 0) // 如果标题内容,那么就修改 if title != `` { reportChapterInfo.Title = title reportChapterInfo.ModifyTime = time.Now() updateCols = append(updateCols, "Title", "ModifyTime") reportChapterInfo.UpdateChapter(updateCols) } reportGrantObj := report.ReportGrant{} chapterGrantObj := report.ReportChapterGrant{} chapterPermissionObj := report.ReportChapterPermissionMapping{} // 报告授权的用户map reportGrantAdminIdMap := make(map[int]bool) // 获取报告授权的用户信息 { // 获取当前报告已经授权的用户信息 reportGrantList, tmpErr := reportGrantObj.GetGrantListById(reportInfo.Id) if tmpErr != nil { err = tmpErr return } for _, v := range reportGrantList { reportGrantAdminIdMap[v.AdminId] = true } } // 需要添加的报告章节授权数据 addChapterAdminList := make([]*report.ReportChapterGrant, 0) // 待移除的报告章节授权数据id delReportChapterGrantIdList := make([]int, 0) // 处理当前报告章节需要新增/移除的授权信息 { // 获取当前章节已经授权的用户信息 chapterGrantList, tmpErr := chapterGrantObj.GetGrantListById(reportChapterInfo.ReportChapterId) if tmpErr != nil { err = tmpErr return } // 当前章节已经授权的用户信息 currChapterAdminMap := make(map[int]*report.ReportChapterGrant) // 需要删除的报告章节授权数据 delChapterAdminMap := make(map[int]*report.ReportChapterGrant) for _, v := range chapterGrantList { currChapterAdminMap[v.AdminId] = v delChapterAdminMap[v.AdminId] = v } for _, adminId := range adminIdList { // 如果该用户 不在 报告授权的用户map 里面,说明这个用户是要移除的 if _, ok := reportGrantAdminIdMap[adminId]; !ok { continue } _, ok := currChapterAdminMap[adminId] // 如果存在,那么从 “需要删除的报告章节授权数据” 的map中移除 if ok { delete(delChapterAdminMap, adminId) continue } // 如果不存在,那么就新增授权 addChapterAdminList = append(addChapterAdminList, &report.ReportChapterGrant{ //GrantId: 0, ReportChapterId: reportChapterInfo.ReportChapterId, AdminId: adminId, CreateTime: time.Now(), }) } // 查出需要移除的授权id for _, v := range delChapterAdminMap { delReportChapterGrantIdList = append(delReportChapterGrantIdList, v.GrantId) } } // 其他章节授权的用户 otherChapterAdminMap := make(map[int]bool) { // 获取报告所有的章节id reportChapterIdList, tmpErr := models.GetReportChapterIdList(reportInfo.Id) if tmpErr != nil { err = tmpErr return } if len(reportChapterIdList) > 0 { list, tmpErr := chapterGrantObj.GetGrantListByIdList(reportChapterIdList) if tmpErr != nil { err = tmpErr return } for _, v := range list { // 如果是当前章节,因为涉及到重新授权,所以得过滤 if v.ReportChapterId == reportChapterInfo.ReportChapterId { continue } otherChapterAdminMap[v.AdminId] = true } } } // 需要添加的报告章节品种权限数据 addChapterPermissionList := make([]*report.ReportChapterPermissionMapping, 0) // 待移除的报告章节品种权限数据id delChapterPermissionMappingIdList := make([]int, 0) // 处理当前报告章节需要新增/移除的品种权限信息 { // 获取当前章节已经配置的品种权限信息 chapterPermissionList, tmpErr := chapterPermissionObj.GetPermissionListById(reportChapterInfo.ReportChapterId) if tmpErr != nil { err = tmpErr return } // 当前章节已经配置的品种权限信息 currChapterPermissionMap := make(map[int]*report.ReportChapterPermissionMapping) // 需要删除的报告章节品种权限配置 delChapterPermissionMap := make(map[int]*report.ReportChapterPermissionMapping) for _, v := range chapterPermissionList { currChapterPermissionMap[v.ChartPermissionId] = v delChapterPermissionMap[v.ChartPermissionId] = v } for _, permissionId := range permissionIdList { _, ok := currChapterPermissionMap[permissionId] // 如果存在,那么从 “需要删除的报告章节品种权限配置” 的map中移除 if ok { delete(delChapterPermissionMap, permissionId) continue } // 如果不存在,那么就新增品种权限配置 addChapterPermissionList = append(addChapterPermissionList, &report.ReportChapterPermissionMapping{ //ReportChapterPermissionMappingId: 0, ReportChapterId: reportChapterInfo.ReportChapterId, ChartPermissionId: permissionId, CreateTime: time.Now(), }) } // 查出需要移除的品种权限配置 for _, v := range delChapterPermissionMap { delChapterPermissionMappingIdList = append(delChapterPermissionMappingIdList, v.ReportChapterPermissionMappingId) } } err = models.EditChapterBaseInfoAndPermission(reportInfo, reportChapterInfo, updateCols, addChapterAdminList, addChapterPermissionList, delReportChapterGrantIdList, delChapterPermissionMappingIdList) return } // DelChapter // @Description: 删除报告章节、授权用户权限、品种权限 // @author: Roc // @datetime 2024-06-06 17:28:37 // @param reportInfo *models.Report // @param reportChapterInfo *models.ReportChapter // @param sysUser *system.Admin // @return err error // @return errMsg string func DelChapter(reportInfo *models.Report, reportChapterInfo *models.ReportChapter, sysUser *system.Admin) (err error, errMsg string) { errMsg = "删除失败" if reportInfo.State == 2 { errMsg = "该报告已发布,不允许删除" err = errors.New(errMsg) return } reportInfo.LastModifyAdminId = sysUser.AdminId reportInfo.LastModifyAdminName = sysUser.RealName reportInfo.ModifyTime = time.Now() updateReportCols := []string{"LastModifyAdminId", "LastModifyAdminName", "ModifyTime"} err = models.DelChapterAndPermission(reportInfo, updateReportCols, reportChapterInfo) return } // DownloadVoice // @Description: 下载报告音频文件 // @author: Roc // @datetime 2024-06-13 15:36:46 // @param reportInfo *models.ReportDetail // @return savePath string // @return fileName string // @return err error // @return errMsg string func DownloadVoice(reportInfo *models.ReportDetail) (savePath, fileName string, err error, errMsg string) { errMsg = `下载失败` // 如果报告有音频,那么下载音频 if reportInfo.VideoUrl != `` { savePath = time.Now().Format(utils.FormatDateTimeUnSpace) + utils.GetRandString(5) + ".mp3" fileName = reportInfo.VideoName + ".mp3" fileBody, tmpErr := http.Get(reportInfo.VideoUrl) if tmpErr != nil { err = tmpErr errMsg = "音频下载失败" return } err = file.SaveFile(fileBody, savePath) if err != nil { errMsg = "音频保存失败" return } } // 如果是章节报告,那么就下载压缩包 if reportInfo.HasChapter == 1 { videoList, tmpErr := models.GetReportChapterVideoList(reportInfo.Id) if tmpErr != nil { err = tmpErr errMsg = "获取音频列表失败" return } if len(videoList) > 0 { // 创建zip savePath = time.Now().Format(utils.FormatDateTimeUnSpace) + utils.GetRandString(5) + ".zip" fileName = reportInfo.VideoName + ".zip" zipFile, tmpErr := os.Create(savePath) if tmpErr != nil { err = tmpErr return } zipWriter := zip.NewWriter(zipFile) // 生成zip过程中报错关闭 defer func() { if err != nil { zipWriter.Close() zipFile.Close() } }() // 获取音频,写入zip for i := 0; i < len(videoList); i++ { item := videoList[i] if item.VideoName == "" || item.VideoUrl == "" { continue } // 音频文件后缀 ext := path.Ext(item.VideoUrl) ioWriter, tmpErr := zipWriter.Create(fmt.Sprintf("%s%s", item.VideoName, ext)) if tmpErr != nil { err = tmpErr if os.IsPermission(err) { fmt.Println("权限不足: ", err) return } return } var content []byte content, err = http.Get(item.VideoUrl) if err != nil { content = []byte("") } ioWriter.Write(content) } // 生成zip后关闭,否则下载文件会损坏 zipWriter.Close() zipFile.Close() } } return } // CheckReportAuthByAdminIdList // @Description: 根据管理员id列表,判断当前用户是否有报告权限 // @author: Roc // @datetime 2024-06-13 11:03:10 // @param adminId int // @param createAdminId int // @param grantAdminIdList []int // @return isAuth bool func CheckReportAuthByAdminIdList(adminId, createAdminId int, grantAdminIdList []int) (isAuth bool) { // 如果是自己创建的报告,那么就有权限 if adminId == createAdminId { isAuth = true return } // 如果是授权用户,那么就有权限 if utils.IsCheckInList(grantAdminIdList, adminId) { isAuth = true return } return } // CheckReportAuthByReportChapterInfo // @Description: 根据报告ID,判断当前用户是否有报告权限 // @author: Roc // @datetime 2024-06-13 16:21:28 // @param adminId int // @param reportInfoId int // @return isAuth bool // @return err error func CheckReportAuthByReportChapterInfo(adminId, createAdminId int, reportInfoId int) (isAuth bool, err error) { // 如果是自己创建的报告,那么就有权限 if adminId == createAdminId { isAuth = true return } obj := report.ReportGrant{} chapterGrantList, err := obj.GetGrantListById(reportInfoId) if err != nil { return } for _, v := range chapterGrantList { if v.AdminId == adminId { isAuth = true return } } return } // EditReportLayoutImg // @Description: 修改报告的版图信息 // @author: Roc // @datetime 2024-06-18 11:35:00 // @param reportInfo *models.Report // @param req models.EditLayoutImgReq // @param sysUser *system.Admin // @return err error // @return errMsg string func EditReportLayoutImg(reportInfo *models.Report, req models.EditLayoutImgReq, sysUser *system.Admin) (err error, errMsg string) { errMsg = `保存失败` reportInfo.HeadResourceId = req.HeadResourceId reportInfo.HeadImg = req.HeadImg reportInfo.EndResourceId = req.EndResourceId reportInfo.EndImg = req.EndImg reportInfo.CanvasColor = req.CanvasColor reportInfo.LastModifyAdminId = sysUser.AdminId reportInfo.LastModifyAdminName = sysUser.RealName reportInfo.ModifyTime = time.Now() updateCols := []string{"HeadResourceId", "HeadImg", "EndResourceId", "EndImg", "CanvasColor", "LastModifyAdminId", "LastModifyAdminName", "ModifyTime"} err = reportInfo.UpdateReport(updateCols) if err != nil { return } return } // PublishReport // @Description: 报告发布 // @author: Roc // @datetime 2024-06-20 09:44:13 // @param reportId int // @param reportUrl string // @param sysUser *system.Admin // @return tips string // @return err error // @return errMsg string func PublishReport(reportId int, reportUrl string, sysUser *system.Admin) (tips string, err error, errMsg string) { errMsg = `报告发布失败` reportInfo, err := models.GetReportByReportId(reportId) if err != nil { errMsg = "获取报告信息失败" return } if reportInfo == nil { errMsg = "获取报告信息失败" err = errors.New(errMsg) return } var publishTime time.Time if reportInfo.MsgIsSend == 1 && reportInfo.PublishTime.IsZero() { //如果报告曾经发布过,并且已经发送过模版消息,则章节的发布时间为报告的发布时间 publishTime = reportInfo.PublishTime } else { publishTime = time.Now() } var tmpErr error // 章节类型的报告(原来的晨周报) if reportInfo.HasChapter == 1 { tips, tmpErr, errMsg = PublishChapterReport(reportInfo, reportUrl, sysUser) if tmpErr != nil { err = errors.New("晨周报发布失败, Err:" + tmpErr.Error() + ", report_id:" + strconv.Itoa(reportId)) } return } // 普通报告 if reportInfo.Content == "" { errMsg = `报告内容为空,不可发布` err = errors.New("报告内容为空,不需要生成,report_id:" + strconv.Itoa(reportId)) return } // 根据审批开关及审批流判断当前报告状态 state, e := CheckReportCurrState(report_approve.FlowReportTypeChinese, reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird, models.ReportOperatePublish) if e != nil { errMsg = "操作失败" err = errors.New("校验报告当前状态失败, Err: " + e.Error()) return } if state == models.ReportStatePublished { // 发布报告 if tmpErr = models.PublishReportById(reportId, publishTime, sysUser.AdminId, sysUser.RealName); tmpErr != nil { err = errors.New("报告发布失败, Err:" + tmpErr.Error() + ", report_id:" + strconv.Itoa(reportId)) return } go func() { // 生成音频 if reportInfo.VideoUrl == "" { go UpdateReportVideo(reportInfo) } // 更新报告Es _ = UpdateReportEs(reportId, 2) }() } else { // 从无审批切换为有审批, 状态重置 if e = models.ResetReportById(reportId, state, sysUser.AdminId, sysUser.RealName); e != nil { errMsg = "操作失败" err = fmt.Errorf("重置报告状态失败, Err: %s, ReportId: %d", e.Error(), reportId) return } } recordItem := &models.ReportStateRecord{ ReportId: reportId, ReportType: 1, State: state, AdminId: sysUser.AdminId, AdminName: sysUser.AdminName, CreateTime: time.Now(), } go func() { _, _ = models.AddReportStateRecord(recordItem) }() // 生成报告pdf和长图 { reportPdfUrl := GetGeneralPdfUrl(reportInfo.ReportCode, reportInfo.ClassifyNameFirst, reportInfo.ReportLayout) go Report2pdfAndJpeg(reportPdfUrl, reportId, 1) } // 报告权限处理 { minClassifyId, _, tmpErr := getMinClassify(reportInfo) if tmpErr != nil { return } go handleReportPermission(int64(reportInfo.Id), minClassifyId) } return } // PublishChapterReport // @Description: 发布章节类型的报告 // @author: Roc // @datetime 2024-06-28 10:38:50 // @param reportInfo *models.Report // @param reportUrl string // @return tips string // @return err error // @return errMsg string func PublishChapterReport(reportInfo *models.Report, reportUrl string, sysUser *system.Admin) (tips string, err error, errMsg string) { reportId := reportInfo.Id if reportInfo.State == 2 { return } // 获取所有章节列表 chapters, err := models.GetChapterListByReportId(reportId) if err != nil { return } chapterLen := len(chapters) if chapterLen <= 0 { tips = "报告章节为空,不可发布" errMsg = tips err = errors.New(tips) return } // 获取报告中的所有章节列表 chapterList, err := models.GetChapterListByReportId(reportId) if err != nil { return } for _, chapter := range chapterList { if chapter.PublishState == 1 { tips = "还存在未发布的章节" errMsg = tips err = errors.New(tips) return } } // 根据审批开关及审批流判断当前报告状态 state, e := CheckReportCurrState(report_approve.FlowReportTypeChinese, reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird, models.ReportOperatePublish) if e != nil { //errMsg = "操作失败" err = errors.New("校验报告当前状态失败, Err: " + e.Error()) return } // 如果状态不是已发布,那么就重置状态 if state != models.ReportStatePublished { // 从无审批切换为有审批, 状态重置 if e = models.ResetReportById(reportId, state, sysUser.AdminId, sysUser.RealName); e != nil { //errMsg = "操作失败" err = fmt.Errorf("重置报告状态失败, Err: %s, ReportId: %d", e.Error(), reportId) return } return } // 需发布整期 updateCols := make([]string, 0) reportInfo.LastModifyAdminId = sysUser.AdminId reportInfo.LastModifyAdminName = sysUser.RealName updateCols = append(updateCols, "LastModifyAdminId", "LastModifyAdminName", "Title", "State", "ModifyTime") // 发布后标题调整 //title := reportInfo.Title //title = strings.ReplaceAll(title, "【弘则FICC晨报】", "") //title = strings.ReplaceAll(title, "【弘则FICC周报】", "") //if title == "" { // // 取第一个需发布章节的标题 // firstId := publishIdArr[0] // firstTitle := "" // for i := 0; i < chapterLen; i++ { // if chapters[i].ReportChapterId == firstId { // firstTitle = chapters[i].Title // break // } // } // title = firstTitle //} //report.Title = title reportInfo.State = state // 研报后台4.4 只在没有发布过时更新发布时间,其余均按模版消息发送时间当作发布时间 if reportInfo.MsgIsSend == 0 || reportInfo.PublishTime.IsZero() { reportInfo.PublishTime = time.Now().Local() updateCols = append(updateCols, "PublishTime") } reportInfo.ModifyTime = time.Now().Local() if e := models.PublishReportAndChapter(reportInfo, true, updateCols); e != nil { err = errors.New("发布报告及章节失败") return } // 生成章节音频 go UpdateReportVideo(reportInfo) // 更新报告ES go func() { _ = UpdateReportEs(reportInfo.Id, 2) }() // 发布时备份内容 go SaveReportLogs(reportInfo, chapters, reportInfo.AdminId, reportInfo.AdminRealName) // 生成报告pdf和长图 { reportPdfUrl := GetGeneralPdfUrl(reportInfo.ReportCode, reportInfo.ClassifyNameFirst, reportInfo.ReportLayout) go Report2pdfAndJpeg(reportPdfUrl, reportId, 1) } return } // DeleteReportAndChapter 删除报告及章节 func DeleteReportAndChapter(reportId int) (err error) { reportInfo, err := models.GetReportByReportId(reportId) if err != nil { err = errors.New("报告信息有误, Err: " + err.Error()) return } if reportInfo.State == 2 { err = errors.New("报告已发布,不可删除") return } // 更新ES _ = UpdateReportEs(reportId, 1) // 删除 if reportInfo.HasChapter == 1 { err = models.DeleteDayWeekReportAndChapter(reportId) } else { err = models.DeleteReport(reportId) } if err != nil { err = errors.New("删除失败, Err: " + err.Error()) return } // 重置PPT关联报告 go func() { _ = ResetPPTReport(reportId, false) }() return } // getMinClassify // @Description: 获取最小分类ID // @author: Roc // @datetime 2024-06-20 09:23:19 // @param reportInfo *models.Report // @return minClassifyId int // @return minClassifyName string // @return err error func getMinClassify(reportInfo *models.Report) (minClassifyId int, minClassifyName string, err error) { defer func() { if err != nil { utils.FileLog.Error("获取最小分类ID失败,报告ID:%d,Err:%s", reportInfo.Id, err.Error()) } }() minClassifyId = reportInfo.ClassifyIdThird minClassifyName = reportInfo.ClassifyNameThird if minClassifyId <= 0 { minClassifyId = reportInfo.ClassifyIdSecond minClassifyName = reportInfo.ClassifyNameSecond } if minClassifyId <= 0 { minClassifyId = reportInfo.ClassifyIdFirst minClassifyName = reportInfo.ClassifyNameFirst } if minClassifyId <= 0 { err = errors.New("分类异常") } return } // handleReportPermission // @Description: 报告权限处理 // @author: Roc // @datetime 2024-06-19 18:00:51 // @param reportId int64 // @param minClassifyId int func handleReportPermission(reportId int64, minClassifyId int) { // TODO 报告权限处理 var err error defer func() { if err != nil { utils.FileLog.Error("报告权限处理失败,报告ID:%d,分类ID:%d,Err:%s", reportId, minClassifyId, err.Error()) //alarm_msg.SendAlarmMsg("修改删除报告权限失败,Err:"+err.Error(), 3) } }() err = models.RemoveChartPermissionChapterMapping(reportId) if err != nil { err = errors.New("修改删除报告权限失败,Err:" + err.Error()) return } permissionItems, err := models.GetPermission(minClassifyId) if err != nil { err = errors.New("获取权限失败,Err:" + err.Error()) return } for _, v := range permissionItems { err = models.AddChartPermissionChapterMapping(v.ChartPermissionId, reportId) if err != nil { err = errors.New("新增权限失败,Err:" + err.Error()) return } } // 同步crm权限 _ = EditReportPermissionSync(reportId, minClassifyId) return } // HandleReportPermission // @Description: 报告权限处理 // @author: Roc // @datetime 2024-07-12 11:17:49 // @param reportInfo *models.Report func HandleReportPermission(reportInfo *models.Report) { minClassifyId, _, tmpErr := getMinClassify(reportInfo) if tmpErr != nil { return } handleReportPermission(int64(reportInfo.Id), minClassifyId) } // UpdateReportVideo // @Description: 更新报告音频 // @author: Roc // @datetime 2024-07-17 18:11:10 // @param reportInfo *models.Report func UpdateReportVideo(reportInfo *models.Report) { if reportInfo.HasChapter == 1 { reportChapterIdList := make([]int, 0) // 获取报告中的所有章节列表 chapterList, err := models.GetChapterListByReportId(reportInfo.Id) if err != nil { return } reportContent := "" for _, chapter := range chapterList { if chapter.PublishState == 2 { reportChapterIdList = append(reportChapterIdList, chapter.ReportChapterId) reportContent += chapter.Title + `。` reportContent += chapter.Content + `。` } } if len(reportChapterIdList) > 0 { err = UpdateChaptersVideo(reportChapterIdList) if err != nil { utils.FileLog.Info(fmt.Sprintf("%d报告音频生产失败:%s", reportInfo.Id, err.Error())) } } // 生成汇总音频 { if reportInfo.VideoUrl != "" && reportInfo.VideoName != "" && reportInfo.VideoSize != "" && reportInfo.VideoPlaySeconds != "" { return } videoUrl, videoName, videoSize, videoPlaySeconds, e := CreateReportVideo(reportInfo.Title, html.UnescapeString(reportContent), time.Now().Format(utils.FormatDateTime)) if e != nil { err = e return } // 修改报告的音频信息 err = models.ModifyReportVideoByNoVideo(reportInfo.Id, videoUrl, videoName, videoSize, videoPlaySeconds) } } else { err := CreateVideo(reportInfo) if err != nil { utils.FileLog.Info(fmt.Sprintf("%d报告音频生产失败:%s", reportInfo.Id, err.Error())) } } } // GetGeneralPdfUrl // @Description: 获取生成pdf的地址 // @author: Roc // @datetime 2024-07-19 14:09:28 // @param reportCode string // @param reportLayout int8 // @return pdfUrl string func GetGeneralPdfUrl(reportCode, classifyFirstName string, reportLayout int8) (pdfUrl string) { // 如果是弘则,且是晨、周报,那么就不返回 if utils.InArrayByStr([]string{utils.BusinessCodeRelease, utils.BusinessCodeSandbox, utils.BusinessCodeDebug}, utils.BusinessCode) && utils.InArrayByStr([]string{"晨报", "周报"}, classifyFirstName) { return } conf, e := models.GetBusinessConfByKey("ReportViewUrl") if e != nil { return } switch reportLayout { case 1: // 普通布局 pdfUrl = fmt.Sprintf("%s/reportshare_pdf?code=%s", conf.ConfVal, reportCode) case 2: // 智能布局 pdfUrl = fmt.Sprintf("%s/reportshare_smart_pdf?code=%s", conf.ConfVal, reportCode) } return } func GetReportWaterMarkPdf(reportInfo *models.Report, sysUser *system.Admin) { dateDir := time.Now().Format("20060102") uploadDir := utils.STATIC_DIR + "pdf/" + dateDir filePath, err := utils.DownloadFile(reportInfo.DetailPdfUrl, uploadDir) if err != nil { return } // 移除临时Pdf文件 defer func() { _ = os.Remove(filePath) }() waterMarkStr := fmt.Sprintf("%s - %s", sysUser.RealName, sysUser.Mobile) GeneralWaterMarkPdf(filePath, waterMarkStr) }