package services

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/beego/beego/v2/client/orm"
	"hongze/hongze_cygx/models"
	"hongze/hongze_cygx/utils"
	"html"
	"net/url"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

func GetReportContentSub(content string) (contentSub string, err error) {
	content = html.UnescapeString(content)
	doc, err := goquery.NewDocumentFromReader(strings.NewReader(content))
	if err != nil {
		fmt.Println("create doc err:", err.Error())
		return
	}
	n := 0
	doc.Find("p").Each(func(i int, s *goquery.Selection) {
		if n > 3 {
			return
		}
		n++
		phtml, err := s.Html()
		if err != nil {
			fmt.Println("get html err", err.Error())
			return
		}
		if s.Text() != "" || strings.Contains(phtml, "src") {
			contentSub = contentSub + "<p>" + phtml + "</p>"
		}
	})
	return
}

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 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
}

// GetReportContentTextSubByarticle 解析文章内容
func GetReportContentTextSubByarticle(content, abstract string, articleId int) (contentSub string, err error) {
	var lenabstract int
	//如果不是研选就这么展示
	if articleId < utils.SummaryArticleId {
		abstract = html.UnescapeString(abstract)
		doc, errdoc := goquery.NewDocumentFromReader(strings.NewReader(abstract))
		if errdoc != nil {
			err = errdoc
			return
		}
		docabstract := doc.Text()
		lenabstract = utf8.RuneCountInString(docabstract)
		if lenabstract >= 20 {
			contentSub = docabstract
			return
		} else {
			contentSub, err = GetReportContentTextSubNew(content)
		}
	} else {
		contentSub, err = GetReportContentTextSubNew(content)
	}

	return

}

// 解析文章内容
func GetArticleAll() {
	var err error
	defer func() {
		if err != nil {
			fmt.Println("err:", err.Error())
			return
		}
	}()
	list, err := models.GetArticleAll()
	if err != nil {
		return
	}
	for _, v := range list {
		fmt.Println(v.ArticleId, v.Title)
		FixArticleContent(v.ArticleId)
	}
}

