Jelajahi Sumber

Merge branch 'cygx_12.0' of http://8.136.199.33:3000/hongze/hongze_cygx

xingzai 1 tahun lalu
induk
melakukan
df54d3b9d7

+ 2 - 1
controllers/banner.go

@@ -121,10 +121,11 @@ func (this *BannerController) ListYx() {
 	listA = []*models.BannerUrlYxResp{
 		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/1.png", Path: "pages-purchaser/leaflet/leaflet?leafletImage=https%3A%2F%2Fhzstatic.hzinsights.com%2Fcygx%2Fconfig%2Fresearch_11_0.png"},
 		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/2.png", Path: "pages-purchaser/survey/surveySubmit"},
+		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/4.png", Path: "pages-purchaser/specialColumn/specialColumn"},
 	}
 
 	listB = []*models.BannerUrlYxResp{
-		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/3.png", Path: "/index/"},
+		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/3.png", Path: "pages-purchaser/researchList/researchList"},
 	}
 	resp.ListA = listA
 	resp.ListB = listB

+ 35 - 4
controllers/research.go

@@ -727,7 +727,7 @@ func (this *ResearchController) ArticleNewList() {
 	var conditiontype string
 	var pars []interface{}
 	condition = `    AND publish_status = 1  `
-	if articleTypeIds == "" {
+	if articleTypeIds == "" || strings.Contains(articleTypeIds, "999") {
 		conditiontype = " AND is_show_yanx  = 1 "
 	} else {
 		conditiontype = ` AND   group_id IN  (` + articleTypeIds + `) `
@@ -738,19 +738,29 @@ func (this *ResearchController) ArticleNewList() {
 		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
 		return
 	}
+	needYanxuanSpecial := true
+	if articleTypeIds != "" && !strings.Contains(articleTypeIds, "999") {
+		needYanxuanSpecial = false
+	}
+
+	//只勾选了研选专栏时去掉文章的统计
+	if articleTypeIds == "999" {
+		condition += ` AND 1<0 `
+	}
 	articleTypeIds = ""
 	for _, v := range listType {
 		articleTypeIds += strconv.Itoa(v.ArticleTypeId) + ","
 	}
 	articleTypeIds = strings.TrimRight(articleTypeIds, ",")
 	condition += `   AND a.article_type_id IN (` + articleTypeIds + `) `
-	total, err := models.GetArticleResearchCount(condition, pars)
+
+	total, err := models.GetArticleResearchCount(condition, pars, needYanxuanSpecial)
 	if err != nil {
 		br.Msg = "获取信息失败"
 		br.ErrMsg = "GetArticleResearchCount,Err:" + err.Error()
 		return
 	}
-	list, err := models.GetArticleResearchList(condition, pars, startSize, pageSize, user.UserId)
+	list, err := models.GetArticleResearchList(condition, pars, startSize, pageSize, user.UserId, needYanxuanSpecial)
 	if err != nil {
 		br.Msg = "获取信息失败"
 		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
@@ -790,16 +800,37 @@ func (this *ResearchController) ArticleNewList() {
 		item := models.ArticleResearchResp{
 			ArticleId:       v.ArticleId,
 			Title:           v.Title,
-			PublishDate:     v.PublishDate,
+			PublishDate:     v.PublishTime.Format(utils.FormatDate),
 			DepartmentId:    v.DepartmentId,
 			NickName:        v.NickName,
 			IsCollect:       v.IsCollect,
 			Pv:              v.Pv,
 			CollectNum:      v.CollectNum,
+			IsSpecial:       v.IsSpecial,
 			ArticleTypeName: nameMap[v.ArticleTypeId],
 			ButtonStyle:     styleMap[v.ArticleTypeId],
+			SpecialTags:     v.SpecialTags,
+			UserId:          v.UserId,
 			List:            v.List,
 		}
+		if v.ArticleTypeId == -1 {
+			item.ArticleTypeName = utils.CYGX_YANXUAN_SPECIAL
+		}
+		if v.SpecialType == 1 {
+			item.Title = "【笔记】" + item.Title
+		} else if v.SpecialType == 2 {
+			item.Title = "【观点】" + item.Title
+		}
+		if v.CompanyTags != "" {
+			v.SpecialTags += v.CompanyTags
+		}
+		if v.IndustryTags != "" {
+			if v.SpecialTags != "" {
+				v.SpecialTags += ","
+			}
+			v.SpecialTags += v.IndustryTags
+		}
+		item.SpecialTags = v.SpecialTags
 		resp.List = append(resp.List, &item)
 	}
 	resp.Paging = page

+ 28 - 15
controllers/user.go

@@ -589,23 +589,36 @@ func (this *UserController) CollectList() {
 	for i := 0; i < lenList; i++ {
 		item := list[i]
 		article := articleMap[item.ArticleId]
-		list[i].Title = article.Title
-		list[i].DepartmentId = article.DepartmentId
-		list[i].NickName = article.NickName
-		list[i].PublishDate = article.PublishDate
-		if article.ArticleTypeId == 0 {
-			list[i].Source = 1
-		} else {
-			list[i].Source = 2
-			list[i].IsResearch = true
+		if list[i].IsSpecial != 1 {
+			list[i].Title = article.Title
+			list[i].DepartmentId = article.DepartmentId
+			list[i].NickName = article.NickName
+			list[i].PublishDate = article.PublishDate
+			if article.ArticleTypeId == 0 {
+				list[i].Source = 1
+			} else {
+				list[i].Source = 2
+				list[i].IsResearch = true
+			}
+			if mapArticleCollectNum[article.ArticleId] != nil {
+				list[i].CollectNum = mapArticleCollectNum[article.ArticleId].CollectNum
+				list[i].Pv = mapArticleCollectNum[article.ArticleId].Pv
+				list[i].IsCollect = mapArticleCollectNum[article.ArticleId].IsCollect
+			}
+			if _, ok := lyjhTypeMap[item.CategoryId]; ok && list[i].ArticleId >= utils.SummaryArticleId {
+				list[i].IsRoadShow = true
+			}
+		}
+		if item.ArticleTypeId == -1 {
+			list[i].ArticleTypeName = utils.CYGX_YANXUAN_SPECIAL
 		}
-		if mapArticleCollectNum[article.ArticleId] != nil {
-			list[i].CollectNum = mapArticleCollectNum[article.ArticleId].CollectNum
-			list[i].Pv = mapArticleCollectNum[article.ArticleId].Pv
-			list[i].IsCollect = mapArticleCollectNum[article.ArticleId].IsCollect
+		if item.SpecialType == 1 {
+			list[i].Title = "【笔记】"+list[i].Title
+		} else if list[i].SpecialType == 2 {
+			list[i].Title = "【观点】"+list[i].Title
 		}
-		if _, ok := lyjhTypeMap[item.CategoryId]; ok && list[i].ArticleId >= utils.SummaryArticleId {
-			list[i].IsRoadShow = true
+		if item.MyCollectNum > 0 {
+			list[i].IsCollect = true
 		}
 	}
 	page := paging.GetPaging(currentIndex, pageSize, total)

+ 1064 - 0
controllers/yanxuan_special.go

@@ -0,0 +1,1064 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/services"
+	"hongze/hongze_cygx/utils"
+	"time"
+)
+
+type YanxuanSpecialController struct {
+	BaseAuthController
+}
+
+// @Title 专栏列表
+// @Description 专栏列表
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /list [get]
+func (this *YanxuanSpecialController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	userId, _ := this.GetInt("UserId", 0)
+	var condition string
+	var pars []interface{}
+
+	var specialUser *models.CygxYanxuanSpecialAuthorItem
+	var err error
+	if userId > 0 {
+		condition += ` AND a.user_id = ? `
+		pars = append(pars, userId)
+	}
+
+	cond := ``
+	cond += ` AND a.status = 1 `
+	specialUser, err = models.GetYanxuanSpecialAuthor(sysUser.UserId, sysUser.UserId, cond)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + err.Error()
+		return
+	}
+
+	condition += ` AND a.status = 3 `
+
+	list, tmpErr := models.GetYanxuanSpecialList(sysUser.UserId, condition, pars)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+	for _, v := range list {
+		hasImg, err := utils.ArticleHasImgUrl(v.Content)
+		if err != nil {
+			return
+		}
+		if hasImg {
+			v.ContentHasImg = 1
+		}
+		v.Content = utils.ArticleRemoveImgUrl(v.Content)
+
+		v.Content, err = utils.ExtractText(v.Content)
+		if err != nil {
+			return
+		}
+		v.Content = services.AnnotationHtml(v.Content)
+		if v.DocUrl != "" {
+			var docs []models.Doc
+			err := json.Unmarshal([]byte(v.DocUrl), &docs)
+			if err != nil {
+				br.Msg = "参数解析异常!"
+				br.ErrMsg = "参数解析失败,Err:" + err.Error()
+				return
+			}
+			v.Docs = docs
+		}
+		if v.MyCollectNum > 0 {
+			v.IsCollect = 1
+		}
+		if v.CompanyTags != "" {
+			v.Tags += v.CompanyTags
+		}
+		if v.IndustryTags != "" {
+			if v.Tags != "" {
+				v.Tags += ","
+			}
+			v.Tags += v.IndustryTags
+		}
+	}
+	resp := new(models.SpecialListResp)
+
+	if specialUser != nil {
+		resp.IsAuthor = true
+	}
+	resp.List = list
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 专栏详情
+// @Description 专栏详情
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /detail [get]
+func (this *YanxuanSpecialController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	specialId, _ := this.GetInt("Id", 0)
+
+	if specialId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+
+	item, tmpErr := models.GetYanxuanSpecialById(specialId, sysUser.UserId)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+	if item.MyCollectNum > 0 {
+		item.IsCollect = 1
+	}
+
+	var resp models.CygxYanxuanSpecialResp
+	resp.CygxYanxuanSpecialItem = *item
+	if item.DocUrl != "" {
+		var docs []models.Doc
+		err := json.Unmarshal([]byte(item.DocUrl), &docs)
+		if err != nil {
+			br.Msg = "参数解析异常!"
+			br.ErrMsg = "参数解析失败,Err:" + err.Error()
+			return
+		}
+		resp.Docs = docs
+	}
+	if item.CompanyTags != "" {
+		resp.Tags += item.CompanyTags
+	}
+	if item.IndustryTags != "" {
+		if resp.Tags != "" {
+			resp.Tags += ","
+		}
+		resp.Tags += item.IndustryTags
+	}
+
+	go services.AddSpecialRecord(this.User, specialId)
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 新增保存专栏作者详情
+// @Description 新增保存专栏作者详情
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/save [post]
+func (this *YanxuanSpecialController) AuthorSave() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.SaveCygxYanxuanSpecialAuthorReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.UserId <= 0 {
+		br.Msg = "用户id有误"
+		return
+	}
+	if req.SpecialName == "" {
+		br.Msg = "请输入专栏名称"
+		return
+	}
+	if req.NickName == "" {
+		br.Msg = "请输入昵称"
+		return
+	}
+
+	item := models.CygxYanxuanSpecialAuthor{
+		UserId:       req.UserId,
+		SpecialName:  req.SpecialName,
+		Introduction: req.Introduction,
+		Label:        req.Label,
+		NickName:     req.NickName,
+		CreateTime:   time.Now(),
+		ModifyTime:   time.Now(),
+		BgImg:        "",
+		Status:       1,
+	}
+
+	//if req.Id == 0{
+	//	_, err = models.AddCygxYanxuanSpecialAuthor(&item)
+	//	if err != nil {
+	//		br.Msg = "新增失败"
+	//		br.ErrMsg = "新增失败,Err:" + err.Error()
+	//		return
+	//	}
+	//} else {
+	//	err = models.UpdateYanxuanSpecialAuthor(&item)
+	//	if err != nil {
+	//		br.Msg = "保存失败"
+	//		br.ErrMsg = "保存失败,Err:" + err.Error()
+	//		return
+	//	}
+	//}
+	err = models.UpdateYanxuanSpecialAuthor(&item)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// @Title 新增保存专栏
+// @Description 新增保存专栏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /save [post]
+func (this *YanxuanSpecialController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.CygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Content == "" && req.DoType == 2 {
+		br.Msg = "请输入内容"
+		return
+	}
+	if req.CompanyTags == "" && req.IndustryTags == "" && req.DoType == 2 {
+		br.Msg = "请至少输入一个标签"
+		return
+	}
+
+	item := models.CygxYanxuanSpecial{
+		Id:           req.Id,
+		UserId:       sysUser.UserId,
+		CreateTime:   time.Now(),
+		ModifyTime:   time.Now(),
+		PublishTime:  time.Now(),
+		Content:      req.Content,
+		ImgUrl:       req.ImgUrl,
+		DocUrl:       req.DocUrl,
+		Title:        req.Title,
+		Type:         req.Type,
+		CompanyTags:  req.CompanyTags,
+		IndustryTags: req.IndustryTags,
+	}
+	if req.DoType == 1 {
+		item.Status = 1
+	} else {
+		item.Status = 2
+	}
+
+	specialId := 0
+
+	if req.Id == 0 {
+		id, err := models.AddCygxYanxuanSpecial(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+		specialId = int(id)
+	} else {
+		err = models.UpdateYanxuanSpecial(&item)
+		if err != nil {
+			br.Msg = "保存失败"
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
+		}
+		specialId = req.Id
+	}
+
+	if req.DoType == 2 {
+		go services.SendReviewTemplateMsgAdmin(specialId)
+		go services.UpdateYanxuanSpecialResourceData(specialId) //  写入首页最新  cygx_resource_data 表
+		go services.EsAddYanxuanSpecial(specialId)              //  写入es 综合搜索
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// @Title 专栏作者详情
+// @Description 专栏作者详情
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/detail [get]
+func (this *YanxuanSpecialController) AuthorDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	userId, _ := this.GetInt("UserId", 0)
+	if userId == 0 {
+		userId = sysUser.UserId
+	}
+	item, tmpErr := models.GetYanxuanSpecialAuthor(userId, sysUser.UserId, "")
+	if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Data = item
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 审批研选专栏
+// @Description 审批研选专栏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /enable [post]
+func (this *YanxuanSpecialController) Enable() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.EnableCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+	if req.Status <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	status := 0
+	if req.Status == 1 {
+		status = 3
+	} else {
+		status = 4
+	}
+	if tmpErr := models.EnableYanxuanSpecial(req.Id, status, req.Reason); tmpErr != nil {
+		br.Msg = "审批失败"
+		br.ErrMsg = "审批失败, Err:" + tmpErr.Error()
+		return
+	}
+	if req.Status == 1 {
+		go services.SendWxMsgSpecialFollow(req.Id)
+	}
+	go services.SendWxMsgSpecialAuthor(req.Id, req.Status)
+	go services.UpdateYanxuanSpecialResourceData(req.Id) //  写入首页最新  cygx_resource_data 表
+	go services.EsAddYanxuanSpecial(req.Id)              //  写入es 综合搜索
+	br.Msg = "审批成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 研选专栏收藏
+// @Description 研选专栏收藏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /collect [post]
+func (this *YanxuanSpecialController) Collect() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.CollectCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+	if req.Status <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	var sellerName string
+	sellerName, err = models.GetCompanySellerName(sysUser.CompanyId)
+	if err != nil {
+		br.Msg = "报名失败!"
+		br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
+		return
+	}
+	if req.Status == 1 {
+		item := models.CygxYanxuanSpecialCollect{
+			UserId:           sysUser.UserId,
+			Mobile:           sysUser.Mobile,
+			Email:            sysUser.Email,
+			CompanyId:        sysUser.CompanyId,
+			CompanyName:      sysUser.CompanyName,
+			RealName:         sysUser.RealName,
+			SellerName:       sellerName,
+			CreateTime:       time.Now(),
+			ModifyTime:       time.Now(),
+			RegisterPlatform: utils.REGISTER_PLATFORM,
+			YanxuanSpecialId: req.Id,
+		}
+		_, err = models.AddCygxYanxuanSpecialCollect(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "收藏成功"
+	} else {
+		err = models.DelCygxYanxuanSpecialCollect(sysUser.UserId, req.Id)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "取消收藏成功"
+	}
+
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 专栏内容中心
+// @Description 专栏内容中心
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /center [get]
+func (this *YanxuanSpecialController) Center() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 1:未发布,2:审核中 3:已发布 4:驳回
+	status, _ := this.GetInt("Status", 0)
+
+	if status <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+
+	var condition string
+	var pars []interface{}
+
+	condition += ` AND a.user_id = ? `
+	pars = append(pars, sysUser.UserId)
+
+	condition += ` AND a.status = ? `
+	pars = append(pars, status)
+
+	list, tmpErr := models.GetYanxuanSpecialList(sysUser.UserId, condition, pars)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	for _, v := range list {
+		hasStyle, err := utils.ArticleHasStyle(v.Content)
+		if err != nil {
+			return
+		}
+		v.ContentHasStyle = hasStyle
+		hasImg, err := utils.ArticleHasImgUrl(v.Content)
+		if err != nil {
+			return
+		}
+		if hasImg {
+			v.ContentHasStyle = hasImg
+		}
+	}
+
+	br.Data = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 专栏点击记录
+// @Description 专栏点击记录
+// @Param	request	body models.AddCygxReportSelectionSubjectHistoryReq true "type json string"
+// @router /record [post]
+func (this *YanxuanSpecialController) Record() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	var req models.AddCygxYanxuanSpecialRecordReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.SpecialId <= 0 {
+		br.Msg = "文章不存在"
+		br.ErrMsg = "文章不存在,文章ID错误"
+		return
+	}
+	var sellerName string
+	sellerName, err = models.GetCompanySellerName(user.CompanyId)
+	if err != nil {
+		br.Msg = "报名失败!"
+		br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
+		return
+	}
+	item := models.CygxYanxuanSpecialRecord{
+		UserId:           user.UserId,
+		Mobile:           user.Mobile,
+		Email:            user.Email,
+		CompanyId:        user.CompanyId,
+		CompanyName:      user.CompanyName,
+		RealName:         user.RealName,
+		SellerName:       sellerName,
+		CreateTime:       time.Now(),
+		ModifyTime:       time.Now(),
+		RegisterPlatform: utils.REGISTER_PLATFORM,
+		YanxuanSpecialId: req.SpecialId,
+	}
+	_, err = models.AddCygxYanxuanSpecialRecord(&item)
+	if err != nil {
+		br.Msg = "记录失败"
+		br.ErrMsg = "记录失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "记录成功"
+}
+
+// @Title 研选专栏关注
+// @Description 研选专栏关注
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /follow [post]
+func (this *YanxuanSpecialController) Follow() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.FollowCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.FollowUserId <= 0 {
+		br.Msg = "被关注的用户id"
+		return
+	}
+	if req.Status <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	var sellerName string
+	sellerName, err = models.GetCompanySellerName(sysUser.CompanyId)
+	if err != nil {
+		br.Msg = "报名失败!"
+		br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
+		return
+	}
+	if req.Status == 1 {
+		item := models.CygxYanxuanSpecialFollow{
+			UserId:           sysUser.UserId,
+			FollowUserId:     req.FollowUserId,
+			Mobile:           sysUser.Mobile,
+			Email:            sysUser.Email,
+			CompanyId:        sysUser.CompanyId,
+			CompanyName:      sysUser.CompanyName,
+			RealName:         sysUser.RealName,
+			SellerName:       sellerName,
+			CreateTime:       time.Now(),
+			ModifyTime:       time.Now(),
+			RegisterPlatform: utils.REGISTER_PLATFORM,
+			YanxuanSpecialId: req.SpecialId,
+		}
+		err = models.AddCygxYanxuanSpecialFollow(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "关注成功"
+	} else {
+		err = models.DelCygxYanxuanSpecialFollow(sysUser.UserId, req.FollowUserId)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "取消关注成功"
+	}
+
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 行业标签搜索
+// @Description 行业标签搜索
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /industrySearch [get]
+func (this *YanxuanSpecialController) IndustrySearch() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	keyword := this.GetString("Keyword")
+
+	list, tmpErr := models.GetYanxuanSpecialIndustry(keyword)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Data = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 公司标签搜索
+// @Description 公司标签搜索
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /companySearch [get]
+func (this *YanxuanSpecialController) CompanySearch() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	keyword := this.GetString("Keyword")
+
+	if keyword == "" {
+		br.Ret = 200
+		return
+	}
+
+	list, tmpErr := models.GetYanxuanSpecialCompany(keyword)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Data = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 专栏取消发布
+// @Description 专栏取消发布
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /cancel [post]
+func (this *YanxuanSpecialController) Cancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.CancelPublishCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+
+	if tmpErr := models.CancelPublishYanxuanSpecial(req.Id); tmpErr != nil {
+		br.Msg = "取消发布失败"
+		br.ErrMsg = "取消发布失败, Err:" + tmpErr.Error()
+		return
+	}
+	go services.UpdateYanxuanSpecialResourceData(req.Id) //  写入首页最新  cygx_resource_data 表
+	go services.EsAddYanxuanSpecial(req.Id)              //  写入es 综合搜索
+	br.Msg = "取消发布成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 作者列表
+// @Description 作者列表
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/list [get]
+func (this *YanxuanSpecialController) AuthorList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var specialUser *models.CygxYanxuanSpecialAuthorItem
+	var err error
+
+	cond := ``
+	cond += ` AND a.status = 1 `
+	specialUser, err = models.GetYanxuanSpecialAuthor(sysUser.UserId, sysUser.UserId, cond)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + err.Error()
+		return
+	}
+
+	list, tmpErr := models.GetYanxuanSpecialAuthorList()
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	for _, v := range list {
+		v.LatestPublishDate = v.LatestPublishTime.Format(utils.FormatDate) + "更新"
+	}
+	resp := new(models.SpecialAuthorListResp)
+
+	if specialUser != nil {
+		resp.IsAuthor = true
+	}
+	resp.List = list
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 更新作者头像
+// @Description 更新作者头像
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/head_img [post]
+func (this *YanxuanSpecialController) AuthorHeadImg() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.SaveCygxYanxuanSpecialAuthoHeadImgrReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.UserId <= 0 {
+		br.Msg = "用户id有误"
+		return
+	}
+	if req.HeadImg == "" {
+		br.Msg = "头像图片错误"
+		return
+	}
+
+	item := models.CygxYanxuanSpecialAuthor{
+		UserId:  req.UserId,
+		HeadImg: req.HeadImg,
+	}
+
+	err = models.UpdateYanxuanSpecialAuthorHeadImg(&item)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// @Title 删除专栏
+// @Description 删除专栏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /del [post]
+func (this *YanxuanSpecialController) Delete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.EnableCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+
+	if tmpErr := models.DelYanxuanSpecial(req.Id); tmpErr != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Msg = "删除成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 专栏文章敏感词检测
+// @Description 专栏文章敏感词检测
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /check [post]
+func (this *YanxuanSpecialController) Check() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.CygxYanxuanSpecialCheckReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Content == "" {
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "校验成功"
+	}
+	itemToken, err := services.WxGetToken()
+	if err != nil {
+		br.Msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if itemToken.AccessToken == "" {
+		br.Msg = "accessToken is empty"
+		return
+	}
+
+	suggest := models.WxCheckContent(itemToken.AccessToken, sysUser.OpenId, req.Content)
+	if suggest == "risky" {
+		br.Msg = "文章内容含有违法违规内容"
+		br.ErrMsg = "文章内容含有违法违规内容"
+		return
+	}
+	if len(req.ImgUrl) > 0 {
+		//for _, imgUrl := range req.ImgUrl {
+		//	imgBody, err := http.Get(imgUrl)
+		//	if err != nil {
+		//		br.Msg = "图片链接有误"
+		//		br.ErrMsg = "图片链接有误"
+		//		return
+		//	}
+		//	rnStr := utils.GetRandStringNoSpecialChar(5)
+		//	savePath := time.Now().Format(utils.FormatDateTimeUnSpace) + rnStr + ".jpg"
+		//	err = file.SaveFile(imgBody, savePath)
+		//	if err != nil {
+		//		br.Msg = "保存图片错误"
+		//		br.ErrMsg = "保存图片错误"
+		//		return
+		//	}
+		//	res, err := weapp.IMGSecCheck(itemToken.AccessToken, savePath)
+		//	if err != nil {
+		//		// 处理一般错误信息
+		//		br.Msg = "图片内容含有违法违规内容"
+		//		br.ErrMsg = "图片内容含有违法违规内容"
+		//		return
+		//	}
+		//	if err := res.GetResponseError(); err != nil {
+		//		// 处理微信返回错误信息
+		//		return
+		//	}
+		//	err = os.RemoveAll(savePath)
+		//	if err != nil {
+		//		return
+		//	}
+		//}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "校验成功"
+}

+ 3 - 0
go.mod

@@ -11,11 +11,14 @@ require (
 	github.com/elastic/go-elasticsearch/v7 v7.17.1
 	github.com/go-sql-driver/mysql v1.6.0
 	github.com/medivhzhan/weapp/v2 v2.5.0
+	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/olivere/elastic/v7 v7.0.32
 	github.com/pdfcpu/pdfcpu v0.3.13
 	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/satori/go.uuid v1.2.0 // indirect
 	github.com/tealeg/xlsx v1.0.5
+	golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
+	golang.org/x/sys v0.6.0 // indirect
 	golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
 )

+ 4 - 2
go.sum

@@ -265,8 +265,9 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
 github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@@ -525,8 +526,9 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

+ 257 - 0
models/cygx_yanxuan_special.go

@@ -0,0 +1,257 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxYanxuanSpecial struct {
+	Id           int       `orm:"column(id);pk"`
+	UserId       int       // 用户ID
+	CreateTime   time.Time // 创建时间
+	ModifyTime   time.Time // 修改时间
+	PublishTime  time.Time // 提审过审或驳回时间
+	Content      string    // 内容
+	Tags         string    // 标签
+	Status       int       // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl       string    // 图片链接
+	DocUrl       string    // 文档链接
+	Reason       string    // 理由
+	Title        string    // 标题
+	Type         int       // 类型1:笔记,2:观点
+	CompanyTags  string    // 公司标签
+	IndustryTags string    // 行业标签
+}
+
+type CygxYanxuanSpecialItem struct {
+	Id            int    `orm:"column(id);pk"`
+	UserId        int    // 用户ID
+	CreateTime    string // 创建时间
+	ModifyTime    string // 修改时间
+	PublishTime   string // 提审过审或驳回时间
+	Content       string // 内容
+	Tags          string // 标签
+	Status        int    // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl        string // 图片链接
+	DocUrl        string // 文档链接
+	SpecialName   string // 专栏名称
+	Introduction  string // 介绍
+	Label         string // 标签
+	NickName      string // 昵称
+	RealName      string // 姓名
+	Mobile        string // 手机号
+	HeadImg       string // 头像
+	BgImg         string // 背景图
+	Reason        string // 理由
+	Title         string // 标题
+	Type          int    // 类型1:笔记,2:观点
+	CollectNum    int
+	MyCollectNum  int
+	IsCollect     int
+	CompanyTags   string
+	IndustryTags  string
+	ContentHasImg int //正文是否包含图片 1包含 0不包含
+	Docs          []Doc
+}
+
+type CygxYanxuanSpecialResp struct {
+	CygxYanxuanSpecialItem
+	Docs         []Doc
+	CompanyTags  []string
+	IndustryTags []string
+}
+
+type CygxYanxuanSpecialCenterResp struct {
+	Id              int    `orm:"column(id);pk"`
+	UserId          int    // 用户ID
+	CreateTime      string // 创建时间
+	ModifyTime      string // 修改时间
+	PublishTime     string // 提审过审或驳回时间
+	Content         string // 内容
+	Tags            string // 标签
+	Status          int    // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl          string // 图片链接
+	DocUrl          string // 文档链接
+	SpecialName     string // 专栏名称
+	Introduction    string // 介绍
+	Label           string // 标签
+	NickName        string // 昵称
+	RealName        string // 姓名
+	Mobile          string // 手机号
+	HeadImg         string // 头像
+	BgImg           string // 背景图
+	Reason          string // 理由
+	Title           string // 标题
+	Type            int    // 类型1:笔记,2:观点
+	CollectNum      int
+	MyCollectNum    int
+	IsCollect       int
+	CompanyTags     string
+	IndustryTags    string
+	ContentHasImg   int  //正文是否包含图片 1包含 0不包含
+	ContentHasStyle bool //正文是否包含格式
+	Docs            []Doc
+	Annotation      string `description:"核心观点"`
+	Source          string `description:"来源"`
+	PublishDate     string // 提审过审或驳回时间      string `description:"核心观点"`
+}
+
+type Doc struct {
+	DocName   string
+	DocSuffix string
+	DocUrl    string
+	DocIcon   string
+}
+
+func GetYanxuanSpecialList(userId int, condition string, pars []interface{}) (items []*CygxYanxuanSpecialCenterResp, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.bg_img,b.head_img,b.introduction,b.label,b.mobile,b.nick_name,b.real_name,b.special_name,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  ) AS collect_num,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  AND user_id = ? ) AS my_collect_num 
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id 
+ WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += `ORDER BY a.publish_time DESC `
+	_, err = o.Raw(sql, userId, pars).QueryRows(&items)
+	return
+}
+
+type EnableCygxYanxuanSpecialReq struct {
+	Id     int    // 文章id
+	Status int    // 1通过2驳回
+	Reason string //理由
+}
+
+func EnableYanxuanSpecial(id, status int, reason string) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET status=?,reason=?,publish_time=NOW(),modify_time=NOW() WHERE id = ? `
+	_, err = o.Raw(sql, status, reason, id).Exec()
+	return
+}
+
+type SpecialListResp struct {
+	List     []*CygxYanxuanSpecialCenterResp
+	IsAuthor bool
+}
+
+func GetYanxuanSpecialById(specialId, userId int) (item *CygxYanxuanSpecialItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.bg_img,b.head_img,b.introduction,b.label,b.mobile,
+b.nick_name,b.real_name,b.special_name,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  ) AS collect_num,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  AND user_id = ? ) AS my_collect_num
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id 
+ WHERE a.id=? `
+	err = o.Raw(sql, userId, specialId).QueryRow(&item)
+	return
+}
+
+type CygxYanxuanSpecialReq struct {
+	Id           int    `orm:"column(id);pk"`
+	Content      string // 内容
+	Tags         string // 标签
+	DoType       int    // 1保存 2发布
+	ImgUrl       string // 图片链接
+	DocUrl       string // 文档链接
+	Title        string // 标题
+	Type         int    // 类型1:笔记,2:观点
+	IndustryTags string // 行业标签
+	CompanyTags  string // 公司标签
+}
+
+func AddCygxYanxuanSpecial(item *CygxYanxuanSpecial) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+func UpdateYanxuanSpecial(item *CygxYanxuanSpecial) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET title=?,content=?,company_tags=?,industry_tags=?,img_url=?,doc_url=?,type=?,status=?,
+	modify_time=NOW(),publish_time=NOW() WHERE id = ? `
+	_, err = o.Raw(sql, item.Title, item.Content, item.CompanyTags, item.IndustryTags, item.ImgUrl, item.DocUrl, item.Type, item.Status, item.Id).Exec()
+	return
+}
+
+func GetYanxuanSpecialIndustry(keyword string) (IndustryNames []string, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	if keyword == "" {
+		sql = `SELECT industry_name FROM cygx_yanxuan_special_industry `
+	} else {
+		sql = `SELECT industry_name FROM cygx_yanxuan_special_industry WHERE industry_name LIKE '%` + keyword + `%' `
+	}
+	_, err = o.Raw(sql).QueryRows(&IndustryNames)
+	return
+}
+
+type CancelPublishCygxYanxuanSpecialReq struct {
+	Id int // 文章id
+}
+
+func CancelPublishYanxuanSpecial(id int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET status=1,publish_time=NOW(),modify_time=NOW() WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+type DelCygxYanxuanSpecialReq struct {
+	Id int // 文章id
+}
+
+func DelYanxuanSpecial(id int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `DELETE FROM cygx_yanxuan_special WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+type CygxYanxuanSpecialCheckReq struct {
+	Content string   // 内容
+	ImgUrl  []string // 图片
+}
+
+func GetYanxuanSpecialFollowUserById(specialId int) (items []int, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT b.user_id
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_follow AS b ON a.user_id = b.follow_user_id
+ WHERE a.id=? `
+	_, err = o.Raw(sql, specialId).QueryRows(&items)
+	return
+}
+
+func GetYanxuanSpecialItemById(specialId int) (item *CygxYanxuanSpecialItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.bg_img,b.head_img,b.introduction,b.label,b.mobile,
+b.nick_name,b.real_name,b.special_name
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id 
+ WHERE a.id=? `
+	err = o.Raw(sql, specialId).QueryRow(&item)
+	return
+}
+
+// 获取数量
+func GetCygxYanxuanSpecialCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_yanxuan_special WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}

+ 39 - 0
models/cygx_yanxuan_special_collect.go

@@ -0,0 +1,39 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxYanxuanSpecialCollect struct {
+	CygxYanxuanSpecialCollectId int       `orm:"column(cygx_yanxuan_special_collect_id);pk"`
+	UserId                      int        // 用户ID
+	Mobile                      string     // 手机号
+	Email                       string     // 邮箱
+	CompanyId                   int        // 公司ID
+	CompanyName                 string     // 公司名称
+	RealName                    string     // 用户实际名称
+	SellerName                  string     // 所属销售
+	CreateTime                  time.Time  // 创建时间
+	ModifyTime                  time.Time  // 修改时间
+	RegisterPlatform            int        // 来源 1小程序,2:网页
+	YanxuanSpecialId            int        // cygx_yanxuan_special 表主键ID
+}
+
+func AddCygxYanxuanSpecialCollect(item *CygxYanxuanSpecialCollect) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type CollectCygxYanxuanSpecialReq struct {
+	Id     int    // 文章id
+	Status int    // 1收藏2取消收藏
+}
+
+func DelCygxYanxuanSpecialCollect(userId, articleId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_yanxuan_special_collect WHERE user_id=? AND yanxuan_special_id=? `
+	_, err = o.Raw(sql, userId, articleId).Exec()
+	return
+}

+ 43 - 0
models/cygx_yanxuan_special_company.go

@@ -0,0 +1,43 @@
+package models
+
+import "github.com/beego/beego/v2/client/orm"
+
+type CygxYanxuanSpecialCompany struct {
+	Id        int    `orm:"column(id);pk"`
+	TradeCode string `json:"trade_code"` // 交易代码
+	SecName   string `json:"sec_name"`   // 公司名
+	PyName    string `json:"py_name"`    // 拼音名
+	Region    string `json:"region"`     // 地区
+}
+
+type VmpStocks struct {
+	Code int
+	Msg  string
+	Data []CygxYanxuanSpecialCompany
+}
+
+// 批量添加
+func AddCygxYanxuanSpecialCompanyMulti(items []*CygxYanxuanSpecialCompany) (err error) {
+	o := orm.NewOrm()
+	if len(items) > 0 {
+		//批量添加
+		_, err = o.InsertMulti(len(items), items)
+	}
+	return
+}
+
+func GetYanxuanSpecialCompany(keyword string) (IndustryNames []string, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT sec_name FROM cygx_yanxuan_special_company WHERE sec_name LIKE '%` + keyword + `%' `
+	_, err = o.Raw(sql).QueryRows(&IndustryNames)
+	return
+}
+
+func DelYanxuanSpecialCompany() (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `DELETE FROM cygx_yanxuan_special_company `
+	_, err = o.Raw(sql).Exec()
+	return
+}

+ 57 - 0
models/cygx_yanxuan_special_follow.go

@@ -0,0 +1,57 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxYanxuanSpecialFollow struct {
+	CygxYanxuanSpecialFollowId int        `orm:"column(cygx_yanxuan_special_follow_id);pk"`
+	UserId                     int        // 用户ID
+	FollowUserId               int        // 被关注用户ID
+	Mobile                     string     // 手机号
+	Email                      string     // 邮箱
+	CompanyId                  int        // 公司ID
+	CompanyName                string     // 公司名称
+	RealName                   string     // 用户实际名称
+	SellerName                 string     // 所属销售
+	CreateTime                 time.Time  // 创建时间
+	ModifyTime                 time.Time  // 修改时间
+	RegisterPlatform           int        // 来源 1小程序,2:网页
+	YanxuanSpecialId           int        // cygx_yanxuan_special 表主键ID
+}
+
+type FollowCygxYanxuanSpecialReq struct {
+	FollowUserId int // 被关注的用户id
+	Status       int // 1关注2取消关注
+	SpecialId    int // 研选专栏Id
+}
+
+func AddCygxYanxuanSpecialFollow(item *CygxYanxuanSpecialFollow) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+func DelCygxYanxuanSpecialFollow(userId, followUserId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_yanxuan_special_follow WHERE user_id=? AND follow_user_id=? `
+	_, err = o.Raw(sql, userId, followUserId).Exec()
+	return
+}
+
+func GetCygxYanxuanSpecialFollowOpenIdList(followUserId int) (items []*OpenIdList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	cr.*,
+	c.user_id 
+FROM
+	user_record AS c
+	INNER JOIN cygx_user_record AS cr ON cr.union_id = c.union_id
+	INNER JOIN cygx_yanxuan_special_follow AS cf ON cf.user_id = c.user_id 
+	AND cf.follow_user_id = ? 
+WHERE
+	create_platform = 4 `
+	_, err = o.Raw(sql, followUserId).QueryRows(&items)
+	return
+}

+ 32 - 0
models/cygx_yanxuan_special_record.go

@@ -0,0 +1,32 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxYanxuanSpecialRecord struct {
+	CygxYanxuanSpecialRecordId int       `orm:"column(cygx_yanxuan_special_record_id);pk"`
+	UserId                     int       // 用户ID
+	Mobile                     string    // 手机号
+	Email                      string    // 邮箱
+	CompanyId                  int       // 公司ID
+	CompanyName                string    // 公司名称
+	RealName                   string    // 用户实际名称
+	SellerName                 string    // 所属销售
+	CreateTime                 time.Time // 创建时间
+	ModifyTime                 time.Time // 修改时间
+	RegisterPlatform           int       // 来源 1小程序,2:网页
+	YanxuanSpecialId           int       // cygx_yanxuan_special 表主键ID
+	StopTime                   int       // 停留时间
+}
+
+func AddCygxYanxuanSpecialRecord(item *CygxYanxuanSpecialRecord) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type AddCygxYanxuanSpecialRecordReq struct {
+	SpecialId           int `description:"专栏文章id"`
+}

+ 138 - 0
models/cygx_yanxuan_special_user.go

@@ -0,0 +1,138 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxYanxuanSpecialAuthor struct {
+	Id           int       `orm:"column(id);pk"`
+	UserId       int       // 用户ID
+	SpecialName  string    // 专栏名称
+	Introduction string    // 介绍
+	Label        string    // 标签
+	NickName     string    // 昵称
+	RealName     string    // 姓名
+	Mobile       string    // 手机号
+	CreateTime   time.Time // 创建时间
+	ModifyTime   time.Time // 修改时间
+	HeadImg      string    // 头像
+	BgImg        string    // 背景图上部分
+	BgImgDown    string    // 背景图下部分
+	Status       int       // 1启用2禁用
+}
+
+type CygxYanxuanSpecialAuthorItem struct {
+	Id                int       `orm:"column(id);pk"`
+	UserId            int       // 用户ID
+	SpecialName       string    // 专栏名称
+	Introduction      string    // 介绍
+	Label             string    // 标签
+	NickName          string    // 昵称
+	RealName          string    // 姓名
+	CompanyName       string    // 公司名
+	Mobile            string    // 手机号
+	CreateTime        string    // 创建时间
+	ModifyTime        time.Time // 修改时间
+	HeadImg           string    // 头像
+	BgImg             string    // 背景图
+	BgImgDown         string    // 背景图下半部分
+	Status            int       // 1启用2禁用
+	CollectNum        int       // 被收藏数
+	FollowNum         int       // 被关注数
+	SpecialArticleNum int       // 文章数
+	LatestPublishTime time.Time // 最近更新时间
+	LatestPublishDate string    // 最近更新时间
+	IsFollow          int       // 是否已关注 1已关注 0 未关注
+	HasChangeHeadImg  int       // 是否更换过默认头像 1是,0否
+}
+
+func AddCygxYanxuanSpecialAuthor(item *CygxYanxuanSpecialAuthor) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type EnableCygxYanxuanSpecialAuthorReq struct {
+	UserId int // 用户ID
+	Status int // 1启用2禁用
+}
+
+// 启用禁用作者
+func EnableYanxuanSpecialAuthor(userId, status int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special_author SET status=?,modify_time=NOW() WHERE user_id = ? `
+	_, err = o.Raw(sql, status, userId).Exec()
+	return
+}
+
+func GetYanxuanSpecialAuthor(reqUserId, sysUserId int, cond string) (item *CygxYanxuanSpecialAuthorItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT
+	a.*,
+	( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac  INNER JOIN cygx_yanxuan_special as cs ON  ac.yanxuan_special_id = cs.id  WHERE cs.user_id = a.user_id  ) AS collect_num,
+	( SELECT count( 1 ) FROM cygx_yanxuan_special_follow AS cf  WHERE cf.follow_user_id = a.user_id  ) AS follow_num,
+	( SELECT count( 1 ) FROM cygx_yanxuan_special AS ca  WHERE ca.user_id = a.user_id AND ca.status = 3 ) AS special_article_num,
+	( SELECT count( 1 ) FROM cygx_yanxuan_special_follow AS cf  WHERE cf.follow_user_id =? AND cf.user_id = ?  ) AS is_follow 
+FROM
+	cygx_yanxuan_special_author as a WHERE a.user_id=? `
+	if cond != "" {
+		sql += cond
+	}
+	err = o.Raw(sql, reqUserId, sysUserId, reqUserId).QueryRow(&item)
+	return
+}
+
+type SaveCygxYanxuanSpecialAuthorReq struct {
+	UserId       int    // 用户ID
+	SpecialName  string // 专栏名称
+	Introduction string // 介绍
+	Label        string // 标签
+	NickName     string // 昵称
+	BgImg        string // 背景图
+}
+
+func UpdateYanxuanSpecialAuthor(item *CygxYanxuanSpecialAuthor) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special_author SET special_name=?,introduction=?,label=?,nick_name=?
+	,modify_time=NOW() WHERE user_id = ? `
+	_, err = o.Raw(sql, item.SpecialName, item.Introduction, item.Label, item.NickName, item.UserId).Exec()
+	return
+}
+
+func GetYanxuanSpecialAuthorList() (items []*CygxYanxuanSpecialAuthorItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT
+	a.*,
+	IFNULL(( SELECT publish_time FROM cygx_yanxuan_special WHERE user_id = a.user_id AND STATUS = 3 ORDER BY publish_time DESC LIMIT 1 ), a.modify_time) AS latest_publish_time
+FROM
+	cygx_yanxuan_special_author AS a
+WHERE
+	a.nick_name <> ''
+ORDER BY
+	latest_publish_time DESC `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+type SpecialAuthorListResp struct {
+	List     []*CygxYanxuanSpecialAuthorItem
+	IsAuthor bool
+}
+
+type SaveCygxYanxuanSpecialAuthoHeadImgrReq struct {
+	UserId  int    // 用户ID
+	HeadImg string // 头像
+}
+
+func UpdateYanxuanSpecialAuthorHeadImg(item *CygxYanxuanSpecialAuthor) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special_author SET head_img=?,modify_time=NOW(),has_change_head_img = 1  WHERE user_id = ? `
+	_, err = o.Raw(sql, item.HeadImg, item.UserId).Exec()
+	return
+}

+ 5 - 0
models/db.go

@@ -172,6 +172,11 @@ func init() {
 		new(CygxResourceDataIndustrialGroupManagement),
 		new(CygxResourceDataIndustrialGroupSubject),
 		new(CygxIndustryFllowLog),
+		new(CygxYanxuanSpecialRecord),
+		new(CygxYanxuanSpecialCollect),
+		new(CygxYanxuanSpecial),
+		new(CygxYanxuanSpecialFollow),
+		new(CygxYanxuanSpecialCompany),
 	)
 	// 记录ORM查询日志
 	orm.Debug = true

+ 82 - 23
models/report.go

@@ -488,7 +488,8 @@ func GetArticleIdsBySubId(subjectId string) (articleIds string, err error) {
 type ArticleCollectionResp struct {
 	ArticleId              int                         `description:"文章id"`
 	Title                  string                      `description:"标题"`
-	PublishDate            string                      `description:"发布时间"`
+	PublishDate            string                      `description:"发布日期"`
+	PublishTime            time.Time                   `description:"发布时间"`
 	IndustrialManagementId int                         `description:"产业Id"`
 	IndustryName           string                      `description:"产业名称"`
 	DepartmentId           int                         `description:"作者Id"`
@@ -500,6 +501,12 @@ type ArticleCollectionResp struct {
 	Source                 int                         `description:"来源 1:弘则资源包(报告)、2:研选主题(报告)"`
 	ArticleTypeId          int                         `description:"文章类型ID"`
 	List                   []*IndustrialManagementResp `description:"产业列表"`
+	IsSpecial              int                         `description:"是否为研选专栏"`
+	SpecialTags            string                      `description:"研选专栏标签"`
+	UserId                 int                         `description:"作者id"`
+	SpecialType            int                         `description:"专栏类型 1:笔记,2:观点"`
+	IndustryTags           string                      `description:"研选专栏行业标签"`
+	CompanyTags            string                      `description:"研选专栏公司标签"`
 }
 
 type IndustrialManagementResp struct {
@@ -595,45 +602,90 @@ type ArticleResearchResp struct {
 	ArticleTypeId   int                         `description:"文章类型ID"`
 	ArticleTypeName string                      `description:"类型名称"`
 	ButtonStyle     string                      `description:"按钮展示样式"`
+	IsSpecial       int                         `description:"是否为研选专栏"`
+	SpecialTags     string                      `description:"研选专栏标签"`
+	UserId          int                         `description:"作者id"`
 	List            []*IndustrialManagementResp `description:"产业列表"`
 }
 
 // 获取我的日程数量
-func GetArticleResearchCount(condition string, pars []interface{}) (count int, err error) {
+func GetArticleResearchCount(condition string, pars []interface{}, needYanxuanSpecial bool) (count int, err error) {
 	o := orm.NewOrm()
 	sqlCount := `SELECT COUNT( 1 ) AS count FROM
 			cygx_article AS a
 		WHERE
 			1 = 1  AND a.publish_status = 1` + condition
+	if needYanxuanSpecial {
+		sqlCount = `SELECT SUM(count) AS count FROM (` + sqlCount + `
+		UNION ALL
+	SELECT COUNT( 1 ) AS count FROM
+		cygx_yanxuan_special AS a WHERE
+	1 = 1  AND a.status = 3) AS c`
+	}
 	err = o.Raw(sqlCount, pars).QueryRow(&count)
 	return
 }
 
-func GetArticleResearchList(condition string, pars []interface{}, startSize, pageSize, userId int) (items []*ArticleCollectionResp, err error) {
+func GetArticleResearchList(condition string, pars []interface{}, startSize, pageSize, userId int, needYanxuanSpecial bool) (items []*ArticleCollectionResp, err error) {
 	o := orm.NewOrm()
 	sql := `SELECT
 			a.article_id,
 			a.title,
-			date_format( a.publish_date, '%Y-%m-%d' ) AS publish_date,
+			a.publish_date AS publish_time,
 			a.article_type_id,
 			d.nick_name,
 			d.department_id,
 			( SELECT count( 1 ) FROM cygx_article_history_record_newpv AS h WHERE h.article_id = a.article_id ) AS pv,
-			( SELECT count( 1 ) FROM cygx_article_collect AS ac   WHERE ac.article_id = a.article_id  ) AS collect_num, 
+			( SELECT count( 1 ) FROM cygx_article_collect AS ac    WHERE ac.article_id = a.article_id  ) AS collect_num, 
 			( SELECT count( 1 ) FROM cygx_article_collect AS ac   WHERE ac.article_id = a.article_id AND DATE_SUB( CURDATE(), INTERVAL 30 DAY ) <= date( ac.create_time )  ) AS collect_num_order, 
-			( SELECT count( 1 ) FROM cygx_article_collect AS ac WHERE ac.article_id = a.article_id  AND user_id = ? ) AS my_collect_num
+			( SELECT count( 1 ) FROM cygx_article_collect AS ac WHERE ac.article_id = a.article_id  AND user_id = ? ) AS my_collect_num,
+			0 AS is_special,
+			0 AS special_type,
+			0 AS user_id,
+			'' AS company_tags, 
+			'' AS industry_tags
 		FROM
 			cygx_article AS a
 			INNER JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = a.article_id
 			INNER JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id
 			INNER JOIN cygx_article_department AS d ON d.department_id = a.department_id 
 		WHERE
-			1 = 1  AND a.publish_status = 1  `
+			1 = 1  AND a.publish_status = 1
+		  `
 	if condition != "" {
 		sql += condition
 	}
-	sql += ` GROUP BY a.article_id ORDER  BY   a.publish_date DESC  LIMIT ?,? `
-	_, err = o.Raw(sql, userId, pars, startSize, pageSize).QueryRows(&items)
+	sql += ` GROUP BY a.article_id  `
+	if needYanxuanSpecial {
+		sql += `UNION ALL
+	SELECT
+		a.id AS article_id,
+		a.title AS title,
+		a.publish_time AS publish_time,
+		-1 AS article_type_id,
+		b.nick_name AS nick_name,
+		a.user_id AS department_id,
+		( SELECT count( 1 ) FROM cygx_yanxuan_special_record AS h WHERE h.yanxuan_special_id = a.id ) AS pv,
+		( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac  WHERE ac.yanxuan_special_id = a.id  ) AS collect_num,
+		0 AS collect_num_order,
+		( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  AND user_id = ? ) AS my_collect_num,
+		1 AS is_special,
+		a.type AS special_type,
+		a.user_id AS user_id,
+		a.company_tags AS company_tags, 
+		a.industry_tags AS industry_tags 
+	FROM
+	cygx_yanxuan_special AS a
+	JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id
+	WHERE
+	1 = 1  AND a.status = 3 `
+		sql += ` ORDER  BY publish_time DESC  LIMIT ?,? `
+		_, err = o.Raw(sql, userId, userId, pars, startSize, pageSize).QueryRows(&items)
+	} else {
+		sql += ` ORDER  BY publish_time DESC  LIMIT ?,? `
+		_, err = o.Raw(sql, userId, pars, startSize, pageSize).QueryRows(&items)
+	}
+
 	return
 }
 
@@ -1021,20 +1073,27 @@ type ReportBillboardTableListResp struct {
 
 // 报告榜单start
 type ArticleReportBillboardResp struct {
-	ArticleId      int    `description:"文章id"`
-	Title          string `description:"标题"`
-	PublishDate    string `description:"发布时间"`
-	PermissionName string `description:"行业名称"`
-	DepartmentId   int    `description:"作者Id"`
-	NickName       string `description:"作者昵称"`
-	IsCollect      bool   `description:"本人是否收藏"`
-	Pv             int    `description:"PV"`
-	CollectNum     int    `description:"收藏人数"`
-	Source         int    `description:"来源 1:弘则资源包(报告)、2:研选主题(报告)"`
-	IsRoadShow     bool   `description:"是否是路演精华"`
-	CategoryId     int    `description:"分类ID"`
-	IsResearch     bool   `description:"是否属于研选"`
-	List           []*IndustrialManagementIdInt
+	ArticleId       int    `description:"文章id"`
+	Title           string `description:"标题"`
+	PublishDate     string `description:"发布时间"`
+	PermissionName  string `description:"行业名称"`
+	DepartmentId    int    `description:"作者Id"`
+	NickName        string `description:"作者昵称"`
+	IsCollect       bool   `description:"本人是否收藏"`
+	Pv              int    `description:"PV"`
+	CollectNum      int    `description:"收藏人数"`
+	Source          int    `description:"来源 1:弘则资源包(报告)、2:研选主题(报告)"`
+	IsRoadShow      bool   `description:"是否是路演精华"`
+	CategoryId      int    `description:"分类ID"`
+	IsResearch      bool   `description:"是否属于研选"`
+	ArticleTypeId   int    `description:"文章类型ID"`
+	ArticleTypeName string `description:"文章类型名称"`
+	IsSpecial       int    `description:"是否为研选专栏"`
+	SpecialTags     string `description:"研选专栏标签"`
+	MyCollectNum    int    `description:"本人是否收藏"`
+	SpecialType     int    `description:"专栏类型 1:笔记,2:观点"`
+	UserId          int    `description:"作者id"`
+	List            []*IndustrialManagementIdInt
 }
 
 type ArticleReportBillboardLIstResp struct {

+ 9 - 0
models/resource_data.go

@@ -38,6 +38,7 @@ type CygxResourceDataResp struct {
 	ProductInterior    *CygxProductInteriorResp                `description:"产品内测"`
 	IndustrialResource *IndustrialManagementHotResp            `description:"产业资源包"`
 	ReportSelection    *CygxReportSelectionRep                 `description:"重点公司(原报告精选)"`
+	YanxuanSpecial     *CygxYanxuanSpecialCenterResp           `description:"研选专栏"`
 }
 
 // Source      string    `description:"资源类型 报告 :article 、图表 :newchart、微路演 :roadshow、活动 :activity、活动视频:activityvideo、活动音频:activityvoice、专项调研活动:activityspecial"`
@@ -134,3 +135,11 @@ func GetCygxResourceDataByIdAndSource(sourceId int, source string) (item *CygxRe
 	err = o.Raw(sql, sourceId, source).QueryRow(&item)
 	return
 }
+
+// 获取数量
+func GetCygxResourceDataBySourceAndIdCount(sourceId int, source string) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_resource_data  WHERE  source_id = ? AND source =?  `
+	err = o.Raw(sqlCount, sourceId, source).QueryRow(&count)
+	return
+}

+ 54 - 5
models/user.go

@@ -158,16 +158,65 @@ type CheckStatusResp struct {
 }
 
 func GetArticleUserCollectCount(userId int) (count int, err error) {
-	sql := `SELECT COUNT(1) AS count FROM cygx_article_collect AS a INNER JOIN cygx_article as art ON art.article_id = a.article_id WHERE a.user_id=? AND art.publish_status = 1  `
-	err = orm.NewOrm().Raw(sql, userId).QueryRow(&count)
+	sql := `SELECT SUM(count) AS count FROM (
+			SELECT COUNT(1) AS count FROM cygx_article_collect AS a 
+			INNER JOIN cygx_article as art ON art.article_id = a.article_id 
+			WHERE a.user_id=? AND art.publish_status = 1  
+			UNION ALL
+			SELECT COUNT(1) AS count FROM cygx_yanxuan_special_collect AS a
+			INNER JOIN cygx_yanxuan_special as b ON b.id = a.yanxuan_special_id 
+			WHERE a.user_id=? AND b.status = 3) AS c 
+			 `
+	err = orm.NewOrm().Raw(sql, userId, userId).QueryRow(&count)
 	return
 }
 
 func GetArticleUserCollectList(startSize, pageSize, userId int) (items []*ArticleReportBillboardResp, err error) {
-	sql := `SELECT a.*,art.category_id FROM cygx_article_collect AS a INNER JOIN cygx_article as art ON art.article_id = a.article_id
+	sql := `SELECT 
+		a.article_id,
+		art.category_id,
+		'' AS title,
+		'' AS publish_date,
+		'' AS nick_name,
+		0 AS article_type_id,
+		'' AS article_type_name,
+		0 AS is_special,
+		'' AS special_tags,
+		0 AS pv,
+		0 AS collect_num,
+		0 AS my_collect_num,
+		0 AS special_type,
+		a.user_id AS user_id,
+		a.create_time AS create_time 
+			FROM cygx_article_collect AS a 
+			INNER JOIN cygx_article as art ON art.article_id = a.article_id
 			WHERE a.user_id=? 
-           ORDER BY a.create_time DESC LIMIT ?,? `
-	_, err = orm.NewOrm().Raw(sql, userId, startSize, pageSize).QueryRows(&items)
+			UNION ALL
+	SELECT
+		a.id AS article_id,
+		0 AS category_id,
+		a.title AS title,
+		date_format( a.publish_time, '%Y-%m-%d' ) AS publish_date,
+		b.nick_name AS nick_name,
+		-1 AS article_type_id,
+		'' AS article_type_name,
+		1 AS is_special,
+		a.tags AS special_tags,
+		( SELECT count( 1 ) FROM cygx_yanxuan_special_record AS h WHERE h.yanxuan_special_id = a.id ) AS pv,
+		( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac  WHERE ac.yanxuan_special_id = a.id  ) AS collect_num,
+		( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  AND user_id = ? ) AS my_collect_num,
+		a.type AS special_type,
+		a.user_id AS user_id,
+		c.create_time AS create_time 
+	FROM
+	cygx_yanxuan_special AS a
+	JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id
+	JOIN cygx_yanxuan_special_collect AS c ON a.id = c.yanxuan_special_id
+	WHERE
+	1 = 1  AND a.status = 3	AND c.user_id=? 		
+	ORDER BY create_time DESC 
+LIMIT ?,? `
+	_, err = orm.NewOrm().Raw(sql, userId, userId, userId, startSize, pageSize).QueryRows(&items)
 	return
 }
 

+ 49 - 18
models/wechat.go

@@ -6,6 +6,9 @@ import (
 	"github.com/beego/beego/v2/client/orm"
 	"github.com/rdlucklib/rdluck_tools/http"
 	"hongze/hongze_cygx/utils"
+	"io/ioutil"
+	netHttp "net/http"
+	"strconv"
 	"strings"
 	"time"
 )
@@ -194,36 +197,64 @@ func WxUsersGet() (openIdStr string) {
 }
 
 type WxCheckContentJson struct {
-	AccessToken  string `json:"access_token"`
-	ExpiresIn    int    `json:"expires_in"`
-	RefreshToken string `json:"refresh_token"`
-	Openid       string `json:"openid"`
-	Unionid      string `json:"unionid"`
-	Scope        string `json:"scope"`
-	Errcode      int    `json:"errcode"`
-	Errmsg       string `json:"errmsg"`
+	Detail  []WxCheckContentJsonDetail `json:"detail"`
+	Errcode int                        `json:"errcode"`
+	Errmsg  string                     `json:"errmsg"`
+	Result  WxCheckContentJsonResult   `json:"result"`
 }
 
-func WxCheckContent(content string) {
-	accessToken, err := GetWxAccessToken()
+type WxCheckContentJsonDetail struct {
+	Label    int
+	KeyWord  string
+	Prob     int
+	Strategy string
+	Errcode  int
+}
+type WxCheckContentJsonResult struct {
+	Suggest string
+	Label   int
+}
+
+func WxCheckContent(token, openId, content string) (suggest string) {
+	url := "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + token
+	fmt.Println(url)
+	//result, err := http.Post(url, content)
+	//if err != nil {
+	//	utils.FileLog.Info("GetUser Err:", err.Error())
+	//	return
+	//}
+	method := "POST"
+	payload := strings.NewReader(`{
+		"openid":"` + openId + `",
+		"scene":` + strconv.Itoa(2) + `,
+		"version":` + strconv.Itoa(2) + `,
+		"content":"` + content + `"
+				}`)
+	client := &netHttp.Client{}
+	req, err := netHttp.NewRequest(method, url, payload)
 	if err != nil {
-		utils.FileLog.Info("GetWxAccessToken Err:%s", err.Error())
 		return
 	}
-	url := "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + accessToken
-	fmt.Println(url)
-	result, err := http.Post(url, content)
+	req.Header.Add("Content-Type", "application/json")
+	postBody, err := client.Do(req)
 	if err != nil {
-		utils.FileLog.Info("GetUser Err:", err.Error())
 		return
 	}
-
+	defer postBody.Body.Close()
+	body, err := ioutil.ReadAll(postBody.Body)
+	if err != nil {
+		fmt.Println(err)
+		utils.FileLog.Info(err.Error())
+		return
+	}
 	item := new(WxCheckContentJson)
-	err = json.Unmarshal(result, &item)
+	err = json.Unmarshal(body, &item)
 	if err != nil {
 		fmt.Println("Unmarshal Err:", err.Error())
 		return
 	}
-	fmt.Println(result)
+	fmt.Println(item.Result.Label)
+	fmt.Println(item.Result.Suggest)
+	suggest = item.Result.Suggest
 	return
 }

+ 153 - 0
routers/commentsRouter.go

@@ -1690,4 +1690,157 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "AuthorDetail",
+            Router: `/author/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "AuthorHeadImg",
+            Router: `/author/head_img`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "AuthorList",
+            Router: `/author/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "AuthorSave",
+            Router: `/author/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Center",
+            Router: `/center`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Check",
+            Router: `/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Collect",
+            Router: `/collect`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "CompanySearch",
+            Router: `/companySearch`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Delete",
+            Router: `/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Enable",
+            Router: `/enable`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Follow",
+            Router: `/follow`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "IndustrySearch",
+            Router: `/industrySearch`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Record",
+            Router: `/record`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:YanxuanSpecialController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
 }

+ 5 - 0
routers/router.go

@@ -165,6 +165,11 @@ func init() {
 				&controllers.TagController{},
 			),
 		),
+		web.NSNamespace("/yanxuan_special",
+			web.NSInclude(
+				&controllers.YanxuanSpecialController{},
+			),
+		),
 		web.NSNamespace("/collection",
 			web.NSInclude(
 				&controllers.CollectionController{},

+ 293 - 0
services/cygx_yanxuan_special.go

@@ -0,0 +1,293 @@
+package services
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 研选专栏有新内容审核通过时,给关注此专栏的客户发送模板消息
+func SendWxMsgSpecialFollow(specialId int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("研选专栏有新内容审核通过时,给关注此专栏的客户发送模板消息失败", specialId, ", specialId", err.Error()), 2)
+		}
+	}()
+	var first string
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var remark string
+
+	followers, e := models.GetYanxuanSpecialFollowUserById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	if len(followers) == 0 {
+		return
+	}
+	specialItem, e := models.GetYanxuanSpecialItemById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	var allInUserId string
+	for _, v := range followers {
+		allInUserId += strconv.Itoa(v) + ","
+	}
+
+	allInUserId = strings.TrimRight(allInUserId, ",")
+
+	userList, err := models.GetWxUserListByUserIds(allInUserId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return err
+	}
+
+	mobile := ``
+
+	for _, v := range userList {
+		mobile += v.Mobile + ","
+	}
+
+	mobile = strings.TrimRight(mobile, ",")
+
+	openIdList, e := models.GetWxOpenIdByMobileList(mobile)
+	if e != nil {
+		err = errors.New("GetSellerByAdminId, Err: " + e.Error())
+		return
+	}
+	if len(openIdList) == 0 {
+		return
+	}
+
+	//first =
+	keyword1 = "研选专栏:" + specialItem.SpecialName
+	keyword2 = "发布了新内容,点击查看详情"
+	keyword3 = "-"
+	//keyword4 = "【" + activityInfo.ResearchTheme + "】已有10人预报名"
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	redirectUrl := ""
+	if utils.RunMode == "release" {
+		redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_DETAIL + strconv.Itoa(specialId)
+	}
+	sendInfo := new(SendWxTemplate)
+	sendInfo.First = first
+	sendInfo.Keyword1 = keyword1
+	sendInfo.Keyword2 = keyword2
+	sendInfo.Keyword3 = keyword3
+	sendInfo.Keyword4 = keyword4
+	sendInfo.Remark = remark
+	sendInfo.TemplateId = utils.WxMsgTemplateIdAskMsgXzs
+	sendInfo.RedirectUrl = redirectUrl
+	sendInfo.RedirectTarget = 3
+	sendInfo.Resource = strconv.Itoa(specialId)
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	err = PublicSendTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// SendReviewTemplateMsgAdmin 提交审核时给王芳,汪洋发消息
+func SendReviewTemplateMsgAdmin(specialId int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("处理试用申请给王芳,汪洋发消息失败, specialId:", specialId, "ErrMsg", err.Error()), 2)
+		}
+	}()
+	var configCode string
+	//如果是研选的就推送给汪洋跟王芳,否则就推送给王芳
+	configCode = utils.TPL_MSG_WANG_FANG_WANG_YANG
+	cnf, e := models.GetConfigByCode(configCode)
+	if e != nil {
+		err = errors.New("GetConfigByCode, Err: " + e.Error() + configCode)
+		return
+	}
+	openIdList, e := models.GetUserRecordListByMobile(4, cnf.ConfigValue)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetUserRecordListByMobile, Err: " + e.Error() + cnf.ConfigValue)
+		return err
+	}
+	specialItem, e := models.GetYanxuanSpecialItemById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	user, e := models.GetWxUserItemByUserId(specialItem.UserId)
+	if e != nil {
+		err = errors.New("GetWxUserItemByUserId, Err: " + e.Error())
+		return err
+	}
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var remark string
+	keyword1 = specialItem.RealName + "【" + user.CompanyName + "】"
+	keyword2 = user.Mobile
+	keyword3 = time.Now().Format(utils.FormatDateTime)
+	keyword4 = "研选专栏提交了内容待审核"
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	redirectUrl := ""
+	if utils.RunMode == "release" {
+		redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_ENABLE_DETAIL + strconv.Itoa(specialId)
+	}
+	sendInfo := new(SendWxTemplate)
+	sendInfo.Keyword1 = keyword1
+	sendInfo.Keyword2 = keyword2
+	sendInfo.Keyword3 = keyword3
+	sendInfo.Keyword4 = keyword4
+	sendInfo.Remark = remark
+	sendInfo.TemplateId = utils.WxMsgTemplateIdAskMsgXzs
+	sendInfo.RedirectUrl = redirectUrl
+	sendInfo.RedirectTarget = 3
+	sendInfo.Resource = strconv.Itoa(specialId)
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	err = PublicSendTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// 研选专栏审核完成时,给提交人发送模板消息
+func SendWxMsgSpecialAuthor(specialId, status int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("研选专栏审核完成时,给提交人发送模板消息", specialId, ", specialId", err.Error()), 2)
+		}
+	}()
+	var first string
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var remark string
+	var redirectUrl string
+
+	specialItem, e := models.GetYanxuanSpecialItemById(specialId)
+	if e != nil {
+		err = errors.New("GetYanxuanSpecialFollowUserById, Err: " + e.Error())
+		return
+	}
+	user, e := models.GetWxUserItemByUserId(specialItem.UserId)
+	if e != nil {
+		err = errors.New("GetWxUserItemByUserId, Err: " + e.Error())
+		return err
+	}
+
+	openIdList, err := models.GetUserRecordListByMobile(4, user.Mobile)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return err
+	}
+
+	keyword1 = "研选专栏内容审核"
+	if status == 1 {
+		keyword2 = "已通过审核,点击查看详情"
+		if utils.RunMode == "release" {
+			redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_DETAIL + strconv.Itoa(specialId)
+		}
+	} else {
+		keyword2 = "未通过审核,点击查看驳回原因"
+		if utils.RunMode == "release" {
+			redirectUrl = utils.WX_MSG_PATH_YX_SPECIAL_CENTER
+		}
+	}
+	keyword3 = "-"
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	sendInfo := new(SendWxTemplate)
+	sendInfo.First = first
+	sendInfo.Keyword1 = keyword1
+	sendInfo.Keyword2 = keyword2
+	sendInfo.Keyword3 = keyword3
+	sendInfo.Keyword4 = keyword4
+	sendInfo.Remark = remark
+	sendInfo.TemplateId = utils.WxMsgTemplateIdArticleUserRemind
+	sendInfo.RedirectUrl = redirectUrl
+	sendInfo.RedirectTarget = 3
+	sendInfo.Resource = strconv.Itoa(specialId)
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	err = PublicSendTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
+	return
+}
+
+//func init() {
+//	UpdateYanxuanSpecialResourceData(185)
+//}
+
+// 更新研选专栏  写入首页最新  cygx_resource_data 表
+func UpdateYanxuanSpecialResourceData(sourceId int) {
+	var err error
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("更新研选专栏失败sourceId: ", sourceId, "ErrMsg", err.Error()), 2)
+		}
+	}()
+	var source = utils.CYGX_OBJ_YANXUANSPECIAL
+	var condition string
+	var pars []interface{}
+	condition = ` AND status = 3  AND  id = ?  `
+	pars = append(pars, sourceId)
+	total, e := models.GetCygxYanxuanSpecialCount(condition, pars)
+	if e != nil {
+		err = errors.New("GetCygxYanxuanSpecialCount, Err: " + e.Error())
+		return
+	}
+	//如果取消发布了就做删除处理
+	if total == 0 {
+		e = models.DeleteResourceData(sourceId, source)
+		if e != nil {
+			err = errors.New("DeleteResourceData, Err: " + e.Error())
+			return
+		}
+	} else {
+		//判断是否存在,如果不存在就新增,存在就更新
+		totalData, e := models.GetCygxResourceDataBySourceAndIdCount(sourceId, source)
+		if e != nil {
+			err = errors.New("GetCygxReportSelectionBySourceAndId, Err: " + e.Error())
+			return
+		}
+		publishDate := time.Now().Format(utils.FormatDateTime)
+		item := new(models.CygxResourceData)
+		item.SourceId = sourceId
+		item.Source = source
+		item.PublishDate = publishDate
+		item.CreateTime = time.Now()
+		if totalData == 0 {
+			_, e := models.AddCygxResourceData(item)
+			if e != nil {
+				err = errors.New("AddCygxResourceData, Err: " + e.Error())
+				return
+			}
+		} else {
+			e = models.UpdateResourceDataByItem(item)
+			if e != nil {
+				err = errors.New("UpdateResourceDataByItem, Err: " + e.Error())
+				return
+			}
+		}
+	}
+	return
+}

