package services import ( "context" "encoding/json" "errors" "fmt" "github.com/PuerkitoBio/goquery" "hongze/hongze_cygx/models" "hongze/hongze_cygx/models/company" "hongze/hongze_cygx/utils" "html" "net/url" "regexp" "sort" "strconv" "strings" "time" ) func GetReportContentTextSub(content string) (contentSub string, err error) { content = html.UnescapeString(content) doc, err := goquery.NewDocumentFromReader(strings.NewReader(content)) docText := doc.Text() bodyRune := []rune(docText) bodyRuneLen := len(bodyRune) if bodyRuneLen > 200 { bodyRuneLen = 200 } body := string(bodyRune[:bodyRuneLen]) contentSub = body contentSub = strings.Replace(body, "Powered by Froala Editor", "", -1) return } func GetAnnotationTextSub(content string) (contentSub string) { contentSub = strings.Replace(content, "

", " ", -1) contentSub = strings.Replace(contentSub, "

", "", -1) return } func GetReportContentTextSubNew(content string) (contentSub string, err error) { content = html.UnescapeString(content) doc, errdoc := goquery.NewDocumentFromReader(strings.NewReader(content)) if errdoc != nil { err = errdoc return } docText := doc.Text() bodyRune := []rune(docText) bodyRuneLen := len(bodyRune) body := string(bodyRune[:bodyRuneLen]) contentSub = body contentSub = strings.Replace(contentSub, "Powered by Froala Editor", "", -1) contentSub = strings.Replace(contentSub, " ", "", -1) contentSub = strings.Replace(contentSub, "

Froala Editor

", "", -1) return } func FixArticleImgUrl(body string) (contentSub string, err error) { r := strings.NewReader(string(body)) doc, err := goquery.NewDocumentFromReader(r) if err != nil { fmt.Println(err) } doc.Find("img").Each(func(i int, s *goquery.Selection) { src, _ := s.Attr("src") if i == 0 && src != "" { contentSub = src } }) return } func SynchronizationArtclehistory() { fmt.Println("同步开始") list, err := models.GetArticleHistoryList() if err != nil { fmt.Println("获取列表失败", err) } fmt.Println(len(list)) for _, v := range list { //endDate := v.ModifyTime.Add(+time.Minute * 10).Format(utils.FormatDateTime) //detail, err := models.GetNewArticleHistoryRecordNewpv(v.UserId, v.ArticleId, endDate) //if err != nil && err.Error() != utils.ErrNoRow() { // fmt.Println("获取信息失败", err) //} v.OutType = 1 //fmt.Println(v.Id) //if detail == nil { // _, err = models.AddCygxArticleViewRecordNewpv(v) // if err != nil { // fmt.Println("新增失败", err) // } //} else { // err = models.UpdateCygxArticleViewRecordNewpvList(v, v.StopTime) // if err != nil { // fmt.Println("修改失败", err) // } //} newId, err := models.AddCygxArticleViewRecordNewpv(v) fmt.Println("新增", newId) if err != nil { fmt.Println("新增失败", err) } } fmt.Println("同步结束") } // UserViewRedisData 阅读数据 type UserViewRedisData struct { Mobile string `json:"mobile"` Email string `json:"email"` RealName string `json:"real_name"` CompanyName string `json:"company_name"` ViewTime string `json:"view_time" description:"阅读时间,格式:2022-02-17 13:06:13"` ProductId int `json:"product_id" description:"报告所属产品,ficc:1,权益:2"` CompanyId int `json:"company_id" description:"客户id"` UserId int `json:"user_id" description:"用户id"` ReportId int `json:"report_id" description:"报告id"` StopTime int `json:"stop_time" description:"停留时间"` ReportChapterId int `json:"report_chapter_id" description:"章节ID"` OutId int `json:"out_id" description:"记录ID"` } type ReportViewRecord struct { Id int `orm:"column(id);pk"` //UserId int `json:"user_id" description:"用户ID"` //ReportId int `description:"报告id"` //Mobile string `description:"手机号"` //Email string `description:"邮箱"` //RealName string `description:"用户实际姓名"` //CompanyName string `description:"公司名称"` //CreateTime time.Time `description:"创建时间"` //StopTime int `json:"stop_time" description:"停留时间"` //ReportChapterId int `json:"report_chapter_id" description:"章节ID"` //OutId int `json:"out_id" description:"记录ID"` Mobile string `json:"mobile"` Email string `json:"email"` RealName string `json:"real_name"` CompanyName string `json:"company_name"` ViewTime string `json:"view_time" description:"阅读时间,格式:2022-02-17 13:06:13"` ProductId int `json:"product_id" description:"报告所属产品,ficc:1,权益:2"` CompanyId int `json:"company_id" description:"客户id"` UserId int `json:"user_id" description:"用户id"` ReportId int `json:"report_id" description:"报告id"` StopTime int `json:"stop_time" description:"停留时间"` ReportChapterId int `json:"report_chapter_id" description:"章节ID"` OutId int `json:"out_id" description:"章节ID"` } // PushViewRecordNewRedisData 阅读数据加入到redis func PushViewRecordNewRedisData(reportViewRecord *ReportViewRecord, companyId int) bool { data := &UserViewRedisData{ Mobile: reportViewRecord.Mobile, UserId: reportViewRecord.UserId, Email: reportViewRecord.Email, RealName: reportViewRecord.RealName, CompanyName: reportViewRecord.CompanyName, ViewTime: reportViewRecord.ViewTime, ProductId: 2, CompanyId: companyId, ReportId: reportViewRecord.ReportId, StopTime: reportViewRecord.StopTime, ReportChapterId: reportViewRecord.ReportChapterId, OutId: reportViewRecord.OutId, } if utils.Re == nil { err := utils.Rc.LPush(utils.CACHE_KEY_USER_VIEW, data) if err != nil { fmt.Println("PushViewRecordNewRedisData LPush Err:" + err.Error()) } return true } return false } // 获取策略平台报告阅读数据 func GetCeLueArticlePv(cont context.Context) (err error) { //func GetCeLueArticlePv() (err error) { defer func() { if err != nil { go utils.SendAlarmMsg("同步策略平台阅读数据失败"+err.Error(), 2) go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "GetCeLueArticlePv ErrMsg:"+err.Error(), utils.EmailSendToUsers) } }() startTime := time.Now().Add(-time.Minute * 12).Format("2006-01-02 15:04:05") endTime := time.Now().Format("2006-01-02 15:04:05") requestUrl := utils.ApiUrl + "backend/statistics_access?take=1000&skip=0&sort=ASC&mode=all&" encodeData := url.Values{} encodeData.Add("start_dt", startTime) encodeData.Add("end_dt", endTime) encodeStr := encodeData.Encode() requestUrl += encodeStr authorization := utils.ApiAuthorization body, err := PublicGetDate(requestUrl, authorization) if err != nil { return } var chartResult models.CeLueArticleResultApi err = json.Unmarshal(body, &chartResult) if err != nil { fmt.Println(err) return err } mapMobileArticleId := make(map[string]int) //获取当天阅读记录 listPv, err := models.GetArticleHistoryRecordAllList() if err != nil && err.Error() != utils.ErrNoRow() { fmt.Println("获取当天阅读记录失败", err) return err } if len(listPv) > 0 { for _, v := range listPv { mapMobileArticleId[fmt.Sprint(v.Mobile, "_", v.ArticleId)] = v.ArticleId } } var celueHistoryIds []int var mobiles []string for _, v := range chartResult.Data { celueHistoryIds = append(celueHistoryIds, v.CelueHistoryId) mobiles = append(mobiles, v.Mobile) } listcelueHistory, e := models.GetCeLueArticleListByIds(celueHistoryIds) if e != nil { err = errors.New("GetCeLueArticleListByIds, Err: " + e.Error()) return } mapCelueHistoryIds := make(map[int]int) for _, v := range listcelueHistory { mapCelueHistoryIds[v.CelueHistoryId] = v.CelueHistoryId } listMobileCompany, e := company.GetCompanyProductListByMobiles(mobiles) if e != nil { err = errors.New("GetCompanyProductListByMobiles, Err: " + e.Error()) return } mapUserCompany := make(map[string]*company.CompanyProductUser) for _, v := range listMobileCompany { mapUserCompany[v.Mobile] = v } var celueArticleHistoryItems []*models.CygxCelueArticleHistoryRecord var allRecordItems []*models.CygxArticleHistoryRecordAll for _, v := range chartResult.Data { articleId, _ := strconv.Atoi(v.ArticleId) if articleId == 0 { continue } //fmt.Println(v.ArticleId) item := new(models.CygxCelueArticleHistoryRecord) item.CelueHistoryId = v.CelueHistoryId item.Mobile = v.Mobile item.ArticleId = v.ArticleId if v.CompanyName != nil { item.CompanyName = v.CompanyName.RealName } if v.CrmUser != nil { item.RealName = v.CrmUser.RealName } if mapUserCompany[v.Mobile] != nil { mapUser := mapUserCompany[v.Mobile] item.CompanyName = mapUser.CompanyName item.CompanyStatus = mapUser.Status item.SellerName = mapUser.SellerName } item.CreateDateApi = time.Now() t1, _ := time.Parse("2006-01-02T15:04:05Z", v.CreateDate) item.CreateTime = t1.Add(+time.Hour * 8).Format(utils.FormatDateTime) //email=?,company_id=?,company_name=?,user_id=?,real_name=? if mapCelueHistoryIds[v.CelueHistoryId] == 0 { celueArticleHistoryItems = append(celueArticleHistoryItems, item) //写入记录到总的统计表 record := new(models.CygxArticleHistoryRecordAll) record.ArticleId = articleId record.CelueHistoryId = item.CelueHistoryId record.CreateTime = item.CreateTime record.ModifyTime = time.Now() record.CreateDateApi = time.Now() if mapUserCompany[v.Mobile] != nil { mapUser := mapUserCompany[v.Mobile] record.Mobile = mapUser.Mobile record.CompanyName = mapUser.CompanyName record.CompanyStatus = mapUser.Status record.SellerName = mapUser.SellerName record.CompanyId = mapUser.CompanyId record.RealName = mapUser.RealName record.UserId = mapUser.UserId record.Email = mapUser.Email } record.Platfor = 2 record.Source = "CELUE" if mapMobileArticleId[fmt.Sprint(item.Mobile, "_", item.ArticleId)] == articleId { record.IsDel = 1 } allRecordItems = append(allRecordItems, record) } //count, err := models.GetCeLueArticleCountById(v.CelueHistoryId) //if err != nil && err.Error() != utils.ErrNoRow() { // return err //} //if count == 0 { // _, err := models.AddCeLueArticle(item, mapMobileArticleId) // if err != nil { // fmt.Println(err) // return err // } //} } if len(celueArticleHistoryItems) > 0 { e = models.AddCygxArticleHistoryRecordAllMulti(celueArticleHistoryItems, allRecordItems) if e != nil { err = errors.New("AddCygxArticleHistoryRecordAllMulti, Err: " + e.Error()) return } } //处理同步过来的阅读记录所属用户 //var condition string //condition = ` AND create_time > ` + "'" + startTime + "'" //listArticlePv, err := models.GetArticleHistoryRecordAllByMobileList(condition) //if err != nil { // fmt.Println("GetArticleHistoryRecordAllByMobileList ,Err" + err.Error()) //} //for _, v := range listArticlePv { // if v.Mobile != "" { // user, err := models.GetWxUserItemByMobile(v.Mobile) // if err != nil && err.Error() != utils.ErrNoRow() { // fmt.Println("GetWxUserItemByUserId ,Err" + err.Error()) // } // if user != nil { // err = models.UpdateCygxArticleHistoryRecordAll(user) // if err != nil { // fmt.Println("UpdateCygxArticleCollect ,Err" + err.Error()) // } // } // } //} return } func GetArticleListByApi(cont context.Context) (err error) { defer func() { if err != nil { //fmt.Println("GetArticleListByApi Err:" + err.Error()) go utils.SendAlarmMsg("同步策略平台数据失败", 2) go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "GetArticleListByApi ErrMsg:"+err.Error(), utils.EmailSendToUsers) } }() listUpdateArticle, err := models.GetArticleCeluePushList() if err != nil && err.Error() != utils.ErrNoRow() { return err } //如果长度为零就不处理 if len(listUpdateArticle) == 0 { return err } for _, v := range listUpdateArticle { // 这里直接go出去会出现并发,导致文章md5ID唯一索引限制报错 err = HandleArticleListByApi(v.ArticleId) if err != nil { utils.FileLog.Info("HandleArticleListByApi", err.Error()) } } return } // 获取策略平台推送过来的文章并更新 func UpdateArticleByRedis() (err error) { for { utils.Rc.Brpop(utils.CYGX_ARTICLE_UPDATE_KEY, func(b []byte) { var log models.CygxArticleCeluePushRedis if err := json.Unmarshal(b, &log); err != nil { fmt.Println("json unmarshal wrong!") go utils.SendAlarmMsg("获取策略平台推送过来的文章并更新处理Redis队列消息失败:"+err.Error()+string(b), 2) } // 这里直接go出去会出现并发,导致文章md5ID唯一索引限制报错 err = HandleArticleListByApi(log.ArticleId) if err != nil { utils.FileLog.Info("HandleArticleListByApi", err.Error()) } }) } } // 处理同步过来的文章 func HandleArticleListByApi(artcleId int) (err error) { defer func() { if err != nil { go utils.SendAlarmMsg("处理同步过来的文章失败"+"HandleArticleListByApi ErrMsg:"+err.Error()+"artcleId:"+strconv.Itoa(artcleId), 2) } }() var clueApiUrl string clueApiUrl = fmt.Sprint(utils.ApiUrl, "articles/", artcleId) fmt.Println(clueApiUrl) authorization := utils.ApiAuthorization body, err := PublicGetDate(clueApiUrl, authorization) if err != nil { fmt.Println(err) return } var articleResultDate models.ArticleDetailResultApi err = json.Unmarshal(body, &articleResultDate) if err != nil { fmt.Println("Getres.PublicGetDate Err:", err.Error()) return err } item := new(models.CygxShanghaiCompanyLog) item.CreateTime = time.Now() item.Url = clueApiUrl item.Body = "" item.Result = string(body) go models.AddCygxShanghaiCompanyLog(item) go models.UpdateCygxArticleCeluePush(artcleId) articleResult := articleResultDate.Data exitMap := make(map[int]int) categoryIdMap := make(map[int]int) classMap := make(map[int]int) reportMap := make(map[int]int) summaryMap := make(map[int]int) listMap, err := models.GetArticleApiMap() if err != nil { fmt.Println("GetlistMap Err:", err.Error()) return err } openIdList, err := models.GetUserRecordListByMobile(4, utils.ArticleTaskClassMobile) if err != nil { fmt.Println(err) return err } fmt.Println(openIdList) //新旧分类 反向隐射,是否归类,是否是报告,是否是纪要库 for _, v := range listMap { exitMap[v.SeriesId] = v.OldId categoryIdMap[v.SeriesId] = v.OldIdMap if v.IsClass == 1 { classMap[v.OldId] = 1 } if v.IsReport == 1 { reportMap[v.OldId] = 1 } if v.IsSummary == 1 { summaryMap[v.OldId] = 1 } } var list []*models.Tactics2 var listArticleData []*models.CygxArticleData var listAuthor []*models.CygxArticleAuthor //如果是英文报告 ,或者香港类型那么则不同步 publish_area :all 全部 ;hk 香港 if articleResult.TypeId == 9 || articleResult.PublishArea != "all" { // 如果是英文报告,或者是香港报告就进行删除处理 err = models.UpdateArticlePublish(artcleId, 0) if err != nil { fmt.Println("UpdateArticlePublish Err:", err.Error()) return err } UpdateArticleResourceData(artcleId) //把数据写入 cygx_resource_data 表 return } var cover string if articleResult.Series.Name == "图解市场" { cover = GetArticleCoverByChartFirst(articleResult.Content.Body) } else if articleResult.Series.Name == "行业深度" { cover = articleResult.Cover } fmt.Println(cover) //return //状态等于 2 跟 4 的进行同步 IsActive 为false 软删除的也不同步 if exitMap[articleResult.SeriesId] > 0 && (articleResult.PublishStatus == 2 || articleResult.PublishStatus == 4) && articleResult.IsActive { articleResult.PublishDate = time.Date(articleResult.PublishDate.Year(), articleResult.PublishDate.Month(), articleResult.PublishDate.Day(), articleResult.PublishDate.Hour(), articleResult.PublishDate.Minute(), articleResult.PublishDate.Second(), articleResult.PublishDate.Nanosecond(), time.Local) item := new(models.Tactics2) itemArticleData := new(models.CygxArticleData) itemArticleData.ArticleId = articleResult.ArticleId itemArticleData.Cover = articleResult.Cover itemArticleData.CreateTime = time.Now() listArticleData = append(listArticleData, itemArticleData) itemAuthor := new(models.CygxArticleAuthor) item.ArticleId = articleResult.ArticleId item.Title = articleResult.Title item.TitleEn = articleResult.TitleEn item.File = articleResult.File if articleResult.Frequency == "日度" { item.UpdateFrequency = "daily" } else if articleResult.Frequency == "周度" { item.UpdateFrequency = "weekly" } else if articleResult.Frequency == "月度" { item.UpdateFrequency = "monthly" } else if articleResult.Frequency == "季度" { item.UpdateFrequency = "quarterly" } else if articleResult.Frequency == "年度" { item.UpdateFrequency = "yearly" } else { item.UpdateFrequency = "unknow" } item.CreateDate = articleResult.CreateDate item.PublishDate = articleResult.PublishDate.Add(time.Hour * 8) item.PublishStatus = 1 item.Body = articleResult.Content.Body item.Abstract = articleResult.Content.Abstract item.Annotation = articleResult.Content.Annotation item.CategoryName = articleResult.Industry.Name item.CategoryId = categoryIdMap[articleResult.SeriesId] item.CategoryIdTwo = exitMap[articleResult.SeriesId] item.SubCategoryName = articleResult.Series.Name item.Cover = cover //{ // //这两种情况特殊处理 // if articleResult.Field.Name == "宏观利率" { // item.CategoryId = 10070 // item.CategoryIdTwo = item.CategoryId // } // if articleResult.Field.Name == "信用" { // item.CategoryId = 10082 // item.CategoryIdTwo = item.CategoryId // } //} if len(articleResult.Stock) > 0 { var stock string for _, vS := range articleResult.Stock { stock += vS + "/" } stock = strings.TrimRight(stock, "/") item.Stock = stock } item.FieldName = articleResult.Field.Name item.SeriesName = articleResult.Series.Name item.TypeName = articleResult.Type.Name item.UpdateDate = articleResult.UpdateDate item.CeLueFieldId = articleResult.Field.Id list = append(list, item) itemAuthor.ArticleId = articleResult.ArticleId itemAuthor.Name = articleResult.Author.Name itemAuthor.Mobile = articleResult.Author.PhoneNumber fmt.Println(articleResult.Cover) listAuthor = append(listAuthor, itemAuthor) } else { // 如果这篇文章没有发布,那么就不作处理。 err = models.UpdateArticlePublish(artcleId, 0) if err != nil { fmt.Println("UpdateArticlePublish Err:", err.Error()) return err } UpdateArticleResourceData(artcleId) //把数据写入 cygx_resource_data 表 //go UpdateResourceData(artcleId, "article", "delete", time.Now().Format(utils.FormatDateTime)) return } //同步作者 for _, v := range listAuthor { var count int count, err = models.GetActivityAuthorCount(v.ArticleId, v.Mobile) if err != nil { fmt.Println("GetActivityAuthorCount Err:", err.Error()) return err } if count == 0 { _, err = models.AddCygxActivityAuthor(v) if err != nil { fmt.Println("AddCygxActivityAuthor Err:", err.Error()) return err } } } fmt.Println("同步文章条数:", len(list)) listCustomArticle, err := models.GetCustomArticleId() //手动归类的文章,不替换文章类型 if err != nil { fmt.Println("GetTacticsList Err:", err.Error()) return err } listGetMatchTypeName, errMatch := models.GetMatchTypeNamenNotNull() //手动归类的文章,不替换文章类型 if errMatch != nil { fmt.Println("GetTacticsList Err:", errMatch.Error()) return err } //mapCategoryIdSet := make(map[int]int) //for _, vMatch := range listGetMatchTypeName { // mapCategoryIdSet[vMatch.CategoryId] = vMatch.CategoryIdSet //} fmt.Println("list len:", len(list)) noSummaryArticleIds := "3454,3456,3457,3459,2449,2450,2453,2454,2459,2530,2583,2663,2670,2699,2715,2732,2748,2759,2399,2356,2870,3173,2978,2826,3470" //非纪要库类型的文章ID listNoSummaryArticleIds := strings.Split(noSummaryArticleIds, ",") for k, v := range list { //同步匹配类型 matchTypeName := "" for _, vMatch := range listGetMatchTypeName { if v.CategoryId == vMatch.CategoryId { matchTypeName = vMatch.MatchTypeName } } //是否属于纪要库的数据 //if _, has := summaryMap[v.CategoryId]; has { // v.IsSummary = 1 //} if v.TypeName == "纪要" { v.IsSummary = 1 } //排除不属于纪要库类型的文章 for _, vArt := range listNoSummaryArticleIds { vArtInt, _ := strconv.Atoi(vArt) if v.ArticleId == vArtInt { v.IsSummary = 0 } } if _, has := reportMap[v.CategoryIdTwo]; has { v.IsReport = 1 if _, ok := classMap[v.CategoryIdTwo]; ok { v.IsClass = 1 v.ReportType = 1 //是否属于行业报告 } else { v.ReportType = 2 //是否属于产业报告 } } v.Department = "弘则权益研究" //判断是否已经存在 if v.ArticleId < 0 { fmt.Println("AddCygxArticle Err:") return err } var count int count, err = models.GetArticleCountById(v.ArticleId) if err != nil && err.Error() != utils.ErrNoRow() { fmt.Println("AddCygxArticle Err:", err.Error()) return err } v.Body = strings.Replace(v.Body, "http://vmp.hzinsights.com", "https://vmp.hzinsights.com", -1) expertNumStr, expertContentStr, interviewDateStr, _, bodyReturn := BodyAnalysis2(v.Body) if strings.Index(v.Body, "报告全文(") > 0 && strings.Index(v.Body, "PDF格式报告下载.pdf") > 0 { v.Body = strings.Replace(v.Body, "报告全文(", "", -1) v.Body = strings.Replace(v.Body, "PDF格式报告下载.pdf", "", -1) v.Body = strings.Replace(v.Body, "):", "", -1) } var titleNew string titleNew = v.Title // 7资金流向 、11大类资产 、51每日复盘 、80医药周报、9估值研究 if v.CategoryId == 7 || v.CategoryId == 11 || v.CategoryId == 51 || v.CategoryId == 9 { if v.UpdateFrequency == "daily" { var daystr string daystr = strconv.Itoa(v.PublishDate.Day()) if len(daystr) == 1 { daystr = "0" + daystr } titleNew = v.Title + "(" + strconv.Itoa(v.PublishDate.Year())[2:len(strconv.Itoa(v.PublishDate.Year()))-0] + v.PublishDate.Format("01") + daystr + ")" } else if v.UpdateFrequency == "weekly" { titleNew = v.Title + utils.WeekByDate(v.PublishDate) } } //策略周度思考,医药周报,消费周报,消费周度思考,科技前言(周报)、智造精粹、智造本周荟 标题处理 if v.CategoryId == 80 || v.CategoryId == 52 || v.CategoryId == 10074 || v.CategoryId == 1008 || v.CategoryId == 10071 || v.CategoryId == 10073 || v.CategoryId == 50 { titleNew = v.Title + utils.WeekByDate(v.PublishDate) } //类型是综述报告的,不区分是什么系列,统一归类到对应产业的路演精华 if articleResult.Type.Name == "综述报告" { detailCategory, err := models.GetdetailByCategoryIdLyjh(v.CategoryIdTwo) if err != nil && err.Error() != utils.ErrNoRow() { return err } v.CategoryId = detailCategory.CategoryId matchTypeName = "路演精华" if v.IsClass == 0 { v.IsSummary = 0 } } var chartPermissionId int var chartPermissionName string categoryDetail, _ := models.GetdetailByCategoryIdPush(v.CategoryId) if categoryDetail != nil { chartPermissionId = categoryDetail.ChartPermissionId chartPermissionName = categoryDetail.ChartPermissionName } if count > 0 { fmt.Println(k, v.ArticleId, "edit") articleIfoOld, e := models.GetArticleDetailTestById(v.ArticleId) if e != nil { err = e return } bodyTextOld, _ := GetReportContentTextSubNew(articleIfoOld.Body) bodyText, _ := GetReportContentTextSubNew(v.Body) var isCustom bool updateParams := make(map[string]interface{}) //updateParams["Title"] = v.Title updateParams["Title"] = titleNew updateParams["TitleEn"] = v.TitleEn updateParams["UpdateFrequency"] = v.UpdateFrequency updateParams["CreateDate"] = v.CreateDate updateParams["PublishDate"] = v.PublishDate //updateParams["Body"] = html.EscapeString(v.Body) updateParams["Body"] = html.EscapeString(bodyReturn) updateParams["BodyText"] = bodyText updateParams["Abstract"] = html.EscapeString(v.Abstract) updateParams["CategoryName"] = v.CategoryName for _, vCustom := range listCustomArticle { if v.ArticleId == vCustom.ArticleId { fmt.Println("手动归类的文章:" + strconv.Itoa(v.ArticleId)) isCustom = true } } if isCustom == false { updateParams["CategoryId"] = v.CategoryId updateParams["MatchTypeName"] = matchTypeName updateParams["IsSummary"] = v.IsSummary updateParams["IsReport"] = v.IsReport updateParams["ReportType"] = v.ReportType updateParams["SubCategoryName"] = v.SubCategoryName } //updateParams["CategoryId"] = v.CategoryId updateParams["PublishStatus"] = 1 updateParams["ExpertBackground"] = expertContentStr updateParams["ExpertNumber"] = expertNumStr updateParams["InterviewDate"] = interviewDateStr //updateParams["IsClass"] = v.IsClass v.Department = "弘则权益研究" updateParams["Department"] = v.Department updateParams["FileLink"] = v.File updateParams["Stock"] = v.Stock updateParams["FieldName"] = v.FieldName updateParams["SeriesName"] = v.SeriesName updateParams["Annotation"] = v.Annotation updateParams["TypeName"] = v.TypeName updateParams["ModifyTimeByCl"] = v.UpdateDate updateParams["CeLueFieldId"] = v.CeLueFieldId updateParams["Cover"] = v.Cover updateParams["ChartPermissionId"] = chartPermissionId updateParams["ChartPermissionName"] = chartPermissionName whereParam := map[string]interface{}{"article_id": v.ArticleId} err = models.UpdateByExpr(models.CygxArticle{}, whereParam, updateParams) if err != nil { fmt.Println("UpdateByExpr Err:" + err.Error()) return err } if len(bodyText)-len(bodyTextOld) > 100 { //fmt.Println("触发推送规则") //更新字数大于一百字触发推送规则 go DoArticleOnenIdWxTemplateMsg(v.ArticleId) UpdateArticleResourceData(v.ArticleId) //把数据写入 cygx_resource_data 表 //go UpdateResourceData(v.ArticleId, "article", "update", time.Now().Format(utils.FormatDateTime)) } else { models.UpdatecygxResourceDatasearchTitle(v.Title, v.ArticleId) } } else { fmt.Println(k, v.ArticleId, "add") item := new(models.CygxArticle) articleIdInt := v.ArticleId item.ArticleId = articleIdInt //item.Title = v.Title item.Title = titleNew item.TitleEn = v.TitleEn item.UpdateFrequency = v.UpdateFrequency item.CreateDate = v.CreateDate item.PublishDate = v.PublishDate.Format(utils.FormatDateTime) //item.Body = html.EscapeString(v.Body) item.Body = html.EscapeString(bodyReturn) item.Abstract = html.EscapeString(v.Abstract) item.CategoryName = v.CategoryName item.SubCategoryName = v.SubCategoryName item.CategoryId = v.CategoryId item.CategoryIdTwo = v.CategoryIdTwo item.PublishStatus = 1 item.ExpertBackground = expertContentStr item.ExpertNumber = expertNumStr item.InterviewDate = interviewDateStr item.Department = v.Department item.ArticleIdMd5 = utils.MD5(strconv.Itoa(articleIdInt)) item.IsClass = v.IsClass item.IsSummary = v.IsSummary item.IsReport = v.IsReport item.ReportType = v.ReportType item.FileLink = v.File item.MatchTypeName = matchTypeName item.Stock = v.Stock item.FieldName = v.FieldName item.SeriesName = v.SeriesName item.Annotation = v.Annotation item.TypeName = v.TypeName item.ModifyTimeByCl = v.UpdateDate item.CeLueFieldId = v.CeLueFieldId item.Cover = v.Cover item.ChartPermissionId = chartPermissionId item.ChartPermissionName = chartPermissionName item.Cover = v.Cover item.CreateTime = time.Now() newId, err := models.AddCygxArticles(item) if err != nil { fmt.Println("AddCygxArticle Err:", err.Error()) return err } //go UpdateResourceData(v.ArticleId, "article", "add", time.Now().Format(utils.FormatDateTime)) UpdateArticleResourceData(v.ArticleId) //把数据写入 cygx_resource_data 表 //fmt.Println(newId) //报告自动归类,以及推送相关模板消息 if v.ReportType == 2 { var subjectStr string var industrialManagementIdStr string var industrialSubjectIdStr string var keyword1 string var keyword2 string var keyword3 string var keyword4 string sliceSubjects := strings.Split(v.Stock, "/") mapManagementForSubject := make(map[string]string) mapIndustrialId := make(map[int]int) if len(sliceSubjects) > 0 { for _, vSubject := range sliceSubjects { sliceKuohao := strings.Split(vSubject, "(") //过滤括号 sliceXiahuaxian := strings.Split(sliceKuohao[0], "-") //过滤下划线 subject := sliceXiahuaxian[0] subjectStr += "'" + subject + "'," } //获取该产业下所对应的行业图片 detailCategory, errCategory := models.GetdetailByCategoryIdOne(v.CategoryId) if errCategory != nil { fmt.Println("GetdetailByCategoryIdOne Err:", err.Error()) return err } subjectStr = strings.TrimRight(subjectStr, ",") if subjectStr != "" { listIndustrial, err := models.GetIndustrialManagementForSubjecName(subjectStr, detailCategory.ChartPermissionId) if err != nil { fmt.Println("GetIndustrialManagementForSubjecName Err:", err.Error()) return err } subjectStr = strings.Replace(subjectStr, "','", "】【", -1) subjectStr = strings.Replace(subjectStr, "'", "", -1) subjectStr = "【" + subjectStr + "】" if len(listIndustrial) > 0 { for _, vIndustrial := range listIndustrial { if _, ok := mapIndustrialId[vIndustrial.IndustrialManagementId]; !ok { industrialManagementIdStr += strconv.Itoa(vIndustrial.IndustrialManagementId) + "," } mapIndustrialId[vIndustrial.IndustrialManagementId] = vIndustrial.IndustrialManagementId industrialSubjectIdStr += strconv.Itoa(vIndustrial.IndustrialSubjectId) + "," mapManagementForSubject[vIndustrial.IndustryName] += vIndustrial.SubjectName + "/" if vIndustrial.LayoutTime == "0000-00-00 00:00:00" { go models.UpdateIndustrialManagementLayoutTime(v.PublishDate.AddDate(0, 0, -10).Format(utils.FormatDateTime), vIndustrial.IndustrialManagementId) } } industrialManagementIdStr = strings.TrimRight(industrialManagementIdStr, ",") industrialSubjectIdStr = strings.TrimRight(industrialSubjectIdStr, ",") if industrialManagementIdStr != "" { err = models.ReportArticleClassificationEditNew(int(newId), industrialManagementIdStr, v.ArticleId, industrialSubjectIdStr) if err != nil { fmt.Println("ReportArticleClassificationEditNew Err:", err.Error()) return err } } var peoductName string for mk, mv := range mapManagementForSubject { peoductName += "【" + mk + "--" + strings.TrimRight(mv, "/") + "】" } keyword1 = "新报告产业标签:【" + v.FieldName + "】,个股标签:" + subjectStr keyword2 = "已自动关联至以下产业和标的:" + peoductName keyword3 = v.Title keyword4 = v.PublishDate.Format(utils.FormatDateTime) SendWxMsgWithArticleClassToAdmin(keyword1, keyword2, keyword3, keyword4, openIdList, articleIdInt) } else { keyword1 = "新报告产业标签:【" + v.FieldName + "】,个股标签:" + subjectStr keyword2 = "未归类" keyword3 = v.Title keyword4 = v.PublishDate.Format(utils.FormatDateTime) SendWxMsgWithArticleClassToAdmin(keyword1, keyword2, keyword3, keyword4, openIdList, articleIdInt) go models.UpdateIsClassFail(artcleId) } } } } go DoArticleOnenIdWxTemplateMsg(v.ArticleId) } if v.CategoryName == utils.ZHOU_QI_NAME { UpdateCygxZhouqiArticleMapTime(v.FieldName) //更新周期对应分类下所管理文章的更新时间 } //【公司调研】系列纪要发布/更新后 end //查研观向6.9模板消息推送规则 //但是如果报告的发布时间是在10天以前的,公众号就不推送了 //if time.Now().AddDate(0, 0, -10).Before(articleResult.PublishDate.Add(time.Hour * 8)) { // go DoArticleOnenIdWxTemplateMsg(v.ArticleId) //} } go models.UpdateCygxArticleCeluePush(artcleId) AddComprehensiveArticle(artcleId) // 同步到综合页面的搜索引擎 AddComprehensiveIndustrialSource("Hz", artcleId) // 同步到综合页面的搜索引擎(添加产业资源包) GetSummarytoEs(artcleId) // 同步到ES搜索引擎 GetIndustrialManagementArticleNewPublishData() if len(listArticleData) > 0 { for _, v := range listArticleData { count, err := models.GetCygxArticleDataCount(v.ArticleId) if err != nil { fmt.Println("GetCygxArticleDataCount Err:", err.Error()) return err } if count == 0 { _, err := models.AddCygxArticleData(v) if err != nil { fmt.Println("AddCygxArticleData Err:", err.Error()) return err } } //} else { // updateParams := make(map[string]interface{}) // updateParams["Cover"] = v.Cover // whereParam := map[string]interface{}{"article_id": v.ArticleId} // err = models.UpdateByExpr(models.CygxArticleData{}, whereParam, updateParams) // if err != nil { // fmt.Println("UpdateByExpr CygxArticleData Err:" + err.Error()) // return err // } //} } } AddCygxReportMappingCategoryGroupByArticleId(artcleId) return err } //func init() { // DoArticleOnenIdWxTemplateMsg(8112) //} // 过滤策略平台报告,研选报告重复推送,以及权限勾选的推送 func DoArticleOnenIdWxTemplateMsg(articleId int) { var err error //策略平台同步过来的文章ID,做微信模板消息推送,同一篇报告12小时只推送一次 cacheKey := fmt.Sprint(utils.CACHE_KEY_ARTICLE_ID_TEMPLATE, ":ArticleId", articleId) ttlTime := utils.Rc.GetRedisTTL(cacheKey) if ttlTime > 0 { fmt.Println(ttlTime) return } defer func() { if err != nil { go utils.SendAlarmMsg("过滤策略平台报告,研选报告重复推送,以及权限勾选的推送失败 DoArticleOnenIdWxTemplateMsg ErrMsg:"+err.Error(), 2) fmt.Println(err) } }() //获取文章详情 articleInfo, e := models.GetArticleDetailById(articleId) if e != nil { err = errors.New("GetArticleDetailById, Err: " + e.Error()) return } articleInfo.Abstract, _ = GetReportContentTextSub(articleInfo.Abstract) var chartPermissionId int //固收的权限,暂时当策略的逻辑一样处理 var chartPermissionName string var permissionName string reportMapDetail, e := models.GetdetailByCategoryIdPush(articleInfo.CategoryId) if e != nil { err = errors.New("GetdetailByCategoryIdPush, Err: " + e.Error()) return } permissionName = reportMapDetail.ChartPermissionName if reportMapDetail.ChartPermissionId == utils.CE_LUE_ID { chartPermissionId = utils.CE_LUE_ID } else if reportMapDetail.ChartPermissionId == utils.GU_SHOU_ID_CHART { chartPermissionId = utils.GU_SHOU_ID_CHART } else { if reportMapDetail.PermissionType == 1 { chartPermissionName = reportMapDetail.ChartPermissionName + "(主观)" } else { chartPermissionName = reportMapDetail.ChartPermissionName + "(客观)" } chartPermissionDetail, e := models.GetChartPermissionByRemark(chartPermissionName) if e != nil { err = errors.New("GetdetailByCategoryIdPush, Err: " + e.Error()) return } chartPermissionId = chartPermissionDetail.ChartPermissionId } //文章关联的产业 var industryName string var industrialManagementId string if chartPermissionId == utils.CE_LUE_ID || chartPermissionId == utils.GU_SHOU_ID_CHART { industryName = reportMapDetail.SubCategoryName } // 获取所有有权的用户的 openid //mapOpenidPower := make(map[int]string) permissionIdList := make([]string, 0) var condition string var pars []interface{} slicepermissionId := strings.Split(strconv.Itoa(chartPermissionId), ",") if len(slicepermissionId) > 0 { for _, v := range slicepermissionId { if v == strconv.Itoa(utils.GU_SHOU_ID_CHART) { v = strconv.Itoa(utils.CE_LUE_ID) } permissionIdList = append(permissionIdList, v) } condition += ` AND p.chart_permission_id IN (` + utils.GetOrmInReplace(len(slicepermissionId)) + ` ) ` pars = append(pars, permissionIdList) } openidPowerListMobile, e := models.GetCygxUserRecordPower(condition, pars) if e != nil { err = errors.New("GetCygxUserRecordPower, Err: " + e.Error()) return } //获取拒绝接收推送的的用户的 openid mapOpenidRefuset := make(map[int]string) openidRefusetList, e := models.GetCygxUserRefusetOpenid() if e != nil { err = errors.New("GetCygxUserRefusetOpenid, Err: " + e.Error()) return } for _, v := range openidRefusetList { mapOpenidRefuset[v.UserId] = v.OpenId } var mobileArr []string for _, v := range openidPowerListMobile { mobileArr = append(mobileArr, v.Mobile) } openidPowerList, err := models.GetWxOpenIdByMobileSliceList(mobileArr) if e != nil { err = errors.New("GetWxOpenIdByMobileSliceList, Err: " + e.Error()) return } //四大行业的行业综述报告,对所有开通了对应行业权限的客户都推送。 if articleInfo.ReportType == 1 && permissionName != utils.CE_LUE_NAME && permissionName != utils.GU_SHOU_NAME && permissionName != utils.ZHOU_QI_NAME { keyword1 := "【" + articleInfo.SubCategoryName + "】有报告发布/更新" //openIditem := new(models.OpenIdList) var openIdArr []string for _, item := range openidPowerList { if mapOpenidRefuset[item.UserId] != "" { continue // 拒绝消息推送的用户不接收模版消息 } openIdArr = append(openIdArr, item.OpenId) } go SendWxMsgWithArticleUpdateList(keyword1, articleInfo.Title, articleInfo.PublishDate, articleInfo.Abstract, openIdArr, articleId) return } //for _, v := range openidPowerList { // mapOpenidPower[v.UserId] = v.OpenId //} if permissionName == utils.CE_LUE_NAME || permissionName == utils.GU_SHOU_NAME { celueListUninterested, e := models.GetCygxXzsChooseCategoryListFollowType(articleInfo.CategoryId, 3) if e != nil { err = errors.New("GetCygxXzsChooseCategoryListFollowType " + e.Error()) return } mapUninterestedClue := make(map[int]string) for _, v := range celueListUninterested { mapUninterestedClue[v.UserId] = "_" mapOpenidRefuset[v.UserId] = "_" //归类成拒绝推送的人 } keyword1 := "【" + articleInfo.SubCategoryName + "】有报告发布/更新" var openIdArr []string for _, item := range openidPowerList { if mapOpenidRefuset[item.UserId] != "" { continue // 拒绝消息推送的用户不接收模版消息 } openIdArr = append(openIdArr, item.OpenId) } go SendWxMsgWithArticleUpdateList(keyword1, articleInfo.Title, articleInfo.PublishDate, articleInfo.Abstract, openIdArr, articleId) return } else if permissionName == utils.ZHOU_QI_NAME { if articleInfo.SeriesName == "" { articleInfo.SeriesName = articleInfo.FieldName } zhouqiListUninterested, e := models.GetCygxXzsChooseCategoryZhouqiListFollowType(articleInfo.FieldName, articleInfo.SeriesName, 3) if e != nil { err = errors.New("GetCygxXzsChooseCategoryListFollowType " + e.Error()) return } mapUninterestedClue := make(map[int]string) for _, v := range zhouqiListUninterested { mapUninterestedClue[v.UserId] = "_" mapOpenidRefuset[v.UserId] = "_" //归类成拒绝推送的人 } keyword1 := "【" + articleInfo.SubCategoryName + "】有报告发布/更新" var openIdArr []string for _, item := range openidPowerList { if mapOpenidRefuset[item.UserId] != "" { continue // 拒绝消息推送的用户不接收模版消息 } openIdArr = append(openIdArr, item.OpenId) } go SendWxMsgWithArticleUpdateList(keyword1, articleInfo.Title, articleInfo.PublishDate, articleInfo.Abstract, openIdArr, articleId) return } else { //if articleInfo.ReportType == 2 { detailIndustryNameList, e := models.GetIndustrialManagemenDetailByAaticleID(articleId) if e != nil { err = errors.New("GetIndustrialManagemenDetailByAaticleID, Err: " + e.Error()) return } //如果不存在关联的产业则不推送 if len(detailIndustryNameList) == 0 { return } else { var industrialIds []int for _, v := range detailIndustryNameList { industrialIds = append(industrialIds, v.IndustrialManagementId) } var conditionFollow string var parsFollow []interface{} //根据产业关注ID,获取用户不感兴趣的产业信息 conditionFollow = " AND industrial_management_id IN (" + utils.GetOrmInReplace(len(industrialIds)) + ") AND follow_type = 3 " parsFollow = append(parsFollow, industrialIds) userFllowListUninterested, e := models.GetCygxIndustryFllowListByCon(conditionFollow, parsFollow) if e != nil { err = errors.New("GetCygxIndustryFllowList, Err: " + e.Error()) return } var userFllowNum = make(map[int]int) for _, v := range userFllowListUninterested { userFllowNum[v.UserId]++ //如果活动对应的产业数量,跟用户不感兴趣的产业数量一致,就不做推送 if userFllowNum[v.UserId] == len(detailIndustryNameList) { mapOpenidRefuset[v.UserId] = "_" } } } for _, v := range detailIndustryNameList { industryName += v.IndustryName + "," industrialManagementId += strconv.Itoa(v.IndustrialManagementId) + "," } industryName = strings.TrimRight(industryName, ",") industrialManagementId = strings.TrimRight(industrialManagementId, ",") //} keyword1 := fmt.Sprint("【", industryName, "】有报告发布/更新") keyword2 := articleInfo.Title keyword3 := time.Now().Format(utils.FormatDateTime) keyword4 := articleInfo.Abstract sliceSubjectId, _ := models.GetSubjectIds(articleId) var appointmentList []*models.CygxAppointment var mapOpenidSubjectId = make(map[int]string) //预约相关纪要的用户 if sliceSubjectId != "" { appointmentList, e = models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId) if e != nil { err = errors.New("GetCygxAppointmentSummaryBySubjectId, Err: " + e.Error()) return } var userIds []string if len(appointmentList) > 0 { for _, v := range appointmentList { userIds = append(userIds, strconv.Itoa(v.UserId)) } userIdstr := strings.Join(userIds, ",") openIdLists, e := models.GetOpenIdByUserIds(userIdstr) if e != nil { err = errors.New("GetOpenIdByUserIds, Err: " + e.Error()) return } keyword1 = industryName var openIdArr []string for _, item := range openIdLists { if mapOpenidRefuset[item.UserId] != "" { continue // 拒绝消息推送的用户不接收模版消息 } openIdArr = append(openIdArr, item.OpenId) mapOpenidSubjectId[item.UserId] = "_" } go SendWxMsgWithArticleUpdateList(industryName, keyword2, keyword3, keyword4, openIdArr, articleId) } } var openIdArr2 []string for _, item := range openidPowerList { if mapOpenidRefuset[item.UserId] != "" || mapOpenidSubjectId[item.UserId] != "" { continue // 拒绝消息推送的用户不接收模版消息 } openIdArr2 = append(openIdArr2, item.OpenId) } go SendWxMsgWithArticleUpdateList(keyword1, keyword2, keyword3, keyword4, openIdArr2, articleId) } ////获取关注这个文章对应产业的用户的 openid //mapOpenidFllow := make(map[int]string) //if chartPermissionId != utils.CE_LUE_ID && chartPermissionId != utils.GU_SHOU_ID_CHART && chartPermissionId != utils.ZHOU_QI_ID { // openidFllowListMobile, e := models.GetCygxUserFllowOpenid(articleId) // if e != nil { // err = errors.New("GetCygxUserFllowOpenid, Err: " + e.Error()) // return // } // // var mobileArrFllow []string // for _, v := range openidFllowListMobile { // mobileArrFllow = append(mobileArrFllow, v.Mobile) // } // // openidFllowList, e := models.GetWxOpenIdByMobileSliceList(mobileArrFllow) // if e != nil { // err = errors.New("GetWxOpenIdByMobileSliceList, Err: " + e.Error()) // return // } // // for _, v := range openidFllowList { // mapOpenidFllow[v.UserId] = v.OpenId // } //} // ////获取提交过推送规则的用户的 openid //mapUserIdChooseSend := make(map[int]int) //mapUserIdChooseSendTypeNoPermission := make(map[int]int) //chooseSendtList, e := models.GetCygxXzsChooseSend() //if e != nil { // err = errors.New("GetCygxXzsChooseSend, Err: " + e.Error()) // return //} //for _, v := range chooseSendtList { // mapUserIdChooseSend[v.UserId] = v.UserId // if v.IsRefuse == 1 { // continue // } // //获取选择主客观赛道的用户 // if reportMapDetail.PermissionType == 1 { // if v.IsSubjective == 1 { // mapUserIdChooseSendTypeNoPermission[v.UserId] = v.UserId // } // } else { // if v.IsObjective == 1 { // mapUserIdChooseSendTypeNoPermission[v.UserId] = v.UserId // } // } //} ////已经推送了的openid //mapOpenidPushed := make(map[int]string) // //keyword2 := articleInfo.Title //keyword3 := time.Now().Format(utils.FormatDateTime) //keyword4 := articleInfo.Abstract //mapAlreadySend := make(map[int]int) // //sliceSubjectId, _ := models.GetSubjectIds(articleId) //var appointmentList []*models.CygxAppointment //if sliceSubjectId != "" { // appointmentList, e = models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId) // if e != nil { // err = errors.New("GetCygxAppointmentSummaryBySubjectId, Err: " + e.Error()) // return // } // //var userIds []string // //if len(appointmentList) > 0 { // // for _, v := range appointmentList { // // //fmt.Println("mapActivityUserId:", v.UserId) // // userIds = append(userIds, strconv.Itoa(v.UserId)) // // mapActivityUserId[v.UserId] += v.ActivityName + "," // // } // // userIdstr := strings.Join(userIds, ",") // // openIdLists, err := models.GetOpenIdByUserIds(userIdstr) // // if err != nil { // // fmt.Println("GetOpenIdByUserIds Err:", err.Error()) // // return err // // } // // for _, item := range openIdLists { // // //first := "您预约的调研,有关联的纪要发布/更新了" // // //keyword1 := industryName // // openIditem := new(models.OpenIdList) // // openIditem.OpenId = item.OpenId // // openIditem.UserId = item.UserId // // if _, ok := mapAlreadySend[openIditem.UserId]; !ok { // // SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId) // // delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId) // // fmt.Println("AlreadySend:", openIditem.UserId) // // mapAlreadySend[openIditem.UserId] = openIditem.UserId // // } // // } // //} //} ////如果是策略就按照策略的推送方式来写 //if reportMapDetail.ChartPermissionName == utils.CE_LUE_NAME || reportMapDetail.ChartPermissionName == utils.GU_SHOU_NAME { // //获取提交过推送规则的用户的 openid // mapUserFllowCeLue := make(map[int]string) // userFllowCeLueList, e := models.GetCygxUserFllowCeLueOpenid(articleInfo.CategoryId) // if e != nil { // err = errors.New("GetCygxUserFllowCeLueOpenid, Err: " + e.Error()) // return // } // for _, v := range userFllowCeLueList { // mapUserFllowCeLue[v.UserId] = v.OpenId // } // for k, v := range mapOpenidPower { // if mapOpenidPushed[k] != "" { // continue // } // openIditem := new(models.OpenIdList) // openIditem.UserId = k // openIditem.OpenId = v // first := "您关注的赛道,有新的报告发布/更新,欢迎查看" // keyword1 := "【" + articleInfo.SubCategoryName + "】有报告发布/更新" // mapActivityUserId := make(map[int]string) // if articleInfo.ReportType == 2 { // sliceSubjectId, _ = models.GetSubjectIds(articleId) // if sliceSubjectId != "" { // appointmentList, e = models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId) // if e != nil { // err = errors.New("GetCygxAppointmentSummaryBySubjectId, Err: " + e.Error()) // return // } // var userIds []string // if len(appointmentList) > 0 { // for _, v := range appointmentList { // //fmt.Println("mapActivityUserId:", v.UserId) // userIds = append(userIds, strconv.Itoa(v.UserId)) // mapActivityUserId[v.UserId] += v.ActivityName + "," // } // userIdstr := strings.Join(userIds, ",") // openIdLists, e := models.GetOpenIdByUserIds(userIdstr) // appointmentList, e = models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId) // if e != nil { // err = errors.New("GetCygxAppointmentSummaryBySubjectId, Err: " + e.Error()) // return // } // for _, item := range openIdLists { // first = "您预约的调研,有关联的纪要发布/更新了" // keyword1 = industryName // openIditem = new(models.OpenIdList) // openIditem.OpenId = item.OpenId // openIditem.UserId = item.UserId // if _, ok := mapAlreadySend[openIditem.UserId]; !ok { // SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId) // delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId) // fmt.Println("AlreadySend:", openIditem.UserId) // mapAlreadySend[openIditem.UserId] = openIditem.UserId // } // } // } // } // } // _, ok := mapAlreadySend[openIditem.UserId] // //如果有权限而且小助手没有提交过信息的 就做正常推送 // if mapUserIdChooseSend[openIditem.UserId] == 0 && !ok { // fmt.Println("1:", articleId) // SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId) // } // //如果小助手勾选了对应的权限信息 就做正常推送 // if mapUserIdChooseSend[openIditem.UserId] != 0 && mapUserFllowCeLue[openIditem.UserId] != "" && !ok { // fmt.Println("2:", articleId) // SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId) // } // } //} else { // for k, v := range mapOpenidPower { // if mapOpenidPushed[k] != "" { // continue // } // mapUserIdChooseSendType := make(map[int]int) // for _, vS := range chooseSendtList { // if vS.IsRefuse == 1 { // continue // } // //获取选择主客观赛道的用户 // if reportMapDetail.PermissionType == 1 { // if vS.IsSubjective == 1 { // mapUserIdChooseSendType[vS.UserId] = vS.UserId // } // } else if reportMapDetail.PermissionType == 2 { // if vS.IsObjective == 1 { // mapUserIdChooseSendType[vS.UserId] = vS.UserId // } // } else { // if vS.IsSubjective == 1 || vS.IsObjective == 1 { // mapUserIdChooseSendType[vS.UserId] = vS.UserId // } // } // } // openIditem := new(models.OpenIdList) // openIditem.UserId = k // openIditem.OpenId = v // first := "您关注的赛道,有新的报告发布/更新,欢迎查看" // keyword1 := "【" + articleInfo.SubCategoryName + "】有报告发布/更新" // mapActivityUserId := make(map[int]string) // if articleInfo.ReportType == 2 { // keyword1 = fmt.Sprint("【", industryName, "】有报告发布/更新") // //sliceSubjectId, _ = models.GetSubjectIds(articleId) // if sliceSubjectId != "" { // //appointmentList, e = models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId) // //if e != nil { // // err = errors.New("GetCygxAppointmentSummaryBySubjectId, Err: " + e.Error()) // // return // //} // var userIds []string // if len(appointmentList) > 0 { // for _, v := range appointmentList { // //fmt.Println("mapActivityUserId:", v.UserId) // userIds = append(userIds, strconv.Itoa(v.UserId)) // mapActivityUserId[v.UserId] += v.ActivityName + "," // } // userIdstr := strings.Join(userIds, ",") // openIdLists, e := models.GetOpenIdByUserIds(userIdstr) // if e != nil { // err = errors.New("GetOpenIdByUserIds, Err: " + e.Error()) // return // } // for _, item := range openIdLists { // //first := "您预约的调研,有关联的纪要发布/更新了" // //keyword1 := industryName // openIditem := new(models.OpenIdList) // openIditem.OpenId = item.OpenId // openIditem.UserId = item.UserId // if _, ok := mapAlreadySend[openIditem.UserId]; !ok { // SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId) // delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId) // fmt.Println("AlreadySend:", openIditem.UserId) // mapAlreadySend[openIditem.UserId] = openIditem.UserId // } // } // } // } // } // // //如果有权限而且小助手没有提交过信息的 就做正常推送 // _, ok := mapAlreadySend[openIditem.UserId] // if mapUserIdChooseSend[openIditem.UserId] == 0 && !ok { // SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId) // delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId) // mapAlreadySend[openIditem.UserId] = openIditem.UserId // } // //如果小助手勾选了对应的权限信息 就做正常推送 // if mapUserIdChooseSend[openIditem.UserId] != 0 && mapOpenidFllow[openIditem.UserId] != "" && mapUserIdChooseSendType[openIditem.UserId] > 0 && !ok { // SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId) // delete(mapUserIdChooseSendTypeNoPermission, openIditem.UserId) // mapAlreadySend[openIditem.UserId] = openIditem.UserId // } // } //} utils.Rc.Put(cacheKey, articleId, time.Hour*12) return } // GetSpecialArticleDetailUserPower 处理用户查看专项调研文章详情的权限 func GetSpecialArticleDetailUserPower(user *models.WxUserItem, articleInfo *models.ArticleDetail) (havePower bool, err error) { userType, _, e := GetUserType(user.CompanyId) if e != nil { err = errors.New("GetSpecialUserType, Err: " + e.Error()) return } // 永续客户、大套餐客户可以查看行业升级套餐客户 权限 if userType == 1 || userType == 2 { havePower = true return } permissionStr, e := GetCompanyPermissionUpgrade(user.CompanyId) if e != nil { err = errors.New("GetCompanyPermissionUpgrade, Err: " + e.Error()) return } reportMapDetail, e := models.GetdetailByCategoryIdPush(articleInfo.CategoryId) if e != nil { err = errors.New("GetdetailByCategoryIdPush, Err: " + e.Error()) return } if reportMapDetail == nil { err = errors.New("GetdetailByCategoryIdP,获取详情失败, ") return } fmt.Println(permissionStr) //如果没有对应的升级权限,则返回 if !strings.Contains(permissionStr, reportMapDetail.ChartPermissionName) { return } else { havePower = true } return } // HandleArticleCategoryImg 预处理文章的封面图片 func HandleArticleCategoryImg(list []*models.HomeArticle) (items []*models.HomeArticle, err error) { //研选的五张图片 detailResearch, e := models.GetConfigByCode("category_research_img_url") if e != nil { err = errors.New("获取研选的五张图片失败" + e.Error()) return } researchList := strings.Split(detailResearch.ConfigValue, "{|}") //对应分类的所图片 detailCategoryUrl, err := models.GetConfigByCode("category_map_img_url") if err != nil { err = errors.New("获取对应分类的所图片失败" + err.Error()) return } categoryUrlList := strings.Split(detailCategoryUrl.ConfigValue, "{|}") mapCategoryUrl := make(map[string]string) var categoryId string var imgUrlChart string for _, v := range categoryUrlList { vslice := strings.Split(v, "_") categoryId = vslice[0] imgUrlChart = vslice[len(vslice)-1] mapCategoryUrl[categoryId] = imgUrlChart } mapChartPerssion := make(map[string]string) reportMappingList, err := models.GetReportMappingStrategyAll() if err != nil { err = errors.New("GetReportMappingStrategyAll err" + err.Error()) return } for _, v := range reportMappingList { mapChartPerssion[strconv.Itoa(v.CategoryId)] = v.ChartPermissionName } for k, v := range list { list[k].Abstract, _ = GetReportContentTextSub(v.Abstract) item := list[k] //如果文章一开始的内容是图片,优先展示第一张图片 if list[k].Annotation == "" { imgurl, _ := FixArticleImgUrl(html.UnescapeString(list[k].Body)) if imgurl != "" { list[k].BodyHtml = imgurl } } //newBody, _ := GetReportContentTextSubByarticle(item.Body, item.Annotation, item.ArticleId) list[k].Annotation = ArticleAnnotation(item) list[k].Body = "" list[k].PublishDate = utils.StrTimeToTime(item.PublishDate).Format(utils.FormatDate) //时间字符串格式转时间格式 list[k].ChartPermissionName = mapChartPerssion[v.CategoryId] //如果是研选系列的任意取五张图片的中的一张 if v.CategoryId == "0" || v.ArticleId > utils.SummaryArticleId { knum := v.ArticleId % 5 list[k].ImgUrlPc = researchList[knum] } else { list[k].ImgUrlPc = mapCategoryUrl[v.CategoryId] } list[k].ArticleResponse = 4 // 默认展示核心观点 //ArticleResponse int `description:"报告类型 0:啥也不是,1研选报告,2:研选纪要,3:研选沙龙,4;核心观点"` if list[k].ArticleId >= utils.SummaryArticleId { list[k].HttpUrl = utils.StrategyPlatform + strconv.Itoa(v.ArticleId) list[k].IsNeedJump = true list[k].ArticleResponse = 1 //if v.IsReport == 1 { // list[k].ArticleResponse = 1 //} else if v.ArticleTypeName == "纪要" { // list[k].ArticleResponse = 2 //} else if v.ArticleTypeName == "观点" { // list[k].ArticleResponse = 3 //} else if v.ArticleTypeName == "沙龙" { // list[k].ArticleResponse = 3 //} else if v.ArticleTypeName == "路演精华" { // list[k].ArticleResponse = 1 //} } list[k].Source = 1 //添加行业默认图片 if v.ImgUrlPc == "" { if v.ChartPermissionName == utils.YI_YAO_NAME { list[k].ImgUrlPc = utils.YI_YAO_OTHER_IMG } else if v.ChartPermissionName == utils.XIAO_FEI_NAME { list[k].ImgUrlPc = utils.XIAO_FEI_OTHER_IMG } else if v.ChartPermissionName == utils.KE_JI_NAME { list[k].ImgUrlPc = utils.KE_JI_OTHER_IMG } else if v.ChartPermissionName == utils.ZHI_ZAO_NAME { list[k].ImgUrlPc = utils.ZHI_ZAO_OTHER_IMG } } //是不是研选报告 if v.ArticleTypeId > 0 { list[k].IsResearch = true } } articleIds := make([]int, 0) for i := range list { articleIds = append(articleIds, list[i].ArticleId) } articleMapPv := GetArticleHistoryByArticleId(articleIds) //文章Pv // 报告关联产业信息 industryMap := make(map[int][]*models.IndustrialManagementIdInt, 0) if len(articleIds) > 0 { var industryCond string var industryPars []interface{} industryCond += ` AND mg.article_id IN (` + utils.GetOrmInReplace(len(articleIds)) + `)` industryPars = append(industryPars, articleIds) industryList, e := models.GetIndustrialListByarticleId(industryPars, industryCond) if e != nil { err = errors.New("GetIndustrialListByarticleId" + e.Error()) return } for i := range industryList { v := industryList[i] industryMap[v.ArticleId] = append(industryMap[v.ArticleId], &models.IndustrialManagementIdInt{ ArticleId: v.ArticleId, IndustrialManagementId: v.IndustrialManagementId, IndustryName: v.IndustryName, ChartPermissionId: v.ChartPermissionId, }) } } for k, v := range list { if len(industryMap[v.ArticleId]) > 0 { list[k].List = industryMap[v.ArticleId] } else { list[k].List = make([]*models.IndustrialManagementIdInt, 0) } v.Pv = articleMapPv[v.ArticleId] if v.Pv > 999 { list[k].Pv = 999 } } if len(list) == 0 { list = make([]*models.HomeArticle, 0) } items = list return } // 处理核心观点的展示规则 func ArticleAnnotation(item *models.HomeArticle) (annotation string) { if item.ArticleId >= utils.SummaryArticleId { item.Annotation = YxArticleAnnotation(item) } if item.Annotation != "" { annotation = strings.Replace(item.Annotation, "
", "", -1) annotation = strings.Replace(item.Annotation, " ", "", -1) } else { return } bodyText, _ := GetReportContentTextSubNew(annotation) if bodyText == "" { return } if annotation != "" { annotation = html.UnescapeString(annotation) doc, _ := goquery.NewDocumentFromReader(strings.NewReader(annotation)) docText := doc.Text() mapDoc := make(map[int]string) var mapSort []int p := doc.Find("p") p.Each(func(tk int, pd *goquery.Selection) { pdText := pd.Text() pdText = strings.Replace(pdText, " ", "", -1) if pdText != "" { textLen := strings.Index(docText, pdText) mapDoc[(strings.Index(docText, pdText))] = pdText mapSort = append(mapSort, textLen) } }) li := doc.Find("li") li.Each(func(tk int, li *goquery.Selection) { liText := li.Text() liText = strings.Replace(liText, " ", "", -1) if liText != "" { textLen := strings.Index(docText, liText) mapDoc[(strings.Index(docText, liText))] = strconv.Itoa(tk+1) + "." + liText mapSort = append(mapSort, textLen) } }) ul := doc.Find("ul") ul.Each(func(tk int, ul *goquery.Selection) { ulText := ul.Text() ulText = strings.Replace(ulText, " ", "", -1) if ulText != "" { textLen := strings.Index(docText, ulText) mapDoc[(strings.Index(docText, ulText))] = ulText mapSort = append(mapSort, textLen) } }) if len(mapSort) == 0 { return } else { //排序 sort.Ints(mapSort) var annotationHtml string for _, vSort := range mapSort { for k, v := range mapDoc { if k == vSort && v != "" { annotationHtml += v + "
" } } } annotationHtml = strings.TrimRight(annotationHtml, "
") annotationHtml = "

" + annotationHtml + "

" annotation = annotationHtml } } return } // 处理核心观点的展示规则 func AnnotationHtml(bodyText string) (annotation string) { if bodyText == "" { return } annotation = bodyText annotation = html.UnescapeString(annotation) doc, _ := goquery.NewDocumentFromReader(strings.NewReader(annotation)) docText := doc.Text() mapDoc := make(map[int]string) var mapSort []int p := doc.Find("p") p.Each(func(tk int, pd *goquery.Selection) { pdText := pd.Text() //pdText = strings.Replace(pdText, " ", "", -1) if pdText != "" { textLen := strings.Index(docText, pdText) mapDoc[(strings.Index(docText, pdText))] = pdText mapSort = append(mapSort, textLen) } }) li := doc.Find("li") li.Each(func(tk int, li *goquery.Selection) { liText := li.Text() liText = strings.Replace(liText, " ", "", -1) if liText != "" { textLen := strings.Index(docText, liText) mapDoc[(strings.Index(docText, liText))] = strconv.Itoa(tk+1) + "." + liText mapSort = append(mapSort, textLen) } }) ul := doc.Find("ul") ul.Each(func(tk int, ul *goquery.Selection) { ulText := ul.Text() ulText = strings.Replace(ulText, " ", "", -1) if ulText != "" { textLen := strings.Index(docText, ulText) mapDoc[(strings.Index(docText, ulText))] = ulText mapSort = append(mapSort, textLen) } }) section := doc.Find("section") section.Each(func(tk int, section *goquery.Selection) { sectionText := section.Text() sectionText = strings.Replace(sectionText, " ", "", -1) if sectionText != "" { textLen := strings.Index(docText, sectionText) mapDoc[(strings.Index(docText, sectionText))] = sectionText mapSort = append(mapSort, textLen) } }) if len(mapSort) == 0 { return } else { //排序 sort.Ints(mapSort) var annotationHtml string for _, vSort := range mapSort { for k, v := range mapDoc { if k == vSort && v != "" { annotationHtml += v + "
" } } } annotationHtml = strings.TrimRight(annotationHtml, "
") annotationHtml = "

" + annotationHtml + "

" annotation = annotationHtml } return } // 处理产品内测展示规则 func ProductInteriorHtml(bodyText string) (annotation string) { if bodyText == "" { return } sliceBody := strings.Split(bodyText, "

") annotation, _ = GetReportContentTextSub(sliceBody[0]) return } // 解析研选内容中的核心观点 func YxArticleAnnotation(article *models.HomeArticle) (annotation string) { //如果不规范,就获取内容主体 if strings.Count(article.Body, "", "") body = strings.ReplaceAll(body, "", "") body = strings.ReplaceAll(body, "", "") body = strings.ReplaceAll(body, "
    ", "
    ") body = strings.ReplaceAll(body, "", "

    ") body = strings.ReplaceAll(body, "
  1. ", "

    ") re, _ := regexp.Compile("") body = re.ReplaceAllString(body, "") reLi, _ := regexp.Compile("") body = reLi.ReplaceAllString(body, "") var plus int coreIndex := strings.Index(body, "核心观点:") plus = 15 if coreIndex == -1 { coreIndex = strings.Index(body, "核心观点:") plus = 13 } if coreIndex == -1 { coreIndex = strings.Index(body, "核心观点") plus = 12 } if coreIndex == -1 { coreIndex = strings.Index(body, "核心结论:") plus = 15 } if coreIndex == -1 { coreIndex = strings.Index(body, "核心结论:") plus = 13 } if coreIndex == -1 { coreIndex = strings.Index(body, "核心结论") plus = 12 } endIndex := strings.Index(body, " 0 { articleInfo, errArt := models.GetArticleDetailById(linkArticleId) if errArt != nil && errArt.Error() != utils.ErrNoRow() { err = errArt return } if articleInfo != nil { articleId = articleInfo.ArticleId } } } } return } // GetArticleStockMap 获取个股标签所对应的文章ID func GetArticleStockMap() (mapResp map[string]int, err error) { defer func() { if err != nil { go utils.SendAlarmMsg("获取个股标签所对应的文章ID失败"+err.Error(), 2) } }() list, err := models.GetArticleStock() if err != nil && err.Error() != utils.ErrNoRow() { return } mapResp = make(map[string]int, 0) if len(list) > 0 { //一对一精准匹配 for _, v := range list { sliceSubjects := strings.Split(v.Stock, "/") if len(sliceSubjects) > 0 { for _, vSubject := range sliceSubjects { sliceKuohao := strings.Split(vSubject, "(") //过滤括号 sliceXiahuaxian := strings.Split(sliceKuohao[0], "-") //过滤下划线 subject := sliceXiahuaxian[0] mapResp[subject] = v.ArticleId } } } } return } // GetAiQianYanArtilceList 获取AI前沿几篇文章 func GetAiQianYanArtilceList(startSize, pageSize int) (items []*models.ReportArticle, total int, err error) { defer func() { if err != nil { go utils.SendAlarmMsg("获取AI前沿几篇文章失败"+err.Error(), 2) } }() var condition string var pars []interface{} condition += ` AND title LIKE '%AI前沿%' AND publish_status = 1 ORDER BY publish_date DESC ` articleList, e := models.GetCygxCygxArticleList(condition, pars, startSize, pageSize) if e != nil { err = errors.New("GetCygxCygxArticleList, Err: " + e.Error()) return } total, e = models.GetCygxArticleCount(condition, pars) if e != nil { err = errors.New("GetCygxArticleCount, Err: " + e.Error()) return } for _, v := range articleList { item := new(models.ReportArticle) item.ArticleId = v.ArticleId item.Title = v.Title item.Abstract = v.Abstract item.Annotation = v.Annotation item.PublishDate = v.PublishDate item.Resource = 1 item.CategoryId = strconv.Itoa(v.CategoryId) item.Body = v.Body items = append(items, item) } return } // 获取文章内部图表的第一张封面图 func GetArticleCoverByChartFirst(body string) (cover string) { var err error defer func() { if err != nil { fmt.Println(err) go utils.SendAlarmMsg("获取文章内部图表的第一张封面图失败,Err:"+err.Error()+body, 3) } }() var chartUrl string var hrefRegexp = regexp.MustCompile(utils.RegularUrl) match := hrefRegexp.FindAllString(body, -1) if match != nil { for _, v := range match { if strings.Contains(v, "charts/display") { chartUrl = v break } } } if chartUrl != "" { urlSlice := strings.Split(chartUrl, "/") lenurlSlice := len(urlSlice) sourceId, _ := strconv.Atoi(urlSlice[lenurlSlice-1]) if sourceId == 0 { sourceId, _ = strconv.Atoi(urlSlice[lenurlSlice-2]) } if sourceId == 0 { err = errors.New("新的图标链接无法解析" + chartUrl) return } chartUrlApi := utils.ApiUrl + "charts/" + strconv.Itoa(sourceId) authorization := utils.ApiAuthorization body, e := PublicGetDate(chartUrlApi, authorization) if e != nil { err = errors.New("PublicGetDate" + err.Error()) return } var resultDate models.ChartResultDetailApi e = json.Unmarshal(body, &resultDate) if e != nil { err = errors.New(" json.Unmarshal" + err.Error()) } cover = resultDate.Data.Cover } return } // GetYxArticleIdMap 获取研选文章ID func GetYxArticleIdMap(articleIds []int) (mapResp map[int]bool) { var err error defer func() { if err != nil { go utils.SendAlarmMsg("获取研选文章ID失败,GetYxArticleIdMap"+err.Error(), 2) } }() var condition string var pars []interface{} condition = ` AND article_type_id > 0 ` if len(articleIds) > 0 { condition += ` AND article_id IN (` + utils.GetOrmInReplace(len(articleIds)) + `)` pars = append(pars, articleIds) } articleList, e := models.GetArticleList(condition, pars) if e != nil { err = errors.New("GetArticleList, Err: " + e.Error()) return } mapResp = make(map[int]bool, 0) for _, v := range articleList { mapResp[v.ArticleId] = true } return } // GetUserArticleHistoryRecord 获取用户已经阅读的文章ID func GetUserArticleHistoryRecord(user *models.WxUserItem) (articleIdMap map[int]bool, err error) { var condition string var pars []interface{} condition = " AND user_id = ? " pars = append(pars, user.UserId) articleIdMap = make(map[int]bool, 0) list, err := models.GetArticleHistoryRecord(condition, pars) if err != nil && err.Error() != utils.ErrNoRow() { return } for _, v := range list { articleIdMap[v.ArticleId] = true } return } // GetUserArticleHistoryIndustrialNewPublishDate 获取产业关联的的文章用户是否阅读 func GetUserArticleHistoryIndustrialNewPublishDate(user *models.WxUserItem, industrialIdArr []int, articleTypeIds, resource string) (mapIndustrialArticleHistory map[int]bool, err error) { if len(industrialIdArr) == 0 { return } var condition string var pars []interface{} articleIdMap, err := GetUserArticleHistoryRecord(user) if err != nil { return } if resource == utils.REOURCE_YX { condition = ` AND a.publish_status = 1 AND a.article_type_id IN (` + articleTypeIds + `) ` } else { condition = ` AND a.article_type_id = 0 AND a.article_id < ` + strconv.Itoa(utils.SummaryArticleId) } var startTime time.Time if utils.StrTimeToTime(utils.OnlineTime).After(user.CreatedTime) { startTime = utils.StrTimeToTime(utils.OnlineTime) } else { startTime = user.CreatedTime } condition += ` AND mg.industrial_management_id IN (` + utils.GetOrmInReplace(len(industrialIdArr)) + `) AND a.publish_date > ? ` pars = append(pars, industrialIdArr, startTime) list, err := models.GetCygxIndustrialArticleGroupManagement(condition, pars) if err != nil { return } mapIndustrialArticle := make(map[int][]*models.CygxIndustrialArticleGroupManagementResp) //mapIndustrialArticleMax := make(map[int]int, 0) mapIndustrialArticleHistory = make(map[int]bool, 0) //mapIndustrialArticleMaxTime := make(map[int]time.Time) for _, v := range list { item := new(models.CygxIndustrialArticleGroupManagementResp) item.IndustrialManagementId = v.IndustrialManagementId item.ArticleId = v.ArticleId item.PublishDate = v.PublishDate mapIndustrialArticle[v.IndustrialManagementId] = append(mapIndustrialArticle[v.IndustrialManagementId], item) } for k, v := range mapIndustrialArticle { for _, item := range v { if !articleIdMap[item.ArticleId] { mapIndustrialArticleHistory[k] = true } } } return }