// 解析报告
func FixArticleContent(articleId int) {
	item, err := models.GetArticleDetailById(articleId)
	if err != nil {
		fmt.Println("GetArticleDetailById Err:" + err.Error())
		return
	}
	content := item.Body
	bodyText, _ := GetReportContentTextSub(content)
	content = html.UnescapeString(content)

	content = strings.Replace(content, "http", "https", -1)

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(content))
	if err != nil {
		fmt.Println("create doc err:", err.Error())
		return
	}

	var expertNumArr []string
	var expertContentArr []string
	var interviewDateArr []string

	doc.Find("p").Each(func(i int, s *goquery.Selection) {
		contentTxt := s.Text()
		if strings.Contains(contentTxt, "#访谈时间：") || strings.Contains(contentTxt, "访谈时间：") {
			interviewDate := s.Next().Text()
			interviewDateArr = append(interviewDateArr, interviewDate)
		}
		if strings.Contains(contentTxt, "#专家评价") || strings.Contains(contentTxt, "专家评价") {
			expertContent := s.Next().Text()
			if expertContent == "" {
				expertContent = contentTxt
			}
			if expertContent != "" {
				rightIndex := strings.Index(expertContent, "）")
				if rightIndex == 0 {
					rightIndex = strings.Index(expertContent, ")")
				}
				if rightIndex > 0 {
					expertNum := expertContent[:rightIndex]
					expertNum = strings.Replace(expertNum, "（", "", -1)
					expertNum = strings.Replace(expertNum, "(", "", -1)
					expertNum = strings.Replace(expertNum, "专家评价", "", -1)
					if expertNum != "" {
						expertNumArr = append(expertNumArr, expertNum)
						rightIndex = rightIndex
						expertContentStr := expertContent[rightIndex:]
						expertContentStr = strings.Replace(expertContentStr, "）", "", -1)
						expertContentStr = strings.TrimLeft(expertContentStr, "：")
						expertContentStr = strings.TrimRight(expertContentStr, "（推荐")
						expertContentArr = append(expertContentArr, expertContentStr)
					}
				}
			}
		}
	})

	if len(expertContentArr) <= 0 {
		doc.Find("pre").Each(func(i int, pre *goquery.Selection) {
			pre.Find("span").Each(func(n int, span *goquery.Selection) {
				contentTxt := span.Text()
				if strings.Contains(contentTxt, "#专家评价") || strings.Contains(contentTxt, "专家评价") {
					span.Find("span").Each(func(m int, subspan *goquery.Selection) {
						subspanText := subspan.Text()
						if strings.Contains(subspanText, "专家评价") {
							expertContent := subspan.Next().Text()
							if expertContent != "" {
								rightIndex := strings.Index(expertContent, "）")
								if rightIndex == 0 {
									rightIndex = strings.Index(expertContent, ")")
								}
								if rightIndex > 0 {
									expertNum := expertContent[:rightIndex]
									expertNum = strings.Replace(expertNum, "（", "", -1)
									expertNum = strings.Replace(expertNum, "(", "", -1)
									expertNum = strings.Replace(expertNum, "专家评价", "", -1)
									if expertNum != "" {
										expertNumArr = append(expertNumArr, expertNum)
										rightIndex = rightIndex
										expertContentStr := expertContent[rightIndex:]
										expertContentStr = strings.Replace(expertContentStr, "）", "", -1)
										expertContentStr = strings.TrimLeft(expertContentStr, "：")
										expertContentStr = strings.TrimRight(expertContentStr, "（推荐")
										expertContentArr = append(expertContentArr, expertContentStr)
									}
								}
							}
						}

					})
				}

				span.Find("span").Each(func(k int, sspan *goquery.Selection) {
					sspanText := sspan.Text()
					if strings.Contains(sspanText, "访谈时间") {
						sspanText = strings.Replace(sspanText, "#访谈时间：", "", -1)
						sspanText = strings.Replace(sspanText, "访谈时间：", "", -1)
						sspanText = strings.Replace(sspanText, "\n", "", -1)
						sspanText = strings.Replace(sspanText, " ", "", -1)
						sspanText = strings.Trim(sspanText, " ")
						sspanText = sspanText[:10]
						interviewDate := sspanText
						if interviewDate != "" {
							interviewDateArr = append(interviewDateArr, interviewDate)
						}
					}
				})
			})
		})
	}

	if len(expertContentArr) <= 0 {
		doc.Find("span").Each(func(i int, span *goquery.Selection) {
			span.Find("strong").Each(func(n int, strong *goquery.Selection) {
				spanText := span.Text()
				strongText := strong.Text()
				if strings.Contains(strongText, "#专家评价") || strings.Contains(strongText, "专家评价") {
					expertContent := strong.Parents().Text()
					if expertContent != "" {
						rightIndex := strings.Index(expertContent, "）")
						if rightIndex == 0 {
							rightIndex = strings.Index(expertContent, ")")
						}
						if rightIndex > 0 {
							expertNum := expertContent[:rightIndex]
							expertNum = strings.Replace(expertNum, "（", "", -1)
							expertNum = strings.Replace(expertNum, "(", "", -1)
							expertNum = strings.Replace(expertNum, "专家评价", "", -1)
							expertNum = strings.Replace(expertNum, "#", "", -1)
							expertNum = strings.Replace(expertNum, "：", "", -1)
							expertNum = strings.Replace(expertNum, "\n", "", -1)
							if expertNum != "" {
								expertNumArr = append(expertNumArr, expertNum)
								rightIndex = rightIndex
								expertContentStr := expertContent[rightIndex:]
								expertContentStr = strings.Replace(expertContentStr, "）", "", -1)
								expertContentStr = strings.TrimLeft(expertContentStr, "：")
								expertContentStr = strings.TrimRight(expertContentStr, "（推荐")
								expertContentArr = append(expertContentArr, expertContentStr)
								return
							}
						}
					}
				}

				if strings.Contains(spanText, "访谈时间") {
					spanText = strings.Replace(spanText, "#访谈时间：", "", -1)
					spanText = strings.Replace(spanText, "访谈时间：", "", -1)
					spanText = strings.Replace(spanText, "\n", "", -1)
					spanText = strings.Replace(spanText, " ", "", -1)
					spanText = strings.Trim(spanText, " ")
					spanText = spanText[:10]
					interviewDate := spanText
					if interviewDate != "" {
						interviewDateArr = append(interviewDateArr, interviewDate)
					}
				}
			})
		})
	}

	var expertNumStr, expertContentStr, interviewDateStr string
	if len(expertNumArr) > 0 {
		expertNumStr = expertNumArr[0]
	}
	if len(expertContentArr) > 0 {
		expertContentStr = expertContentArr[0]
	}

	if len(interviewDateArr) > 0 {
		interviewDateStr = interviewDateArr[0]
	}
	expertNumStr = strings.Replace(expertNumStr, "#：", "", -1)
	err = models.ModifyArticleExpert(articleId, expertNumStr, expertContentStr, interviewDateStr, bodyText)
	if err != nil {
		fmt.Println("ModifyArticleExpert Err:" + err.Error())
		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 FixArticleFirstCount(body string) (contentSub string, err error) {

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(body))
	if err != nil {
		fmt.Println("create doc err:", err.Error())
		return
	}
	doc.Find("p").Each(func(i int, s *goquery.Selection) {
		contentTxt := s.Text()
		fmt.Println(contentTxt)
	})
	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("同步结束")
}