+ 91 - 0
services/cygx_yanxuan_special_company.go

@@ -0,0 +1,91 @@
+package services
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/utils"
+	"io/ioutil"
+	"net/http"
+	"time"
+)
+
+func GetStocksFromVmp(cont context.Context) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("err:", err)
+			go utils.SendAlarmMsg("更新上市公司表失败"+err.Error(), 2)
+		}
+	}()
+	err = models.DelYanxuanSpecialCompany()
+	if err != nil {
+		fmt.Println("获取上市公司信息失败 Err:%s", err.Error())
+		return
+	}
+	getUrl := "https://vmp.hzinsights.com/v2api/articles/stock"
+	result, err := http.Get(getUrl)
+	if err != nil {
+		return
+	}
+	defer result.Body.Close()
+	body, err := ioutil.ReadAll(result.Body)
+	if err != nil {
+		fmt.Println("err:" + err.Error())
+		return
+	}
+	fmt.Println(body)
+	var resp models.VmpStocks
+	err = json.Unmarshal(body, &resp)
+	if err != nil {
+		fmt.Println("获取上市公司信息失败 Err:%s", err.Error())
+		return
+	}
+
+	items := make([]*models.CygxYanxuanSpecialCompany, 0)
+
+
+	for i, _ := range resp.Data {
+		items = append(items, &resp.Data[i])
+		if len(items) > 5000 {
+			err  = models.AddCygxYanxuanSpecialCompanyMulti(items)
+			if err != nil {
+				fmt.Println("AddCygxYanxuanSpecialCompanyMulti Err:%s", err.Error())
+				return
+			}
+			items = []*models.CygxYanxuanSpecialCompany{}
+		}
+	}
+
+	err  = models.AddCygxYanxuanSpecialCompanyMulti(items)
+	if err != nil {
+		fmt.Println("AddCygxYanxuanSpecialCompanyMulti Err:%s", err.Error())
+		return
+	}
+	return
+}
+
+func AddSpecialRecord(user *models.WxUserItem, specialId int) {
+	var sellerName string
+	sellerName, err := models.GetCompanySellerName(user.CompanyId)
+	if err != nil {
+		return
+	}
+	item := models.CygxYanxuanSpecialRecord{
+		UserId:           user.UserId,
+		Mobile:           user.Mobile,
+		Email:            user.Email,
+		CompanyId:        user.CompanyId,
+		CompanyName:      user.CompanyName,
+		RealName:         user.RealName,
+		SellerName:       sellerName,
+		CreateTime:       time.Now(),
+		ModifyTime:       time.Now(),
+		RegisterPlatform: utils.REGISTER_PLATFORM,
+		YanxuanSpecialId: specialId,
+	}
+	_, err = models.AddCygxYanxuanSpecialRecord(&item)
+	if err != nil {
+		return
+	}
+}

