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, "<p class=\"ql-align-justify\">", "&nbsp;", -1)
	contentSub = strings.Replace(contentSub, "</p>", "", -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, "<p data-f-id=\"pbf\" style=\"text-align: center; font-size: 14px; margin-top: 30px; opacity: 0.65; font-family: sanered by <a href=\"https://www.froala.com/wysiwyg-editor?pb=1\" title=\"Froala Editor\">Froala Editor</a></p>", "", -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()
			record.Mobile = v.Mobile
			if mapUserCompany[v.Mobile] != nil {
				mapUser := mapUserCompany[v.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 init() {
//	tiemStart := utils.StrTimeToTime("2025-01-01")
//	if time.Now().After(tiemStart) {
//		fmt.Println("同步")
//	}
//}

//func init() {
//	HandleArticleListByApi(12448)
//}

// 处理同步过来的文章
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
	}

	var isSynchronous bool // 有些报告可以自定义同步，满足这个条件就同步过去
	if articleResult.Series.Name == "周度首席说" && articleResult.PublishDate.After(utils.StrTimeToTime("2025-01-01")) {
		isSynchronous = true
	}
	//fmt.Println("isSynchronous", isSynchronous)
	//fmt.Println(cover)
	//return
	//状态等于 2 跟 4 的进行同步 IsActive 为false 软删除的也不同步
	if exitMap[articleResult.SeriesId] > 0 && (articleResult.PublishStatus == 2 || articleResult.PublishStatus == 4) && articleResult.IsActive || isSynchronous {
		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)

							for _, vIndustrial := range listIndustrial {
								IndustrialManagementTimeLineDateList3(vIndustrial.IndustrialManagementId) // 更新时间线报告内容
							}

						} 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 {
		if v.CompanyId == utils.JMCJ_COMPANY_ID {
			continue //需求池 1043：深圳进门财经科技股份有限公司下所有的账号，所有活动的新增修改都做推送，所有的报告的新增修改都不做推送。
		}
		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 v.SubCategoryName == "宏观G2观察" {
			list[k].Title = "【宏观G2观察】" + v.Title
		}
	}

	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, "<br>", "", -1)
		annotation = strings.Replace(item.Annotation, "&nbsp;", "", -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 + "<br>"
					}
				}
			}
			annotationHtml = strings.TrimRight(annotationHtml, "<br>")
			annotationHtml = "<p>" + annotationHtml + "</p>"
			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 + "<br>"
				}
			}
		}
		annotationHtml = strings.TrimRight(annotationHtml, "<br>")
		annotationHtml = "<p>" + annotationHtml + "</p>"
		annotation = annotationHtml
	}
	return
}

// 处理产品内测展示规则
func ProductInteriorHtml(bodyText string) (annotation string) {
	if bodyText == "" {
		return
	}
	sliceBody := strings.Split(bodyText, "</p>")
	annotation, _ = GetReportContentTextSub(sliceBody[0])
	return
}

// 解析研选内容中的核心观点
func YxArticleAnnotation(article *models.HomeArticle) (annotation string) {
	//如果不规范，就获取内容主体
	if strings.Count(article.Body, "<hr") == 0 {
		//如果内容不规范而且，还有图片，就把核心观点置空
		if article.BodyHtml != "" {
			return
		}
		annotation, _ = GetReportContentTextSub(article.Body)
		return
	}
	body := strings.ReplaceAll(article.Body, "<strong>", "")
	body = strings.ReplaceAll(body, "</strong>", "")
	body = strings.ReplaceAll(body, "</ol>", "</div>")
	body = strings.ReplaceAll(body, "<ol>", "<div>")
	body = strings.ReplaceAll(body, "</li>", "</p>")
	body = strings.ReplaceAll(body, "<li>", "<p>")
	re, _ := regexp.Compile("<strong.*?>")
	body = re.ReplaceAllString(body, "")
	reLi, _ := regexp.Compile("<li.*?>")
	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, "<hr")
	if coreIndex != -1 && endIndex != -1 {
		body = body[coreIndex+plus : endIndex]
	}
	annotation = body
	return
}

// 通过接解析带有Md5的文章链接获取文章ID
func GetReportLinkToArticleid(reportLink string) (articleId int, err error) {
	defer func() {
		if err != nil {
			go utils.SendAlarmMsg("通过接解析带有Md5的文章链接获取文章ID失败"+err.Error(), 2)
		}
	}()
	var artMd5 string
	//处理Md5的
	strnum1 := strings.Index(reportLink, "id=")
	if strnum1 > 0 {
		sliceId := strings.Split(reportLink, "id=")
		if len(sliceId) > 1 {
			reportLink = sliceId[1]
			sliceMd5Id := strings.Split(reportLink, "&")
			artMd5 = sliceMd5Id[0]
		}
		if artMd5 != "" {
			detail, errArt := models.GetArticleDetailByIdMd5(artMd5)
			if errArt != nil && errArt.Error() != utils.ErrNoRow() {
				err = errArt
				return
			}
			if detail != nil {
				articleId = detail.ArticleId
			}
		}
	} else {
		//处理活动的
		linkList := strings.Split(reportLink, "/")
		if linkList[len(linkList)-1] != "" {
			linkArticleId, _ := strconv.Atoi(linkList[len(linkList)-1])
			if linkArticleId > 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
}