// 统计报表
func StatisticalReport() {
	var isSummaryNumAll, isClassNum, pvNumAll, uvNumAll int
	list, err := models.GetChartPermissionActivity()
	if err != nil {
		fmt.Println("获取列表失败", err)
	}
	for _, v := range list {
		var listPv []*models.ReportMappingStatistical
		if v.PermissionName == "研选" {
			listPv, err = models.GetStatisticalReportArtilceExpert()
			if err != nil {
				fmt.Println("获取Pv列表失败", err)
			}
		} else {
			listPv, err = models.GetStatisticalReportArtilce(v.ChartPermissionId)
			if err != nil {
				fmt.Println("获取Pv列表失败", err)
			}
		}
		var pvNum, uvNum, isSummaryNum int
		for _, v2 := range listPv {
			pvNum += v2.Pv
			uvNum += v2.Uv
			if v2.IsSummary == "1" {
				isSummaryNum += 1
			}
			if v2.IsClass == "1" && v.ChartPermissionId <= 22 {
				isClassNum += 1
			}
			if v2.IsSummary == "1" && v.ChartPermissionId <= 22 {
				isSummaryNumAll += 1
			}
		}
		if v.ChartPermissionId <= 22 {
			pvNumAll += pvNum
			uvNumAll += uvNum
		}
		fmt.Println(v.PermissionName+"行业", len(listPv), "篇，其中主观类报告", isSummaryNum, "篇，客观类报告", len(listPv)-isSummaryNum, "篇。共产生阅读量pv-,", pvNum, "，uv-", uvNum)
	}
	fmt.Println("目前同步四大行业的总报告（已归类）数量", isClassNum, "篇，其中主观类报告", isSummaryNumAll, "篇，客观类报告", isClassNum-isSummaryNumAll, "篇。共产生阅读量pv-", pvNumAll, "，uv-", uvNumAll)
	var totalOnline int        //线上
	var totalOffline int       //线下
	var totalPeople int        //共累计预约外呼人数
	var totalSignUpOff int     //线下报名人数
	var totalSignUpOffTime int //线下报名人数
	var totalPeopleMeet int    //线下参会人数
	o := orm.NewOrm()
	sql := `SELECT COUNT(1) FROM cygx_activity WHERE activity_type_id IN (1,2,3) AND publish_status = 1 AND is_submit_meeting = 1 AND activity_time <= NOW();`
	err = o.Raw(sql).QueryRow(&totalOnline)
	if err != nil {
		fmt.Println("获取线上", err)
	}
	sql = `SELECT COUNT(1) FROM cygx_activity WHERE activity_type_id IN (4,5,6) AND publish_status = 1 AND is_submit_meeting = 1 	AND activity_time <= NOW();`
	err = o.Raw(sql).QueryRow(&totalOffline)
	if err != nil {
		fmt.Println("获取线下", err)
	}
	sql = `SELECT COUNT( 1 ) FROM
			cygx_activity_signup  as s 
			INNER JOIN cygx_activity as a ON  a.activity_id = s.activity_id
		WHERE
			s.do_fail_type = 0
			AND a.is_submit_meeting = 1
			AND a.activity_time <= NOW()
			AND a.publish_status = 1`
	err = o.Raw(sql).QueryRow(&totalPeople)
	if err != nil {
		fmt.Println("共累计预约外呼人数", err)
	}

	sql = `SELECT COUNT( 1 ) FROM
			cygx_activity_signup  as s 
			INNER JOIN cygx_activity as a ON  a.activity_id = s.activity_id
		WHERE
			s.do_fail_type = 0
			AND a.is_submit_meeting = 1
			AND a.activity_time <= NOW()
			AND a.activity_type_id IN (4,5,6)
			AND a.publish_status = 1`
	err = o.Raw(sql).QueryRow(&totalSignUpOff)
	if err != nil {
		fmt.Println("共累计预约外呼人数", err)
	}

	sql = `SELECT COUNT( 1 ) FROM
			cygx_activity_signup  as s 
			INNER JOIN cygx_activity as a ON  a.activity_id = s.activity_id
		WHERE
			s.do_fail_type = 0
			AND a.publish_status = 1
			AND a.is_submit_meeting = 1
			AND a.activity_time <= NOW()
			AND a.is_submit_meeting = 1
			AND a.activity_type_id IN (4,5,6);`
	err = o.Raw(sql).QueryRow(&totalSignUpOffTime)
	if err != nil {
		fmt.Println("线下报名参会人数", err)
	}

	sql = `SELECT COUNT( 1 ) FROM
			cygx_activity_signup  as s 
			INNER JOIN cygx_activity as a ON  a.activity_id = s.activity_id
		WHERE
			s.do_fail_type = 0
			AND a.is_submit_meeting = 1
			AND a.activity_time <= NOW()
			AND a.publish_status = 1
			AND s.is_meeting = 1
			AND a.activity_type_id IN (4,5,6);`
	err = o.Raw(sql).QueryRow(&totalPeopleMeet)
	if err != nil {
		fmt.Println("线下参会人数", err)
	}

	fmt.Println("共上线活动", totalOnline+totalOffline, "个，其中线上", totalOnline, "个，线下", totalOffline, "个")
	fmt.Println("共累计预约外呼人数", totalPeople, "人")
	fmt.Println("报名线下参会", totalSignUpOff, "人，实际到会人数", totalPeopleMeet, "人，线下到会率约", totalPeopleMeet*100/totalSignUpOff, "%")

	num := totalPeopleMeet / totalSignUpOffTime
	fmt.Println(num)
	fmt.Println(totalOnline)
	fmt.Println(totalOffline)
	fmt.Println(totalPeople)
	fmt.Println(totalSignUpOff)
	fmt.Println(totalPeopleMeet)
	fmt.Println(totalSignUpOffTime)
	fmt.Println(totalPeopleMeet / totalSignUpOffTime)
	return

}

