package services //FICC研报 import ( "context" "encoding/json" "errors" "fmt" "hongze/hongze_cygx/models" "hongze/hongze_cygx/models/ficc_report" "hongze/hongze_cygx/utils" "html" "strconv" "strings" "time" ) // 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 *ficc_report.Report) (minClassifyId int, minClassifyName string, err error) { defer func() { if err != nil { go utils.SendAlarmMsg(fmt.Sprint("获取最小分类ID失败,报告ID:%d,Err:%s", reportInfo.Id, err.Error()), 2) } }() 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 } // 获取报告详情 func GetReportDetail(userinfo *models.WxUserItem, reportId int) (reportDetail ficc_report.ReportDetail, err error) { //var errMsg string defer func() { if err != nil { fmt.Println(err) go utils.SendAlarmMsg(fmt.Sprint("获取研报详情失败 GetReportDetail ,err:", err.Error(), "ReportId:", reportId), 2) } }() detailArticle, e := models.GetArticleDetailByReportId(reportId) if e != nil { err = errors.New("报告查询出错" + e.Error()) return } reportInfo, e := ficc_report.GetByReportId(reportId) if e != nil { //errMsg = err.Error() err = errors.New("报告查询出错" + e.Error()) return } if reportInfo.Id == 0 { err = errors.New("报告不存在") return } if reportInfo.State != 2 && reportInfo.State != 6 { err = errors.New("报告未发布") return } // 获取最小分类 minClassifyId, _, err := GetMinClassify(reportInfo) // 判断报告是否属于专栏报告 firstClassify, e := ficc_report.GetByClassifyId(reportInfo.ClassifyIdFirst) if e != nil { err = errors.New("报告一级分类有误") return } // 最小分类 var minClassify *ficc_report.Classify if reportInfo.ClassifyIdFirst == minClassifyId { minClassify = firstClassify } else { minClassify, e = ficc_report.GetByClassifyId(minClassifyId) if e != nil { err = errors.New("报告最小层级分类有误") return } } var hasPermission int var hasPower bool if userinfo.CompanyId > 1 { companyPermission, e := models.GetCompanyPermission(userinfo.CompanyId) if e != nil { err = errors.New("GetCompanyPermission") return } if companyPermission != "" { slice := strings.Split(companyPermission, ",") if utils.InArrayByStr(slice, "周期") { hasPower = true } } } if hasPower { hasPermission = 1 } else { if userinfo.UserId == 0 { hasPermission = 1 } else { hasPermission, e = GetUserPermissionCode(userinfo.UserId, userinfo.CompanyId) if e != nil { err = errors.New("GetUserPermissionCode") return } reportDetail.SellerName, reportDetail.SellerMobile, _ = GetSellerName(userinfo) } } reportDetail.HasPermission = hasPermission //判断权限 var authOk bool var reportChapterIdList []int if reportInfo.HasChapter == 1 { if reportInfo.ClassifyNameFirst == "晨报" { //authOk, permissionCheckInfo, err = CheckDayReportPermission(userinfo, productAuthOk) } else { _, _, _, reportChapterIdList, err = CheckWeekReportPermission(userinfo, reportId, true) } } if hasPermission == 1 { authOk = true } reportItem := new(ficc_report.ReportItem) reportItem.ReportId = reportInfo.Id reportItem.Title = reportInfo.Title reportItem.PublishTime = reportInfo.PublishTime reportItem.ClassifyNameFirst = reportInfo.ClassifyNameFirst reportItem.ClassifyNameSecond = reportInfo.ClassifyNameSecond reportItem.Stage = reportInfo.Stage reportItem.Abstract = reportInfo.Abstract reportItem.ContentSub = html.UnescapeString(reportInfo.ContentSub) reportItem.Frequency = reportInfo.Frequency reportItem.VideoName = reportInfo.VideoName reportItem.HasChapter = reportInfo.HasChapter reportItem.ReportLayout = reportInfo.ReportLayout reportItem.HeadImg = reportInfo.HeadImg reportItem.EndImg = reportInfo.EndImg reportItem.CanvasColor = reportInfo.CanvasColor reportItem.ArticleId = detailArticle.ArticleId reportItem.Disclaimer = GetConfigCodeDisclaimer() if reportInfo.ClassifyNameFirst == "晨会纪要" && reportInfo.ClassifyNameSecond == "晨会纪要" { reportItem.Title = "FICC/周期品晨会纪要" } //版头版尾样式 { if reportInfo.HeadResourceId > 0 { headResource, tmpErr := ficc_report.GetResourceItemById(reportInfo.HeadResourceId) if tmpErr != nil { err = tmpErr return } reportItem.HeadImg = headResource.ImgURL reportItem.HeadStyle = headResource.Style } if reportInfo.EndResourceId > 0 { endResource, tmpErr := ficc_report.GetResourceItemById(reportInfo.EndResourceId) if tmpErr != nil { err = tmpErr return } reportItem.EndImg = endResource.ImgURL reportItem.EndStyle = endResource.Style } } if reportInfo.VideoName == "" && reportInfo.VideoUrl != "" { reportItem.VideoName = reportInfo.Title } reportItem.VideoSize = reportInfo.VideoSize reportItem.VideoPlaySeconds = reportInfo.VideoPlaySeconds reportItem.Author = reportInfo.Author // 分享背景图取二级分类配图, 二级没有配图时使用一级配图, 一级也没有使用默认图 reportItem.ShareBgImg = utils.DEFAULT_REPORT_SHARE_BG_IMG secondClassify, e := ficc_report.GetByClassifyId(reportInfo.ClassifyIdSecond) if e != nil { err = errors.New("报告二级分类有误") return } if secondClassify.YbShareBgImg != "" { reportItem.ShareBgImg = secondClassify.YbShareBgImg } else { if firstClassify.YbShareBgImg != "" { reportItem.ShareBgImg = firstClassify.YbShareBgImg } } var reportTypeList []*ficc_report.ReportChapterListItem if reportInfo.HasChapter == 1 { //(晨报和周报的banner图) if reportInfo.ClassifyNameFirst == "晨报" { reportItem.BannerUrl = utils.ALIYUN_YBIMG_HOST + "report_banner_day.jpg" } else { reportItem.BannerUrl = utils.ALIYUN_YBIMG_HOST + "report_banner_week.jpg" } // 如果还没有配置banner图,则取晨报的 if reportItem.BannerUrl == `` { reportItem.BannerUrl = utils.ALIYUN_YBIMG_HOST + "report_banner_day.jpg" } if authOk { reportTypeList, err = GetChapterListByReportChapterIdList(reportInfo.ClassifyNameFirst, reportInfo.Id, reportChapterIdList) if err != nil { return } } } else { // 音频播放条图片用分类图片 //reportItem.VideoImg = utils.HZ_DEFAULT_AVATAR //permissionIds, tmpErr := chart_permission_search_key_word_mapping.GetChartPermissionIdsByKeyWord(reportInfo.ClassifyIdSecond) //if tmpErr != nil { // errMsg = tmpErr.Error() // err = errors.New("查询报告权限失败") // return //} //if len(permissionIds) > 0 { // chartPermission, tmpErr := chart_permission.GetListByIds(permissionIds) // if tmpErr != nil { // errMsg = tmpErr.Error() // err = errors.New("查询品种信息失败") // return // } // lenChart := len(chartPermission) // for i := 0; i < lenChart; i++ { // if chartPermission[i].YbImgUrl != "" { // reportItem.VideoImg = utils.ALIYUN_YBIMG_HOST + chartPermission[i].YbImgUrl // break // } // } //} } //如果有权限则展示content if authOk { reportItem.Content = html.UnescapeString(reportInfo.Content) reportItem.VideoUrl = reportInfo.VideoUrl } if userinfo.UserId == 0 { reportItem.Content = utils.InterceptHtmlLength(reportInfo.Content, 200) } reportDetail.ReportInfo = reportItem reportDetail.ReportChapterList = reportTypeList //reportDetail.PermissionCheck = &permissionCheckInfo reportDetail.AuthOk = authOk //reportDetail.LikeNum = likeNum //reportDetail.LikeEnabled = likeEnabled reportDetail.ReportShowType = int(firstClassify.ShowType) reportDetail.ReportDetailShowType = int(minClassify.ReportDetailShowType) // 如果分类配置是列表展示,那么就移除content内容 if minClassify.ReportDetailShowType == 2 { for _, v := range reportTypeList { v.Content = `` } } else { for _, v := range reportTypeList { v.Content = html.UnescapeString(v.Content) } } return } // CheckWeekReportPermission // @Description: 验证周报的权限(并获取拥有权限的章节id列表) // @author: Roc // @datetime 2024-06-24 11:06:52 // @param userInfo user.UserInfo // @param reportId int // @param productAuthOk bool // @return authOk bool // @return permissionCheckInfo response.PermissionCheckInfo // @return validTypeIds []int 分类关联的章节类型ID列表 // @return reportChapterIdList []int 并获取拥有权限的章节id列表 // @return err error func CheckWeekReportPermission(userInfo *models.WxUserItem, reportId int, productAuthOk bool) (authOk bool, permissionCheckInfo ficc_report.PermissionCheckInfo, validTypeIds, reportChapterIdList []int, err error) { var permissionIds []int //var validPermissionIds []int //最后允许显示的章节 // 当前报告的品种与章节列表的map permissionChapterList := make(map[int][]int) permissionIdMap := make(map[int]bool) typeIdMap := make(map[int]bool) reportChapterIdMap := make(map[int]bool) if productAuthOk { reportChapterMappingList, e := ficc_report.GetReportChapterPermissionMappingItemListByReportId(reportId) if e != nil && e.Error() != utils.ErrNoRow() { err = errors.New(e.Error()) return } for _, v := range reportChapterMappingList { if _, ok := permissionIdMap[v.ChartPermissionId]; !ok { permissionIdMap[v.ChartPermissionId] = true permissionIds = append(permissionIds, v.ChartPermissionId) } if _, ok := typeIdMap[v.TypeId]; !ok { typeIdMap[v.TypeId] = true validTypeIds = append(validTypeIds, v.TypeId) } tmpList, ok := permissionChapterList[v.ChartPermissionId] if !ok { tmpList = make([]int, 0) } permissionChapterList[v.ChartPermissionId] = append(tmpList, v.ReportChapterId) if _, ok := reportChapterIdMap[v.ReportChapterId]; !ok { reportChapterIdMap[v.ReportChapterId] = true reportChapterIdList = append(reportChapterIdList, v.ReportChapterId) //走权益的校验权限,到这里的权限都可以用 } } } return } // GetChapterListByReportChapterIdList // @Description: 根据报告获取章节列表 // @author: Roc // @datetime 2024-06-24 11:23:36 // @param classifyNameFirst string // @param reportId int // @param reportChapterIdList []int // @param reportCreateTime time.Time // @return reportTypeList response.ReportChapterList // @return err error func GetChapterListByReportChapterIdList(classifyNameFirst string, reportId int, reportChapterIdList []int) (reportTypeList ficc_report.ReportChapterList, err error) { var errMsg string defer func() { if err != nil { go utils.SendAlarmMsg(fmt.Sprintf("GetChapterListByReport: err:%s, errMsg:%s", err.Error(), errMsg), 2) } }() //查询有效的章节 typeList, e := ficc_report.GetEffectTypes() if e != nil { err = errors.New("章节类型查询出错" + e.Error()) return } if len(typeList) == 0 { err = errors.New("无有效的章节") return } typeMap := make(map[uint64]*ficc_report.ReportChapterType) for _, v := range typeList { typeMap[v.ReportChapterTypeId] = v } var chapterList []*ficc_report.ReportChapter if len(reportChapterIdList) > 0 { //获取所有当前研报有权限的章节 chapterList, e = ficc_report.GetListByChapterIds(reportChapterIdList) } else { // 获取所有报告章节 chapterList, e = ficc_report.GetListByReportId(reportId, classifyNameFirst) } if e != nil && e.Error() != utils.ErrNoRow() { err = errors.New("章节查询出错" + e.Error()) return } if len(chapterList) == 0 { err = errors.New("无有效章节") return } for _, item := range chapterList { typeItem, ok1 := typeMap[uint64(item.TypeId)] // 如果是配置的章节,那么就需要判断是否禁用,如果禁用,则不展示 if item.TypeId > 0 && !ok1 { continue } temp := new(ficc_report.ReportChapterListItem) temp.ReportChapterId = item.ReportChapterId temp.TypeId = item.TypeId temp.TypeName = item.TypeName temp.Title = item.Title temp.Trend = item.Trend temp.ReportId = item.ReportId temp.Sort = item.Sort temp.PublishTime = item.PublishTime temp.VideoUrl = item.VideoUrl temp.VideoName = item.VideoName temp.VideoPlaySeconds = item.VideoPlaySeconds temp.VideoSize = item.VideoSize temp.Content = item.Content // 系统配置的参数,只有配置的章节类型,才能赋值 if typeItem != nil { temp.ReportChapterTypeKey = typeItem.ReportChapterTypeKey temp.ReportChapterTypeName = typeItem.ReportChapterTypeName temp.ReportChapterTypeThumb = typeItem.YbIconUrl } reportTypeList = append(reportTypeList, temp) } //if len(reportTypeList) > 0 { // sort.Sort(reportTypeList) //} return } //func init() { // GetFiccRreportToCygxArticle() // //UpdateFICCReportResourceData(5542) //} // 获取FICC研报到查研观向数据库中 func GetFiccRreportToCygxArticle(cont context.Context) (err error) { //func GetFiccRreportToCygxArticle() (err error) { defer func() { if err != nil { fmt.Println(err) go utils.SendAlarmMsg(fmt.Sprint("获取FICC研报到查研观向数据库中定时任务失败 ,err:", err.Error()), 2) } }() var condition string var pars []interface{} modifyTime := time.Now().Add(-10 * time.Minute) condition = ` AND modify_time >= ? ` pars = append(pars, modifyTime) reportList, e := ficc_report.GetFiccRreportToCygxArticle(condition, pars) if e != nil { err = errors.New("GetFiccRreportToCygxArticle, Err: " + e.Error()) return } fmt.Println(len(reportList)) //if len(reportList) == 0 { // return //} //获取研报的匹配关系 conf, e := models.GetConfigByCode(utils.GET_FICC_REPORT_SET) if e != nil { err = errors.New("GetConfigByCode, Err: " + e.Error()) return } if conf.ConfigValue == "" { err = errors.New("同步FICC研报的规则配置值有误") return } listFiccSet := new(ficc_report.GetReporteSetListResp) if e = json.Unmarshal([]byte(conf.ConfigValue), &listFiccSet); e != nil { err = errors.New("同步FICC研报的规则配置值解析失败 Err: " + e.Error()) return } if len(reportList) > 0 { var reportIds []int for _, v := range reportList { reportIds = append(reportIds, v.Id) } listFiccReport, e := models.GetCygxCygxArticleListByReportIds(reportIds) if e != nil { err = errors.New("GetCygxCygxArticleListByReportIds, Err: " + e.Error()) return } mapFiccReport := make(map[int]int) for _, v := range listFiccReport { mapFiccReport[v.ReportId] = v.ArticleId } //量不大,先这么写吧 for _, v := range reportList { time.Sleep(1 * time.Millisecond) // 延时一秒 item := new(models.CygxArticle) item.ReportId = v.Id item.PublishDate = v.PublishTime.Format(utils.FormatDateTime) item.Title = v.Title if v.ClassifyNameFirst == "晨会纪要" && v.ClassifyNameSecond == "晨会纪要" { item.Title = "FICC/周期品晨会纪要" } item.CategoryName = utils.ZHOU_QI_NAME item.Body = v.Content item.Abstract = v.Abstract item.FieldName = v.ClassifyNameSecond item.CreateDate = time.Now().Format(utils.FormatDate) item.PublishStatus = 1 item.IsReport = 1 item.IsClass = 1 item.CreateTime = time.Now() item.ChartPermissionName = utils.ZHOU_QI_NAME item.ChartPermissionId = utils.ZHOU_QI_ID var haveSet bool for _, vSet := range listFiccSet.List { if v.ClassifyNameFirst == vSet.ClassifyNameFirst && v.ClassifyNameSecond == vSet.ClassifyNameSecond { haveSet = true item.SubCategoryName = v.ClassifyNameSecond item.MatchTypeName = v.ClassifyNameSecond continue } } if !haveSet { continue } detailCategory, detailCategoryErr := models.GetCygxReportMappingCelueDetailByZhoQiCategoryName(item.SubCategoryName) if detailCategoryErr != nil { continue } item.CategoryId = detailCategory.CategoryId item.CategoryIdTwo = detailCategory.CategoryId var articleIdMax int //如果不存在就新增 if mapFiccReport[v.Id] == 0 { maxArticleIdArticleInfo, e := models.GetMaxArticleIdInfo() if e != nil { err = errors.New("GetMaxArticleIdInfo, Err: " + e.Error()) return } articleIdMax = maxArticleIdArticleInfo.ArticleId + 1 item.ArticleIdMd5 = utils.MD5(strconv.Itoa(articleIdMax)) item.ArticleId = articleIdMax _, e = models.AddCygxArticles(item) if e != nil { err = errors.New("AddCygxArticles, Err: " + e.Error()) return } } else { articleIdMax = mapFiccReport[v.Id] item.ArticleId = mapFiccReport[v.Id] updateParams := make(map[string]interface{}) updateParams["Title"] = item.Title updateParams["PublishDate"] = item.PublishDate updateParams["Body"] = item.Body updateParams["Abstract"] = item.Abstract updateParams["PublishStatus"] = item.PublishStatus updateParams["SubCategoryName"] = item.SubCategoryName updateParams["MatchTypeName"] = item.MatchTypeName updateParams["FieldName"] = item.FieldName updateParams["CategoryId"] = item.CategoryId updateParams["CategoryIdTwo"] = item.CategoryIdTwo whereParam := map[string]interface{}{"article_id": item.ArticleId} err = models.UpdateByExpr(models.CygxArticle{}, whereParam, updateParams) if err != nil { fmt.Println("UpdateByExpr Err:" + err.Error()) return err } } UpdateFICCReportResourceData(v.Id, listFiccSet) AddCygxReportMappingCategoryGroupByArticleId(articleIdMax) UpdateCygxZhouqiArticleMapTime(item.FieldName) //更新周期对应分类下所管理文章的更新时间 } } //获取已经同步到查研的FICC研报 对比,如果FICC研报已经取消发布,查研也做对应的删除 listCygxFiccReport, e := models.GetCygxCygxArticleFiccReportList() if e != nil { err = errors.New("GetCygxCygxArticleFiccReportList, Err: " + e.Error()) return } var cygxFiccReportIds []int for _, v := range listCygxFiccReport { if v.PublishStatus == 1 { cygxFiccReportIds = append(cygxFiccReportIds, v.ReportId) } } lenArr := len(cygxFiccReportIds) if lenArr == 0 { return } reportByHandList, e := ficc_report.GetCygxFiccReportByHandList() // 手动同步过来的报告 if e != nil { err = errors.New("GetCygxFiccReportByHandList, Err: " + e.Error()) return } ficcReporIdsHand := make(map[int]bool) // Ficc 研报手动同步过来的报告ID for _, v := range reportByHandList { ficcReporIdsHand[v.FiccReportId] = true } condition = ` AND id IN (` + utils.GetOrmInReplace(lenArr) + `) ` pars = make([]interface{}, 0) pars = append(pars, cygxFiccReportIds) ficcReportListPush, e := ficc_report.GetFiccRreportToCygxArticle(condition, pars) if e != nil { err = errors.New("GetFiccRreportToCygxArticle, Err: " + e.Error()) return } var removeficcReporIds []int // 需要移除的报告ID ficcReporIdsPush := make(map[int]bool) // Ficc 研报还存在的报告ID for _, v := range ficcReportListPush { ficcReporIdsPush[v.Id] = true } for _, v := range listCygxFiccReport { if !ficcReporIdsPush[v.ReportId] && !ficcReporIdsHand[v.ReportId] { // 手动同步过来的报告不做删除处理 removeficcReporIds = append(removeficcReporIds, v.ReportId) } } if len(removeficcReporIds) > 0 { e = models.HideCygxResourceDataFiccReport(removeficcReporIds) if e != nil { err = errors.New("HideCygxResourceDataFiccReport, Err: " + e.Error()) return } } fmt.Println("end") return } // 根据用户信息,获取跳转研报小程序详情信息 func GetFiccReportXcxItem(user *models.WxUserItem) (itemSourceResp *models.CygxResourceDataResp) { var err error defer func() { if err != nil { fmt.Println(err) go utils.SendAlarmMsg(fmt.Sprint("根据用户信息,获取跳转研报小程序详情信息失败 GetFiccReportXcxItem ,err:", err.Error(), "UserId:", user.UserId), 2) } }() deUserId := utils.DesBase64Encrypt([]byte(strconv.Itoa(user.UserId))) itemSource := new(models.CygxResourceDataResp) itemSource.Source = utils.CYGX_OBJ_FICC_REPORT_XCX itemResp := new(models.FiccReportXcx) itemResp.Source = utils.CYGX_OBJ_FICC_REPORT_XCX itemResp.Title = "每日原油播报" itemResp.SecondTitle = "欧美市场隔夜复盘" itemResp.ImgUrl = utils.FICC_REPORT_ICO_HOME itemResp.Mobile = user.Mobile itemResp.SellerMobile = "" itemResp.SellerName = "" itemResp.Appid = utils.FICC_REPORT_APPID itemResp.SourceUrl = "pages/voice/voice?thirdCode=" itemResp.ThirdCode = string(deUserId) //var hasPermission int var hasPersion bool if user.CompanyId > 1 { companyPermission, e := models.GetCompanyPermission(user.CompanyId) if e != nil { err = errors.New("获取用户权限信息失败" + e.Error()) return } if companyPermission != "" { slice := strings.Split(companyPermission, ",") if utils.InArrayByStr(slice, "周期") { hasPersion = true } } } var hasPermission int var e error if hasPersion { hasPermission = 1 } else { if user.UserId == 0 { hasPermission = 1 } else { itemResp.HasPermission, itemResp.SellerName, itemResp.SellerMobile, _, err = GetUserHasPermissionArticle(user) if err != nil { return } hasPermission, e = GetUserPermissionCode(user.UserId, user.CompanyId) if e != nil { err = errors.New("GetUserPermissionCode") return } itemResp.SellerName, itemResp.SellerMobile, _ = GetSellerName(user) } } itemResp.HasPermission = hasPermission itemSource.FiccReportXcx = itemResp itemSourceResp = itemSource return } //func init() { // strslice := []string{"晨会纪要", "煤炭", "铜行业数据点评", "石油石化", "黑色调研", "宏观G2观察", "黄金月报"} // for _, v := range strslice { // fmt.Println(v) // UpdateCygxZhouqiArticleMapTime(v) // } //} // UpdateCygxZhouqiArticleMapTime 更新周期对应分类下所管理文章的更新时间 func UpdateCygxZhouqiArticleMapTime(fieldName string) { var err error defer func() { if err != nil { fmt.Println("err:", err) go utils.SendAlarmMsg(fmt.Sprint("更新周期对应分类下所管理文章的更新时间 失败,UpdateCygxZhouqiArticleMapTime Err:"+err.Error()+"fieldName", fieldName), 3) } }() detail, e := models.GetCygxZhouqiArticleMapByMatchTypeName(fieldName) if e != nil { err = errors.New("GetCygxZhouqiArticleMapByMatchTypeName, Err: " + err.Error()) return } listCategory, e := models.GetCygxZhouqiArticleMapByParentId(detail.ParentId) if e != nil { err = errors.New("GetCygxZhouqiArticleMapByParentId, Err: " + err.Error()) return } var matchTypeName = []string{} for _, v := range listCategory { matchTypeName = append(matchTypeName, v.MatchTypeName) } var condition string var pars []interface{} condition = " AND category_name = '周期' AND field_name IN ('" + strings.Join(matchTypeName, "','") + "') ORDER BY publish_date DESC " articleList, e := models.GetCygxCygxArticleList(condition, pars, 0, 1) if e != nil { err = errors.New("GetCygxCygxArticleList, Err: " + e.Error()) return } //就一条数据 for _, v := range articleList { e = models.UpdateCygxZhouqiArticleMapTime(v.PublishDate, detail.ParentId) } return }