+ 61 - 1
services/es_comprehensive.go

@@ -584,6 +584,41 @@ func AddComprehensiveRoadshow() {
 	}
 }
 
+// Es研选专栏
+func EsAddYanxuanSpecial(sourceId int) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println("err:", err)
+			go utils.SendAlarmMsg(fmt.Sprint("更新研选专栏失败sourceId: ", sourceId), 2)
+		}
+	}()
+	detail, e := models.GetYanxuanSpecialItemById(sourceId)
+	if e != nil {
+		err = errors.New("GetArticleInfoOtherByArticleId" + e.Error())
+		return
+	}
+	content := html.UnescapeString(detail.Content)
+	doc, e := goquery.NewDocumentFromReader(strings.NewReader(content))
+	if e != nil {
+		err = errors.New("goquery.NewDocumentFromReader" + e.Error())
+		return
+	}
+	bodyText := doc.Text()
+	item := new(ElasticComprehensiveDetail)
+	item.SourceId = detail.Id
+	item.Source = utils.CYGX_OBJ_YANXUANSPECIAL
+	item.Title = detail.Title
+	item.PublishDate = detail.PublishTime
+	item.BodyText = bodyText
+	if detail.Status == 3 {
+		EsAddOrEditComprehensiveData(item) //如果发布了就新增
+	} else {
+		EsDeleteComprehensiveData(item) // 没有发布就删除
+	}
+	return
+}
+
 // 新增和修改数据
 func EsAddOrEditComprehensiveData(item *ElasticComprehensiveDetail) (err error) {
 	indexName := utils.IndexNameComprehensive
@@ -962,6 +997,7 @@ func GetResourceDataEsList(list []*SearchComprehensiveItem, user *models.WxUserI
 	var productinteriorIds []int
 	var industrialResourceIdsHz []int // 弘则产业资源包
 	var industrialResourceIdsYx []int // 研选产业资源包
+	var yanxuanSpecialIds []int       // 研选专栏
 	//Source      string    `description:"资源类型 报告 :article 、图表 :newchart、微路演 :roadshow、活动 :activity、活动视频:activityvideo、活动音频:activityvoice、专项调研活动:activityspecial 、 本周研究汇总: researchsummary 、 上周纪要汇总 :minutessummary 、晨会精华 :meetingreviewchapt "`
 	for _, v := range list {
 		if v.Source == "article" {
@@ -990,6 +1026,8 @@ func GetResourceDataEsList(list []*SearchComprehensiveItem, user *models.WxUserI
 			industrialResourceIdsHz = append(industrialResourceIdsHz, v.SourceId)
 		} else if v.Source == "industrialsourceYx" {
 			industrialResourceIdsYx = append(industrialResourceIdsYx, v.SourceId)
+		} else if v.Source == utils.CYGX_OBJ_YANXUANSPECIAL {
+			yanxuanSpecialIds = append(yanxuanSpecialIds, v.SourceId)
 		}
 	}
 	//处理文章
@@ -1420,10 +1458,32 @@ func GetResourceDataEsList(list []*SearchComprehensiveItem, user *models.WxUserI
 		}
 	}
 
+	//处理研选专栏
+	lenyanxuanSpecialIds := len(yanxuanSpecialIds)
+	if lenyanxuanSpecialIds > 0 {
+		pars = make([]interface{}, 0)
+		condition = ` AND a.id IN (` + utils.GetOrmInReplace(lenyanxuanSpecialIds) + `) `
+		pars = append(pars, yanxuanSpecialIds)
+		listyanxuanSpecial, e := models.GetYanxuanSpecialList(user.UserId, condition, pars)
+		if e != nil {
+			err = errors.New("GetYanxuanSpecialList, Err: " + e.Error())
+			return
+		}
+
+		for _, v := range listyanxuanSpecial {
+			v.PublishTime = utils.TimeRemoveHms2(v.PublishTime)
+			v.Annotation, _ = GetReportContentTextSubNew(v.Content)
+			// Source  PublishDate 字段兼容前端样式
+			v.Source = utils.CYGX_OBJ_YANXUANSPECIAL
+			v.PublishDate = v.PublishTime
+			mapItems[fmt.Sprint(utils.CYGX_OBJ_YANXUANSPECIAL, v.Id)].YanxuanSpecial = v
+		}
+	}
+
 	for _, vList := range list {
 		for _, v := range mapItems {
 			//如果这些类型都为空,那么就不合并
-			if v.Article == nil && v.Newchart == nil && v.Roadshow == nil && v.Activity == nil && v.Activityvideo == nil && v.Activityvoice == nil && v.Activityspecial == nil && v.Researchsummary == nil && v.Minutessummary == nil && v.Meetingreviewchapt == nil && v.ProductInterior == nil && v.IndustrialResource == nil {
+			if v.Article == nil && v.Newchart == nil && v.Roadshow == nil && v.Activity == nil && v.Activityvideo == nil && v.Activityvoice == nil && v.Activityspecial == nil && v.Researchsummary == nil && v.Minutessummary == nil && v.Meetingreviewchapt == nil && v.ProductInterior == nil && v.IndustrialResource == nil && v.YanxuanSpecial == nil {
 				continue
 			}
 			if v.Article != nil && v.SourceId == vList.SourceId {

+ 35 - 0
services/oss.go

@@ -138,3 +138,38 @@ func UploadFileToAliyun(filename, filepath, savePath string) error {
 	//return path,err
 	return err
 }
+
+// GetCloudDiskResourceFileTypeExtMap 常见文件类型图标
+func GetCloudDiskResourceFileTypeExtMap() map[string]string {
+	return map[string]string{
+		".doc":  "https://hzstatic.hzinsights.com/static/icon/file_type_docx.png",
+		".docx": "https://hzstatic.hzinsights.com/static/icon/file_type_docx.png",
+
+		".pdf": "https://hzstatic.hzinsights.com/static/icon/file_type_pdf.png",
+
+		".ppt":  "https://hzstatic.hzinsights.com/static/icon/file_type_ppt.png",
+		".pptx": "https://hzstatic.hzinsights.com/static/icon/file_type_ppt.png",
+
+		".xls":  "https://hzstatic.hzinsights.com/static/icon/file_type_xlsx.png",
+		".xlsx": "https://hzstatic.hzinsights.com/static/icon/file_type_xlsx.png",
+
+		".jpg":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
+		".jpeg": "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
+		".png":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
+		".bmp":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
+		".svg":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
+		".gif":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
+
+		".mp4":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+		".wmv":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+		".mov":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+		".mpeg": "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+		".avi":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+		".flv":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+		".rm":   "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+		".rmvb": "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
+
+		".mp3": "https://hzstatic.hzinsights.com/static/icon/file_type_audio.png",
+		".wma": "https://hzstatic.hzinsights.com/static/icon/file_type_audio.png",
+	}
+}

+ 27 - 3
services/resource_data.go

@@ -41,6 +41,7 @@ func GetResourceDataList(condition string, pars []interface{}, startSize, pageSi
 	var meetingreviewchaptIds []int
 	var productinteriorIds []int
 	var reportselectionIds []int // 报告精选
+	var yanxuanSpecialIds []int  // 研选专栏
 	//Source      string    `description:"资源类型 报告 :article 、图表 :newchart、微路演 :roadshow、活动 :activity、活动视频:activityvideo、活动音频:activityvoice、专项调研活动:activityspecial 、 本周研究汇总: researchsummary 、 上周纪要汇总 :minutessummary 、晨会精华 :meetingreviewchapt "`
 	for _, v := range list {
 		if v.Source == "article" {
@@ -67,8 +68,9 @@ func GetResourceDataList(condition string, pars []interface{}, startSize, pageSi
 			productinteriorIds = append(productinteriorIds, v.SourceId)
 		} else if v.Source == "reportselection" {
 			reportselectionIds = append(reportselectionIds, v.SourceId)
+		} else if v.Source == utils.CYGX_OBJ_YANXUANSPECIAL {
+			yanxuanSpecialIds = append(yanxuanSpecialIds, v.SourceId)
 		}
-
 	}
 	//处理文章
 	if len(articleIds) > 0 {
@@ -440,10 +442,32 @@ func GetResourceDataList(condition string, pars []interface{}, startSize, pageSi
 		}
 	}
 
+	//处理研选专栏
+	lenyanxuanSpecialIds := len(yanxuanSpecialIds)
+	if lenyanxuanSpecialIds > 0 {
+		pars = make([]interface{}, 0)
+		condition = ` AND a.id IN (` + utils.GetOrmInReplace(lenyanxuanSpecialIds) + `) `
+		pars = append(pars, yanxuanSpecialIds)
+		listyanxuanSpecial, e := models.GetYanxuanSpecialList(user.UserId, condition, pars)
+		if e != nil {
+			err = errors.New("GetYanxuanSpecialList, Err: " + e.Error())
+			return
+		}
+
+		for _, v := range listyanxuanSpecial {
+			v.PublishTime = utils.TimeRemoveHms2(v.PublishTime)
+			v.Annotation, _ = GetReportContentTextSubNew(v.Content)
+			// Source  PublishDate 字段兼容前端样式
+			v.Source = utils.CYGX_OBJ_YANXUANSPECIAL
+			v.PublishDate = v.PublishTime
+			mapItems[fmt.Sprint(utils.CYGX_OBJ_YANXUANSPECIAL, v.Id)].YanxuanSpecial = v
+		}
+	}
+
 	for _, vList := range list {
 		for _, v := range mapItems {
 			//如果这些类型都为空,那么就不合并
-			if v.Article == nil && v.Newchart == nil && v.Roadshow == nil && v.Activity == nil && v.Activityvideo == nil && v.Activityvoice == nil && v.Activityspecial == nil && v.Researchsummary == nil && v.Minutessummary == nil && v.Meetingreviewchapt == nil && v.ProductInterior == nil && v.IndustrialResource == nil && v.ReportSelection == nil {
+			if v.Article == nil && v.Newchart == nil && v.Roadshow == nil && v.Activity == nil && v.Activityvideo == nil && v.Activityvoice == nil && v.Activityspecial == nil && v.Researchsummary == nil && v.Minutessummary == nil && v.Meetingreviewchapt == nil && v.ProductInterior == nil && v.IndustrialResource == nil && v.ReportSelection == nil && v.YanxuanSpecial == nil {
 				continue
 			}
 			if v.SourceId == vList.SourceId {
@@ -534,7 +558,7 @@ func UpdateArticleResourceData(sourceId int) {
 		}
 	} else {
 		//判断是否存在,如果不存在就新增,存在就更新
-		totalData, e := models.GetCygxReportSelectionBySourceAndId(sourceId, source)
+		totalData, e := models.GetCygxResourceDataBySourceAndIdCount(sourceId, source)
 		if e != nil {
 			err = errors.New("GetCygxReportSelectionBySourceAndId, Err: " + e.Error())
 			return

+ 2 - 0
services/task.go

@@ -120,6 +120,8 @@ func Task() {
 		cygxActivityRestrictSignupByTask := task.NewTask("cygxActivityRestrictSignupByTask", "0 */10 6-23 * * *", CygxActivityRestrictSignupByTask)
 		task.AddTask("cygxActivityRestrictSignupByTask", cygxActivityRestrictSignupByTask) //定时任务处理为到会人员的爽约
 
+		getStocksFromVmp := task.NewTask("getStocksFromVmp", "0 40 3 * * *", GetStocksFromVmp)
+		task.AddTask("getStocksFromVmp", getStocksFromVmp) //定时任务更新上市公司表
 	}
 	if utils.RunMode != "release" {
 		getArticleListByApi := task.NewTask("getArticleListByApi", "0 */60 * * * *", GetArticleListByApi) //通过三方接口获取策略平台上的文章

+ 61 - 0
utils/common.go

@@ -7,6 +7,7 @@ import (
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
+	"github.com/PuerkitoBio/goquery"
 	"image"
 	"image/png"
 	"math"
@@ -868,3 +869,63 @@ func GetTimeDateRemoveYearAndSecond(strTime string) (dataStr string) {
 	dataStr = dataStr[:len(dataStr)-3]
 	return
 }
+
+func ArticleHasImgUrl(body string) (hasImg bool, 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) {
+		hasImg = true
+	})
+	return
+}
+
+func ArticleHasStyle(body string) (hasStyle bool, err error) {
+	r := strings.NewReader(string(body))
+	doc, err := goquery.NewDocumentFromReader(r)
+	if err != nil {
+		fmt.Println(err)
+	}
+	doc.Find("p style").Each(func(i int, s *goquery.Selection) {
+		hasStyle = true
+	})
+	doc.Find("class").Each(func(i int, s *goquery.Selection) {
+		hasStyle = true
+	})
+	return
+}
+
+func ArticleRemoveImgUrl(body string) (result string){
+	// 使用正则表达式去除img标签
+	re := regexp.MustCompile(`<img[^>]*>`)
+	result = re.ReplaceAllString(body, "")
+
+	return
+}
+
+func FindArticleImgUrls(body string) (imgUrls []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")
+		imgUrls = append(imgUrls, src)
+	})
+	return
+}
+
+// 去除部分style
+func ExtractText(body string) (result string, err error) {
+	// 使用正则表达式去除img标签
+	re := regexp.MustCompile(`<section style[\s\S]*?>`)
+	result = re.ReplaceAllString(body, "")
+
+	re = regexp.MustCompile(`<span style[\s\S]*?>`)
+	result = re.ReplaceAllString(result, "")
+
+	return
+}

+ 8 - 0
utils/constants.go

@@ -183,6 +183,9 @@ const (
 	WX_MSG_PATH_APPLY_DETAIL             = "pages-message/applyFor/applyFor?id="                          //潜在用户试用权限申请
 	WX_MSG_PATH_YX_SURVEY_DETAIL         = "pages-purchaser/survey/surveyDetail?surveyId="                //用户提交研选调研需求
 	WX_MSG_PATH_APPLY_COLLECTION_DETAIL  = "reportPages/bulletinDetail/bulletinDetail?id="                //精选看板申请详情页
+	WX_MSG_PATH_YX_SPECIAL_DETAIL        = "pages-purchaser/noteAndViewpoint/noteAndViewpoint?id="        //研选专栏详情
+	WX_MSG_PATH_YX_SPECIAL_ENABLE_DETAIL = "pages-purchaser/toExamine/toExamine?id="                      //研选专栏审核详情页面
+	WX_MSG_PATH_YX_SPECIAL_CENTER        = "pages-purchaser/contentAllPage/contentAllPage"                //研选专栏内容中心
 )
 
 //2:文章详情  https://web.hzinsights.com/material/info/8436  小程序路径:/pageMy/reportDetail/reportDetail?id=
@@ -238,4 +241,9 @@ const (
 	CYGX_OBJ_PRODUCTINTERIOR    string = "productinterior"    // 对象类型:产品内测
 	CYGX_OBJ_RESEARCHSUMMARY    string = "researchsummary"    // 对象类型:本周研究汇总
 	CYGX_OBJ_MINUTESSUMMARY     string = "minutessummary"     // 对象类型:本周研究汇总
+	CYGX_OBJ_YANXUANSPECIAL     string = "yanxuanspecial"     // 对象类型:研选专栏
+)
+
+const (
+	CYGX_YANXUAN_SPECIAL = "研选专栏" //用户阅读数据
 )