// 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() {
//	sum := 0
//	for i := 0; i <= 450; i++ {
//		if i >= 102 {
//			//GetCeLueArticlePvs(strconv.Itoa(i * 1000))
//		}
//	}
//	fmt.Println(sum)
//}

// 获取策略平台报告阅读数据
func GetCeLueArticlePv(cont context.Context) (err error) {
	defer func() {
		if err != nil {
			go utils.SendAlarmMsg("同步策略平台阅读数据失败", 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
		}
	}
	for _, v := range chartResult.Data {
		//fmt.Println(v.ArticleId)
		item := new(models.CygxCelueArticleHistoryRecord)
		item.CelueHistoryId = v.CelueHistoryId
		item.Mobile = v.Mobile
		item.ArticleId = v.ArticleId
		if v.CrmUser != nil {
			item.RealName = v.CrmUser.RealName
		}
		if v.CompanyName != nil {
			item.CompanyName = v.CompanyName.RealName
		}
		item.CreateDateApi = time.Now()
		t1, _ := time.Parse("2006-01-02T15:04:05Z", v.CreateDate)
		item.CreateTime = t1.Add(+time.Hour * 8).Format(utils.FormatDateTime)
		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
			}
		}
	}

	//处理同步过来的阅读记录所属用户
	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() {
//	// allList, err := models.GetArticleAll()
//	//
//	// fmt.Println(err)
//	//
//	//	for _, v := range allList {
//	//		HandleArticleListByApi(v.ArticleId)
//	//	}
//
//	//for i := 8648; i < 9004; i++ {
//	//	HandleArticleListByApi(9552)
//	//}
//	HandleArticleListByApi(10914)
//	//UpdateArticleResourceData(9551)
//}

// 处理同步过来的文章
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.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 {
			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
			v.IsSummary = 0
		}

		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)
			if len(bodyText)-len(bodyTextOld) > 100 {
				//fmt.Println("触发推送规则")
				//更新字数大于一百字触发推送规则
				go DoArticleOnenIdWxTemplateMsg(v.ArticleId)
				go UpdateArticleResourceData(v.ArticleId) //把数据写入 cygx_resource_data 表
				//go UpdateResourceData(v.ArticleId, "article", "update", time.Now().Format(utils.FormatDateTime))
			}
			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["Annotation"] = v.Annotation
			updateParams["TypeName"] = v.TypeName
			updateParams["ModifyTimeByCl"] = v.UpdateDate
			updateParams["CeLueFieldId"] = v.CeLueFieldId
			updateParams["Cover"] = v.Cover
			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
			}

		} 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.Annotation = v.Annotation
			item.TypeName = v.TypeName
			item.ModifyTimeByCl = v.UpdateDate
			item.CeLueFieldId = v.CeLueFieldId
			item.Cover = v.Cover
			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))
			go 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)
		}

		//【公司调研】系列纪要发布/更新后 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) (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 err
	}
	var msg string
	defer func() {
		if err != nil {
			go utils.SendAlarmMsg("过滤策略平台报告，研选报告重复推送，以及权限勾选的推送失败 DoArticleOnenIdWxTemplateMsg  ErrMsg:"+err.Error(), 2)
			fmt.Println(err)
		}
		if msg != "" {
			utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
		}
	}()

	//获取文章详情
	articleInfo, err := models.GetArticleDetailById(articleId)
	if err != nil {
		return
	}
	articleInfo.Abstract, _ = GetReportContentTextSub(articleInfo.Abstract)
	var chartPermissionId int

	//固收的权限，暂时当策略的逻辑一样处理
	var chartPermissionName string
	reportMapDetail, err := models.GetdetailByCategoryIdPush(articleInfo.CategoryId)
	if err != nil {
		return err
	}
	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, err := models.GetChartPermissionByRemark(chartPermissionName)
		if err != nil {
			return err
		}
		chartPermissionId = chartPermissionDetail.ChartPermissionId
	}

	//文章关联的产业
	var industryName string
	var industrialManagementId string
	if chartPermissionId == utils.CE_LUE_ID || chartPermissionId == utils.GU_SHOU_ID_CHART {
		industryName = reportMapDetail.SubCategoryName
	} else {
		if articleInfo.ReportType == 2 {
			detailIndustryNameList, err := models.GetIndustrialManagemenDetailByAaticleID(articleId)
			if err != nil && err.Error() != utils.ErrNoRow() {
				return err
			}
			//如果不存在关联的产业则不推送
			if len(detailIndustryNameList) == 0 {
				return err
			}
			for _, v := range detailIndustryNameList {
				industryName += v.IndustryName + ","
				industrialManagementId += strconv.Itoa(v.IndustrialManagementId) + ","
			}
			industryName = strings.TrimRight(industryName, ",")
			industrialManagementId = strings.TrimRight(industrialManagementId, ",")

			//处理勾选了全部行业赛道的用户
			var allIn string
			allIn = DoXzsChooseSend(reportMapDetail.ChartPermissionName)
			if allIn != "" {
				allInList, err := models.GetCygxXzsChooseSendByAllIn(allIn)
				if err != nil && err.Error() != utils.ErrNoRow() {
					return err
				}
				if len(allInList) > 0 {
					var allInUserId string
					for _, v := range allInList {
						allInUserId += strconv.Itoa(v.UserId) + ","
					}
					allInUserId = strings.TrimRight(allInUserId, ",")

					userFllowIndustrialList, err := models.GetUserFllowIndustrialListByUserIdAndIndustrial(allInUserId, industrialManagementId)
					if err != nil && err.Error() != utils.ErrNoRow() {
						return err
					}
					mapUserFllowed := make(map[string]int)
					for _, v := range userFllowIndustrialList {
						//用户ID与其关注的产业组成唯一索引，判断是否存在，如果不存在就进行自动关注
						mapUserFllowed[fmt.Sprint("uid:", v.UserId, "_Industrial:", v.IndustrialManagementId)] = v.UserId
					}
					//获取这些allIN用户的的信息进行遍历生成需要插入的数据
					userList, err := models.GetWxUserListByUserIds(allInUserId)
					if err != nil && err.Error() != utils.ErrNoRow() {
						return err
					}
					var industryFllowItems []*models.CygxIndustryFllow
					for _, v := range detailIndustryNameList {
						for _, vUser := range userList {
							//如果用户这个用户没有关注这个产业就进行自动关注
							if mapUserFllowed[fmt.Sprint("uid:", vUser.UserId, "_Industrial:", v.IndustrialManagementId)] == 0 {
								item := new(models.CygxIndustryFllow)
								item.IndustrialManagementId = v.IndustrialManagementId
								item.UserId = vUser.UserId
								item.Email = vUser.Email
								item.Mobile = vUser.Mobile
								item.RealName = vUser.RealName
								item.CompanyId = vUser.CompanyId
								item.CompanyName = vUser.CompanyName
								item.Source = 3
								item.Type = 1
								item.CreateTime = time.Now()
								item.ModifyTime = time.Now()
								industryFllowItems = append(industryFllowItems, item)
							}
						}
					}
					err = models.AddCygxIndustryFllowMulti(industryFllowItems)
					if err != nil {
						go utils.SendAlarmMsg("用户关注全部赛道，出现新赛道批量添加失败 ，AddCygxIndustryFllowMulti ErrMsg:"+err.Error(), 2)
					}
				}
			}
		}
	}

	// 获取所有有权的用户的 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, err := models.GetCygxUserRecordPower(condition, pars)
	if err != nil {
		return err
	}

	var mobileArr []string
	for _, v := range openidPowerListMobile {
		mobileArr = append(mobileArr, v.Mobile)
	}
	openidPowerList, err := models.GetWxOpenIdByMobileSliceList(mobileArr)
	if err != nil {
		return err
	}

	//四大行业的行业综述报告，对所有开通了对应行业权限的客户都推送。
	if articleInfo.ReportType == 1 && chartPermissionId != utils.CE_LUE_ID && chartPermissionId != utils.GU_SHOU_ID_CHART {
		for _, item := range openidPowerList {
			first := "您关注的赛道，有新的报告发布/更新，欢迎查看"
			keyword1 := "【" + articleInfo.SubCategoryName + "】有报告发布/更新"
			openIditem := new(models.OpenIdList)
			openIditem.OpenId = item.OpenId
			openIditem.UserId = item.UserId
			SendWxMsgWithArticleUpdate(first, keyword1, articleInfo.Title, articleInfo.PublishDate, articleInfo.Abstract, openIditem, articleId)
		}
		return err
	}
	for _, v := range openidPowerList {
		mapOpenidPower[v.UserId] = v.OpenId
	}
	//获取关注这个文章对应产业的用户的 openid
	mapOpenidFllow := make(map[int]string)
	if chartPermissionId != utils.CE_LUE_ID && chartPermissionId != utils.GU_SHOU_ID_CHART {
		openidFllowListMobile, err := models.GetCygxUserFllowOpenid(articleId)
		if err != nil {
			return err
		}

		var mobileArrFllow []string
		for _, v := range openidFllowListMobile {
			mobileArrFllow = append(mobileArrFllow, v.Mobile)
		}

		openidFllowList, err := models.GetWxOpenIdByMobileSliceList(mobileArrFllow)
		if err != nil {
			return err
		}

		for _, v := range openidFllowList {
			mapOpenidFllow[v.UserId] = v.OpenId
		}

	}

	//获取拒绝接收推送的的用户的 openid
	mapOpenidRefuset := make(map[int]string)
	openidRefusetList, err := models.GetCygxUserRefusetOpenid()
	if err != nil {
		return err
	}
	for _, v := range openidRefusetList {
		mapOpenidRefuset[v.UserId] = v.OpenId
	}
	//获取提交过推送规则的用户的 openid
	mapUserIdChooseSend := make(map[int]int)
	mapUserIdChooseSendTypeNoPermission := make(map[int]int)
	chooseSendtList, err := models.GetCygxXzsChooseSend()
	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)
	//如果是策略就按照策略的推送方式来写
	if reportMapDetail.ChartPermissionName == utils.CE_LUE_NAME || reportMapDetail.ChartPermissionName == utils.GU_SHOU_NAME {
		//获取提交过推送规则的用户的 openid
		mapUserFllowCeLue := make(map[int]string)
		userFllowCeLueList, err := models.GetCygxUserFllowCeLueOpenid(articleInfo.CategoryId)
		if err != nil {
			return err
		}
		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, err := models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId)
					if err != nil {
						fmt.Println("GetCygxAppointmentSummaryListBySubjectId Err:", err.Error())
						return err
					}
					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
							}
						}
					}
				}
				//fmt.Println("openIditem.UserId:", openIditem.UserId)
				//if _,ok := mapActivityUserId[openIditem.UserId]; ok{
				//	first = "您预约的调研，有关联的纪要发布/更新了"
				//	keyword1 = industryName
				//	SendWxMsgWithArticleUpdate(first, keyword1, keyword2, keyword3, keyword4, openIditem, articleId)
				//	delete(mapUserIdChooseSendTypeNoPermission, 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, err := models.GetCygxAppointmentSummaryBySubjectId(sliceSubjectId)
					if err != nil {
						fmt.Println("GetCygxAppointmentSummaryListBySubjectId Err:", err.Error())
						return err
					}
					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
							}
						}
					}
				}
			}

			//如果有权限而且小助手没有提交过信息的 就做正常推送
			_, 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
}

//func init() {
//	GetArticNewLabelWhithActivity3Month()
//}

// 弘则报告发布日期在三个月以内的
func GetArticNewLabelWhithActivity3Month() (labelMap map[int]bool, err error) {
	var condition string
	var pars []interface{}
	condition += ` AND publish_date  <= ?  AND article_id < ? `
	pars = append(pars, time.Now().AddDate(0, -3, 0), utils.SummaryArticleId)
	articleList, e := models.GetArticleList(condition, pars)
	if e != nil {
		err = errors.New("GetArticleList, Err: " + e.Error())
		return
	}
	var articleIds []int
	for _, v := range articleList {
		articleIds = append(articleIds, v.ArticleId)
	}
	if len(articleIds) == 0 {
		return
	}

	pars = make([]interface{}, 0)
	condition = ` AND article_id IN (` + utils.GetOrmInReplace(len(articleIds)) + `)`
	pars = append(pars, articleIds)
	industrialList, e := models.GetIndustrialArticleGroupManagementList(condition, pars)
	if e != nil {
		err = errors.New("GetIndustrialArticleGroupManagementList, Err: " + e.Error())
		return
	}
	labelMap = make(map[int]bool, 0)
	var industrialIds []int
	for _, v := range industrialList {
		industrialIds = append(industrialIds, v.IndustrialManagementId)
	}
	// 获取活动关联的产业
	var groupCond string
	var groupPars []interface{}
	groupCond += ` AND b.industrial_management_id IN (` + utils.GetOrmInReplace(len(industrialIds)) + `)  AND b.source = 1  `
	groupPars = append(groupPars, industrialIds)
	groups, e := models.GetActivityIndustryRelationList(groupCond, groupPars)
	if e != nil {
		err = errors.New("获取活动产业关联列表失败, Err: " + e.Error())
		return
	}
	for _, v := range groups {
		labelMap[v.ActivityId] = 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, "<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 init() {
//	strss := AnnotationHtml("")
//
//	fmt.Println(strss)
//}

// 处理核心观点的展示规则
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
}

//func init() {
//
//	//listarticle, err := models.GetArticleInit13_5()
//	//fmt.Println(err)
//	//fmt.Println("listarticle", len(listarticle))
//	//
//	//for _, v := range listarticle {
//	//	HandleArticleListByApiInit13_5(v.ArticleId)
//	//}
//	//HandleArticleListByApiInit13_5(10825)
//
//	listarticle, err := models.GetArticleInit13_5GuSHou()
//	fmt.Println(err)
//	fmt.Println("listarticle", len(listarticle))
//
//	for _, v := range listarticle {
//		HandleArticleListByApiInit13_5GuShou(v.ArticleId)
//	}
//
//}

// 处理同步过来的文章
func HandleArticleListByApiInit13_5(artcleId int) (err error) {
	defer func() {
		if err != nil {
			go utils.SendAlarmMsg("处理同步策略平台数据失败"+"GetArticleListByApi ErrMsg:"+err.Error()+"artcleId："+strconv.Itoa(artcleId), 2)
			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "GetArticleListByApi ErrMsg:"+err.Error()+"artcleId："+strconv.Itoa(artcleId), utils.EmailSendToUsers)
		}
	}()
	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)

	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
	}

	//新旧分类 反向隐射,是否归类,是否是报告,是否是纪要库
	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

		fmt.Println("item.CategoryIdTwo", item.CategoryIdTwo)
		fmt.Println("item.CategoryId", item.CategoryId)

		{
			//这两种情况特殊处理
			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.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
	}

	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 := "" //非纪要库类型的文章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 {
			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
			v.IsSummary = 0
		}

		if count > 0 {
			fmt.Println(k, v.ArticleId, "edit")

			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["Annotation"] = v.Annotation
			updateParams["TypeName"] = v.TypeName
			updateParams["ModifyTimeByCl"] = v.UpdateDate
			updateParams["CeLueFieldId"] = v.CeLueFieldId
			updateParams["Cover"] = v.Cover
			//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
			//}
			fmt.Println("v.ReportType", v.ReportType)

			//if v.ReportType == 2 {
			var subjectStr string
			var industrialManagementIdStr string
			var industrialSubjectIdStr 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(artcleId, industrialManagementIdStr, v.ArticleId, industrialSubjectIdStr)
							if err != nil {
								fmt.Println("ReportArticleClassificationEditNew Err:", err.Error())
								return err
							}
						}
					}
					//}
				}
			}

		}
	}

	AddComprehensiveIndustrialSource("Hz", artcleId) // 同步到综合页面的搜索引擎（添加产业资源包）

	AddCygxReportMappingCategoryGroupByArticleId(artcleId)
	return err
}

func HandleArticleListByApiInit13_5GuShou(artcleId int) (err error) {
	defer func() {
		if err != nil {
			go utils.SendAlarmMsg("处理同步策略平台数据失败"+"GetArticleListByApi ErrMsg:"+err.Error()+"artcleId："+strconv.Itoa(artcleId), 2)
			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "GetArticleListByApi ErrMsg:"+err.Error()+"artcleId："+strconv.Itoa(artcleId), utils.EmailSendToUsers)
		}
	}()
	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)

	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
	}

	//新旧分类 反向隐射,是否归类,是否是报告,是否是纪要库
	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

		fmt.Println("item.CategoryIdTwo", item.CategoryIdTwo)
		fmt.Println("item.CategoryId", item.CategoryId)

		{
			//这两种情况特殊处理
			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.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
	}

	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 := "" //非纪要库类型的文章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 {
			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
			v.IsSummary = 0
		}

		if count > 0 {
			fmt.Println(k, v.ArticleId, "edit")

			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["Annotation"] = v.Annotation
			updateParams["TypeName"] = v.TypeName
			updateParams["ModifyTimeByCl"] = v.UpdateDate
			updateParams["CeLueFieldId"] = v.CeLueFieldId
			updateParams["Cover"] = v.Cover
			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
			}
			fmt.Println("v.ReportType", v.ReportType)

			if v.ReportType == 2 {
				var subjectStr string
				var industrialManagementIdStr string
				var industrialSubjectIdStr 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(artcleId, industrialManagementIdStr, v.ArticleId, industrialSubjectIdStr)
								if err != nil {
									fmt.Println("ReportArticleClassificationEditNew Err:", err.Error())
									return err
								}
							}
						}
						//}
					}
				}

			}
		}
	}

	AddComprehensiveIndustrialSource("Hz", artcleId) // 同步到综合页面的搜索引擎（添加产业资源包）

	AddCygxReportMappingCategoryGroupByArticleId(artcleId)
	return err
}
